1 /*
2 | new_curse.c
3 |
4 | A subset of curses developed for use with ae.
5 |
6 | written by Hugh Mahon
7 |
8 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11 | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 | FITNESS FOR A PARTICULAR PURPOSE. Neither
13 | Hewlett-Packard nor Hugh Mahon shall be liable
14 | for errors contained herein, nor for
15 | incidental or consequential damages in
16 | connection with the furnishing, performance or
17 | use of this material. Neither Hewlett-Packard
18 | nor Hugh Mahon assumes any responsibility for
19 | the use or reliability of this software or
20 | documentation. This software and
21 | documentation is totally UNSUPPORTED. There
22 | is no support contract available. Hewlett-
23 | Packard has done NO Quality Assurance on ANY
24 | of the program or documentation. You may find
25 | the quality of the materials inferior to
26 | supported materials.
27 |
28 | This software is not a product of Hewlett-Packard, Co., or any
29 | other company. No support is implied or offered with this software.
30 | You've got the source, and you're on your own.
31 |
32 | This software may be distributed under the terms of Larry Wall's
33 | Artistic license, a copy of which is included in this distribution.
34 |
35 | This notice must be included with this software and any derivatives.
36 |
37 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
38 | All are rights reserved.
39 |
40 | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh Exp $
41 |
42 */
43
44 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
45 "All rights are reserved."};
46
47 char * new_curse_name= "@(#) new_curse.c $Revision: 1.54 $";
48
49 #include "new_curse.h"
50 #include <signal.h>
51 #include <fcntl.h>
52
53 #ifdef SYS5
54 #include <string.h>
55 #else
56 #include <strings.h>
57 #endif
58
59 #ifdef BSD_SELECT
60 #include <sys/types.h>
61 #include <sys/time.h>
62
63 #ifdef SLCT_HDR
64 #include <sys/select.h> /* on AIX */
65 #endif /* SLCT_HDR */
66
67 #endif /* BSD_SELECT */
68
69 #ifdef HAS_STDLIB
70 #include <stdlib.h>
71 #endif
72
73 #if defined(__STDC__)
74 #include <stdarg.h>
75 #else
76 #include <varargs.h>
77 #endif
78
79 #ifdef HAS_UNISTD
80 #include <unistd.h>
81 #endif
82
83 #ifdef HAS_SYS_IOCTL
84 #include <sys/ioctl.h>
85 #endif
86
87
88 WINDOW *curscr;
89 static WINDOW *virtual_scr;
90 WINDOW *stdscr;
91 WINDOW *last_window_refreshed;
92
93 #ifdef TIOCGWINSZ
94 struct winsize ws;
95 #endif
96
97 #define min(a, b) (a < b ? a : b)
98 #define highbitset(a) ((a) & 0x80)
99
100 #ifndef CAP
101 #define String_Out(table, stack, place) Info_Out(table, stack, place)
102 #else
103 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
104 #endif
105
106 #define bw__ 0 /* booleans */
107 #define am__ 1
108 #define xb__ 2
109 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
110 #define xn__ 4
111 #define eo__ 5
112 #define gn__ 6 /* generic type terminal */
113 #define hc__ 7 /* hardcopy terminal */
114 #define km__ 8
115 #define hs__ 9
116 #define in__ 10
117 #define da__ 11
118 #define db__ 12
119 #define mi__ 13 /* safe to move during insert mode */
120 #define ms__ 14 /* safe to move during standout mode */
121 #define os__ 15
122 #define es__ 16
123 #define xt__ 17
124 #define hz__ 18 /* hazeltine glitch */
125 #define ul__ 19
126 #define xo__ 20
127 #define chts__ 21
128 #define nxon__ 22
129 #define nrrmc__ 23
130 #define npc__ 24
131 #define mc5i__ 25
132
133 #define co__ 0 /* number of columns */ /* numbers */
134 #define it__ 1 /* spaces per tab */
135 #define li__ 2 /* number of lines */
136 #define lm__ 3
137 #define sg__ 4 /* magic cookie glitch */
138 #define pb__ 5
139 #define vt__ 6
140 #define ws__ 7
141
142 #define cols__ 0
143 #define lines__ 2
144 #define xmc__ 4
145 #define vt__ 6
146 #define wsl__ 7
147 #define nlab__ 8
148 #define lh__ 9
149 #define lw__ 10
150
151 #define bt__ 0 /* back tab */ /* strings */
152 #define bl__ 1 /* bell */
153 #define cr__ 2 /* carriage return */
154 #define cs__ 3 /* change scroll region */
155 #define ct__ 4 /* clear all tab stops */
156 #define cl__ 5 /* clear screen and home cursor */
157 #define ce__ 6 /* clear to end of line */
158 #define cd__ 7 /* clear to end of display */
159 #define ch__ 8 /* set cursor column */
160 #define CC__ 9 /* term, settable cmd char in */
161 #define cm__ 10 /* screen rel cursor motion, row, column */
162 #define do__ 11 /* down one line */
163 #define ho__ 12 /* home cursor */
164 #define vi__ 13 /* make cursor invisible */
165 #define le__ 14 /* move cursor left one space */
166 #define CM__ 15 /* memory rel cursor addressing */
167 #define ve__ 16 /* make cursor appear normal */
168 #define nd__ 17 /* non-destructive space (cursor right) */
169 #define ll__ 18 /* last line, first col */
170 #define up__ 19 /* cursor up */
171 #define vs__ 20
172 #define dc__ 21 /* delete character */
173 #define dl__ 22 /* delete line */
174 #define ds__ 23
175 #define hd__ 24
176 #define as__ 25
177 #define mb__ 26
178 #define md__ 27 /* turn on bold */
179 #define ti__ 28
180 #define dm__ 29 /* turn on delete mode */
181 #define mh__ 30 /* half bright mode */
182 #define im__ 31 /* insert mode */
183 #define mk__ 32
184 #define mp__ 33
185 #define mr__ 34
186 #define so__ 35 /* enter standout mode */
187 #define us__ 36
188 #define ec__ 37
189 #define ae__ 38
190 #define me__ 39
191 #define te__ 40
192 #define ed__ 41
193 #define ei__ 42 /* exit insert mode */
194 #define se__ 43 /* exit standout mode */
195 #define ue__ 44
196 #define vb__ 45
197 #define ff__ 46
198 #define fs__ 47
199 #define i1__ 48
200 #define i2__ 49
201 #define i3__ 50
202 #define if__ 51
203 #define ic__ 52
204 #define al__ 53
205 #define ip__ 54
206 #define kb__ 55 /* backspace key */
207 #define ka__ 56
208 #define kC__ 57
209 #define kt__ 58
210 #define kD__ 59
211 #define kL__ 60
212 #define kd__ 61
213 #define kM__ 62
214 #define kE__ 63
215 #define kS__ 64
216 #define k0__ 65
217 #define k1__ 66
218 #define kf10__ 67
219 #define k2__ 68
220 #define k3__ 69
221 #define k4__ 70
222 #define k5__ 71
223 #define k6__ 72
224 #define k7__ 73
225 #define k8__ 74
226 #define k9__ 75
227 #define kh__ 76
228 #define kI__ 77
229 #define kA__ 78
230 #define kl__ 79
231 #define kH__ 80
232 #define kN__ 81
233 #define kP__ 82
234 #define kr__ 83
235 #define kF__ 84
236 #define kR__ 85
237 #define kT__ 86
238 #define ku__ 87 /* key up */
239 #define ke__ 88
240 #define ks__ 89
241 #define l0__ 90
242 #define l1__ 91
243 #define la__ 92
244 #define l2__ 93
245 #define l3__ 94
246 #define l4__ 95
247 #define l5__ 96
248 #define l6__ 97
249 #define l7__ 98
250 #define l8__ 99
251 #define l9__ 100
252 #define mo__ 101
253 #define mm__ 102
254 #define nw__ 103
255 #define pc__ 104
256 #define DC__ 105
257 #define DL__ 106
258 #define DO__ 107
259 #define IC__ 118
260 #define SF__ 109
261 #define AL__ 110
262 #define LE__ 111
263 #define RI__ 112
264 #define SR__ 113
265 #define UP__ 114
266 #define pk__ 115
267 #define pl__ 116
268 #define px__ 117
269 #define ps__ 118
270 #define pf__ 119
271 #define po__ 120
272 #define rp__ 121
273 #define r1__ 122
274 #define r2__ 123
275 #define r3__ 124
276 #define rf__ 125
277 #define rc__ 126
278 #define cv__ 127
279 #define sc__ 128
280 #define sf__ 129
281 #define sr__ 130
282 #define sa__ 131 /* sgr */
283 #define st__ 132
284 #define wi__ 133
285 #define ta__ 134
286 #define ts__ 135
287 #define uc__ 136
288 #define hu__ 137
289 #define iP__ 138
290 #define K1__ 139
291 #define K2__ 140
292 #define K3__ 141
293 #define K4__ 142
294 #define K5__ 143
295 #define pO__ 144
296 #define ml__ 145
297 #define mu__ 146
298 #define rmp__ 145
299 #define acsc__ 146
300 #define pln__ 147
301 #define kcbt__ 148
302 #define smxon__ 149
303 #define rmxon__ 150
304 #define smam__ 151
305 #define rmam__ 152
306 #define xonc__ 153
307 #define xoffc__ 154
308 #define enacs__ 155
309 #define smln__ 156
310 #define rmln__ 157
311 #define kbeg__ 158
312 #define kcan__ 159
313 #define kclo__ 160
314 #define kcmd__ 161
315 #define kcpy__ 162
316 #define kcrt__ 163
317 #define kend__ 164
318 #define kent__ 165
319 #define kext__ 166
320 #define kfnd__ 167
321 #define khlp__ 168
322 #define kmrk__ 169
323 #define kmsg__ 170
324 #define kmov__ 171
325 #define knxt__ 172
326 #define kopn__ 173
327 #define kopt__ 174
328 #define kprv__ 175
329 #define kprt__ 176
330 #define krdo__ 177
331 #define kref__ 178
332 #define krfr__ 179
333 #define krpl__ 180
334 #define krst__ 181
335 #define kres__ 182
336 #define ksav__ 183
337 #define kspd__ 184
338 #define kund__ 185
339 #define kBEG__ 186
340 #define kCAN__ 187
341 #define kCMD__ 188
342 #define kCPY__ 189
343 #define kCRT__ 190
344 #define kDC__ 191
345 #define kDL__ 192
346 #define kslt__ 193
347 #define kEND__ 194
348 #define kEOL__ 195
349 #define kEXT__ 196
350 #define kFND__ 197
351 #define kHLP__ 198
352 #define kHOM__ 199
353 #define kIC__ 200
354 #define kLFT__ 201
355 #define kMSG__ 202
356 #define kMOV__ 203
357 #define kNXT__ 204
358 #define kOPT__ 205
359 #define kPRV__ 206
360 #define kPRT__ 207
361 #define kRDO__ 208
362 #define kRPL__ 209
363 #define kRIT__ 210
364 #define kRES__ 211
365 #define kSAV__ 212
366 #define kSPD__ 213
367 #define kUND__ 214
368 #define rfi__ 215
369 #define kf11__ 216
370 #define kf12__ 217
371 #define kf13__ 218
372 #define kf14__ 219
373 #define kf15__ 220
374 #define kf16__ 221
375 #define kf17__ 222
376 #define kf18__ 223
377 #define kf19__ 224
378 #define kf20__ 225
379 #define kf21__ 226
380 #define kf22__ 227
381 #define kf23__ 228
382 #define kf24__ 229
383 #define kf25__ 230
384 #define kf26__ 231
385 #define kf27__ 232
386 #define kf28__ 233
387 #define kf29__ 234
388 #define kf30__ 235
389 #define kf31__ 236
390 #define kf32__ 237
391 #define kf33__ 238
392 #define kf34__ 239
393 #define kf35__ 240
394 #define kf36__ 241
395 #define kf37__ 242
396 #define kf38__ 243
397 #define kf39__ 244
398 #define kf40__ 245
399 #define kf41__ 246
400 #define kf42__ 247
401 #define kf43__ 248
402 #define kf44__ 249
403 #define kf45__ 250
404 #define kf46__ 251
405 #define kf47__ 252
406 #define kf48__ 253
407 #define kf49__ 254
408 #define kf50__ 255
409 #define kf51__ 256
410 #define kf52__ 257
411 #define kf53__ 258
412 #define kf54__ 259
413 #define kf55__ 260
414 #define kf56__ 261
415 #define kf57__ 262
416 #define kf58__ 263
417 #define kf59__ 264
418 #define kf60__ 265
419 #define kf61__ 266
420 #define kf62__ 267
421 #define kf63__ 268
422 #define el1__ 269
423 #define mgc__ 270
424 #define smgl__ 271
425 #define smgr__ 272
426
427 #ifdef CAP
428 char *Boolean_names[] = {
429 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
430 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
431 };
432
433 char *Number_names[] = {
434 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
435 };
436
437 char *String_names[] = {
438 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
439 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
440 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
441 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
442 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
443 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
444 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
445 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
446 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
447 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
448 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
449 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
450 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
451 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
452 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
453 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
454 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
455 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
456 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
457 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
458 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
459 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
460 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
461 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
462 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
463 };
464 #endif
465
466 char *new_curse = "October 1987";
467
468 char in_buff[100]; /* buffer for ungetch */
469 int bufp; /* next free position in in_buff */
470
471 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
472 int CFOUND = FALSE;
473 int Data_Line_len = 0;
474 int Max_Key_len; /* max length of a sequence sent by a key */
475 char *Data_Line = NULL;
476 char *TERM_PATH = NULL;
477 char *TERM_data_ptr = NULL;
478 char *Term_File_name = NULL; /* name of file containing terminal description */
479 FILE *TFP; /* file pointer to file with terminal des. */
480 int Fildes; /* file descriptor for terminfo file */
481 int STAND = FALSE; /* is standout mode activated? */
482 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
483 int Time_Out; /* set when time elapsed while trying to read function key */
484 int Curr_x; /* current x position on screen */
485 int Curr_y; /* current y position on the screen */
486 int LINES;
487 int COLS;
488 int Move_It; /* flag to move cursor if magic cookie glitch */
489 int initialized = FALSE; /* tells whether new_curse is initialized */
490 float speed;
491 float chars_per_millisecond;
492 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
493 int Intr; /* storeage for interrupt character */
494 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
495 int Noblock; /* for BSD systems */
496 int Num_bits; /* number of bits per character */
497 int Flip_Bytes; /* some systems have byte order reversed */
498 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
499
500 #ifndef CAP
501 char *Strings;
502 #endif
503
504 #if !defined(TERMCAP)
505 #define TERMCAP "/etc/termcap"
506 #endif
507
508 struct KEYS {
509 int length; /* length of string sent by key */
510 char *string; /* string sent by key */
511 int value; /* CURSES value of key (9-bit) */
512 };
513
514 struct KEY_STACK {
515 struct KEYS *element;
516 struct KEY_STACK *next;
517 };
518
519 struct KEY_STACK *KEY_TOS = NULL;
520 struct KEY_STACK *KEY_POINT;
521
522 /*
523 |
524 | Not all systems have good terminal information, so we will define
525 | keyboard information here for the most widely used terminal type,
526 | the VT100.
527 |
528 */
529
530 struct KEYS vt100[] =
531 {
532 { 3, "\033[A", 0403 }, /* key up */
533 { 3, "\033[C", 0405 }, /* key right */
534 { 3, "\033[D", 0404 }, /* key left */
535
536 { 4, "\033[6~", 0522 }, /* key next page */
537 { 4, "\033[5~", 0523 }, /* key prev page */
538 { 3, "\033[[", 0550 }, /* key end */
539 { 3, "\033[@", 0406 }, /* key home */
540 { 4, "\033[2~", 0513 }, /* key insert char */
541
542 { 3, "\033[y", 0410 }, /* key F0 */
543 { 3, "\033[P", 0411 }, /* key F1 */
544 { 3, "\033[Q", 0412 }, /* key F2 */
545 { 3, "\033[R", 0413 }, /* key F3 */
546 { 3, "\033[S", 0414 }, /* key F4 */
547 { 3, "\033[t", 0415 }, /* key F5 */
548 { 3, "\033[u", 0416 }, /* key F6 */
549 { 3, "\033[v", 0417 }, /* key F7 */
550 { 3, "\033[l", 0420 }, /* key F8 */
551 { 3, "\033[w", 0421 }, /* key F9 */
552 { 3, "\033[x", 0422 }, /* key F10 */
553
554 { 5, "\033[10~", 0410 }, /* key F0 */
555 { 5, "\033[11~", 0411 }, /* key F1 */
556 { 5, "\033[12~", 0412 }, /* key F2 */
557 { 5, "\033[13~", 0413 }, /* key F3 */
558 { 5, "\033[14~", 0414 }, /* key F4 */
559 { 5, "\033[15~", 0415 }, /* key F5 */
560 { 5, "\033[17~", 0416 }, /* key F6 */
561 { 5, "\033[18~", 0417 }, /* key F7 */
562 { 5, "\033[19~", 0420 }, /* key F8 */
563 { 5, "\033[20~", 0421 }, /* key F9 */
564 { 5, "\033[21~", 0422 }, /* key F10 */
565 { 5, "\033[23~", 0423 }, /* key F11 */
566 { 5, "\033[24~", 0424 }, /* key F12 */
567 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
568 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
569 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
570 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
571 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
572
573 /*
574 | The following are the same keys as above, but with
575 | a different character following the escape char.
576 */
577
578 { 3, "\033OA", 0403 }, /* key up */
579 { 3, "\033OC", 0405 }, /* key right */
580 { 3, "\033OD", 0404 }, /* key left */
581 { 3, "\033OB", 0402 }, /* key down */
582 { 4, "\033O6~", 0522 }, /* key next page */
583 { 4, "\033O5~", 0523 }, /* key prev page */
584 { 3, "\033O[", 0550 }, /* key end */
585 { 3, "\033O@", 0406 }, /* key home */
586 { 4, "\033O2~", 0513 }, /* key insert char */
587
588 { 3, "\033Oy", 0410 }, /* key F0 */
589 { 3, "\033OP", 0411 }, /* key F1 */
590 { 3, "\033OQ", 0412 }, /* key F2 */
591 { 3, "\033OR", 0413 }, /* key F3 */
592 { 3, "\033OS", 0414 }, /* key F4 */
593 { 3, "\033Ot", 0415 }, /* key F5 */
594 { 3, "\033Ou", 0416 }, /* key F6 */
595 { 3, "\033Ov", 0417 }, /* key F7 */
596 { 3, "\033Ol", 0420 }, /* key F8 */
597 { 3, "\033Ow", 0421 }, /* key F9 */
598 { 3, "\033Ox", 0422 }, /* key F10 */
599
600 { 5, "\033O10~", 0410 }, /* key F0 */
601 { 5, "\033O11~", 0411 }, /* key F1 */
602 { 5, "\033O12~", 0412 }, /* key F2 */
603 { 5, "\033O13~", 0413 }, /* key F3 */
604 { 5, "\033O14~", 0414 }, /* key F4 */
605 { 5, "\033O15~", 0415 }, /* key F5 */
606 { 5, "\033O17~", 0416 }, /* key F6 */
607 { 5, "\033O18~", 0417 }, /* key F7 */
608 { 5, "\033O19~", 0420 }, /* key F8 */
609 { 5, "\033O20~", 0421 }, /* key F9 */
610 { 5, "\033O21~", 0422 }, /* key F10 */
611 { 5, "\033O23~", 0423 }, /* key F11 */
612 { 5, "\033O24~", 0424 }, /* key F12 */
613 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
614 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
615 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
616 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
617 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
618
619 { 0, "", 0 } /* end */
620 };
621
622 struct Parameters {
623 int value;
624 struct Parameters *next;
625 };
626
627 int Key_vals[] = {
628 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
629 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
630 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
631 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
632 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
633 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
634 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
635 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
636 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
637 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
638 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
639 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
640 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
641 };
642
643 int attributes_set[9];
644
645 static int nc_attributes = 0; /* global attributes for new_curse to observe */
646
647 #ifdef SYS5
648 struct termio Terminal;
649 struct termio Saved_tty;
650 #else
651 struct sgttyb Terminal;
652 struct sgttyb Saved_tty;
653 #endif
654
655 char *tc_;
656
657 int Booleans[128];
658 int Numbers[128];
659 char *String_table[1024];
660
661 int *virtual_lines;
662
663 static char nc_scrolling_ability = FALSE;
664
665 char *terminfo_path[] = {
666 "/lib/terminfo",
667 "/usr/lib/terminfo",
668 "/usr/share/lib/terminfo",
669 "/usr/share/terminfo",
670 NULL
671 };
672
673 #ifdef CAP
674
675 #if defined(__STDC__) || defined(__cplusplus)
676 #define P_(s) s
677 #else
678 #define P_(s) ()
679 #endif /* __STDC__ */
680
681 int tc_Get_int P_((int));
682 void CAP_PARSE P_((void));
683 void Find_term P_((void));
684
685 #undef P_
686
687 #endif /* CAP */
688
689
690 #ifndef __STDC__
691 #ifndef HAS_STDLIB
692 extern char *fgets();
693 extern char *malloc();
694 extern char *getenv();
695 FILE *fopen(); /* declaration for open function */
696 #endif /* HAS_STDLIB */
697 #endif /* __STDC__ */
698
699 #ifdef SIGWINCH
700
701 /*
702 | Copy the contents of one window to another.
703 */
704
705 void
copy_window(origin,destination)706 copy_window(origin, destination)
707 WINDOW *origin, *destination;
708 {
709 int row, column;
710 struct _line *orig, *dest;
711
712 orig = origin->first_line;
713 dest = destination->first_line;
714
715 for (row = 0;
716 row < (min(origin->Num_lines, destination->Num_lines));
717 row++)
718 {
719 for (column = 0;
720 column < (min(origin->Num_cols, destination->Num_cols));
721 column++)
722 {
723 dest->row[column] = orig->row[column];
724 dest->attributes[column] = orig->attributes[column];
725 }
726 dest->changed = orig->changed;
727 dest->scroll = orig->scroll;
728 dest->last_char = min(orig->last_char, destination->Num_cols);
729 orig = orig->next_screen;
730 dest = dest->next_screen;
731 }
732 destination->LX = min((destination->Num_cols - 1), origin->LX);
733 destination->LY = min((destination->Num_lines - 1), origin->LY);
734 destination->Attrib = origin->Attrib;
735 destination->scroll_up = origin->scroll_up;
736 destination->scroll_down = origin->scroll_down;
737 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
738 }
739
740 void
reinitscr(foo)741 reinitscr(foo)
742 int foo;
743 {
744 WINDOW *local_virt;
745 WINDOW *local_std;
746 WINDOW *local_cur;
747
748 signal(SIGWINCH, reinitscr);
749 #ifdef TIOCGWINSZ
750 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
751 {
752 if (ws.ws_row == LINES && ws.ws_col == COLS)
753 return;
754 if (ws.ws_row > 0)
755 LINES = ws.ws_row;
756 if (ws.ws_col > 0)
757 COLS = ws.ws_col;
758 }
759 #endif /* TIOCGWINSZ */
760 local_virt = newwin(LINES, COLS, 0, 0);
761 local_std = newwin(LINES, COLS, 0, 0);
762 local_cur = newwin(LINES, COLS, 0, 0);
763 copy_window(virtual_scr, local_virt);
764 copy_window(stdscr, local_std);
765 copy_window(curscr, local_cur);
766 delwin(virtual_scr);
767 delwin(stdscr);
768 delwin(curscr);
769 virtual_scr = local_virt;
770 stdscr = local_std;
771 curscr = local_cur;
772 free(virtual_lines);
773 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
774 interrupt_flag = TRUE;
775 }
776 #endif /* SIGWINCH */
777
778 void
initscr()779 initscr() /* initialize terminal for operations */
780 {
781 int value;
782 int counter;
783 char *lines_string;
784 char *columns_string;
785 #ifdef CAP
786 char *pointer;
787 #endif /* CAP */
788
789 #ifdef DIAG
790 printf("starting initscr \n");fflush(stdout);
791 #endif
792 if (initialized)
793 return;
794 #ifdef BSD_SELECT
795 setbuf(stdin, NULL);
796 #endif /* BSD_SELECT */
797 Flip_Bytes = FALSE;
798 Parity = 0;
799 Time_Out = FALSE;
800 bufp = 0;
801 Move_It = FALSE;
802 Noblock = FALSE;
803 #ifdef SYS5
804 value = ioctl(0, TCGETA, &Terminal);
805 if (Terminal.c_cflag & PARENB)
806 {
807 if (Terminal.c_cflag & PARENB)
808 Parity = 1;
809 else
810 Parity = 2;
811 }
812 if ((Terminal.c_cflag & CS8) == CS8)
813 {
814 Num_bits = 8;
815 }
816 else if ((Terminal.c_cflag & CS7) == CS7)
817 Num_bits = 7;
818 else if ((Terminal.c_cflag & CS6) == CS6)
819 Num_bits = 6;
820 else
821 Num_bits = 5;
822 value = Terminal.c_cflag & 037;
823 switch (value) {
824 case 01: speed = 50.0;
825 break;
826 case 02: speed = 75.0;
827 break;
828 case 03: speed = 110.0;
829 break;
830 case 04: speed = 134.5;
831 break;
832 case 05: speed = 150.0;
833 break;
834 case 06: speed = 200.0;
835 break;
836 case 07: speed = 300.0;
837 break;
838 case 010: speed = 600.0;
839 break;
840 case 011: speed = 900.0;
841 break;
842 case 012: speed = 1200.0;
843 break;
844 case 013: speed = 1800.0;
845 break;
846 case 014: speed = 2400.0;
847 break;
848 case 015: speed = 3600.0;
849 break;
850 case 016: speed = 4800.0;
851 break;
852 case 017: speed = 7200.0;
853 break;
854 case 020: speed = 9600.0;
855 break;
856 case 021: speed = 19200.0;
857 break;
858 case 022: speed = 38400.0;
859 break;
860 default: speed = 0.0;
861 }
862 #else
863 value = ioctl(0, TIOCGETP, &Terminal);
864 if (Terminal.sg_flags & EVENP)
865 Parity = 2;
866 else if (Terminal.sg_flags & ODDP)
867 Parity = 1;
868 value = Terminal.sg_ospeed;
869 switch (value) {
870 case 01: speed = 50.0;
871 break;
872 case 02: speed = 75.0;
873 break;
874 case 03: speed = 110.0;
875 break;
876 case 04: speed = 134.5;
877 break;
878 case 05: speed = 150.0;
879 break;
880 case 06: speed = 200.0;
881 break;
882 case 07: speed = 300.0;
883 break;
884 case 010: speed = 600.0;
885 break;
886 case 011: speed = 1200.0;
887 break;
888 case 012: speed = 1800.0;
889 break;
890 case 013: speed = 2400.0;
891 break;
892 case 014: speed = 4800.0;
893 break;
894 case 015: speed = 9600.0;
895 break;
896 default: speed = 0.0;
897 }
898 #endif
899 chars_per_millisecond = (0.001 * speed) / 8.0;
900 TERMINAL_TYPE = getenv("TERM");
901 if (TERMINAL_TYPE == NULL)
902 {
903 printf("unknown terminal type\n");
904 exit(0);
905 }
906 #ifndef CAP
907 Fildes = -1;
908 TERM_PATH = getenv("TERMINFO");
909 if (TERM_PATH != NULL)
910 {
911 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
912 Term_File_name = malloc(Data_Line_len);
913 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
914 Fildes = open(Term_File_name, O_RDONLY);
915 if (Fildes == -1)
916 {
917 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
918 Fildes = open(Term_File_name, O_RDONLY);
919 }
920 }
921 counter = 0;
922 while ((Fildes == -1) && (terminfo_path[counter] != NULL))
923 {
924 TERM_PATH = terminfo_path[counter];
925 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
926 Term_File_name = malloc(Data_Line_len);
927 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
928 Fildes = open(Term_File_name, O_RDONLY);
929 if (Fildes == -1)
930 {
931 sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
932 Fildes = open(Term_File_name, O_RDONLY);
933 }
934 counter++;
935 }
936 if (Fildes == -1)
937 {
938 free(Term_File_name);
939 Term_File_name = NULL;
940 }
941 else
942 TERM_INFO = INFO_PARSE();
943 #else
944 /*
945 | termcap information can be in the TERMCAP env variable, if so
946 | use that, otherwise check the /etc/termcap file
947 */
948 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
949 {
950 if (*Term_File_name != '/')
951 Term_File_name = TERMCAP;
952 }
953 else
954 {
955 Term_File_name = TERMCAP;
956 }
957 if ((TFP = fopen(Term_File_name, "r")) == NULL)
958 {
959 printf("unable to open %s file \n", TERMCAP);
960 exit(0);
961 }
962 for (value = 0; value < 1024; value++)
963 String_table[value] = NULL;
964 for (value = 0; value < 128; value++)
965 Booleans[value] = 0;
966 for (value = 0; value < 128; value++)
967 Numbers[value] = 0;
968 Data_Line = malloc(512);
969 if (pointer && *pointer != '/')
970 {
971 TERM_data_ptr = pointer;
972 CAP_PARSE();
973 }
974 else
975 {
976 Find_term();
977 CAP_PARSE();
978 }
979 #endif
980 if (String_table[pc__] == NULL)
981 String_table[pc__] = "\0";
982 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
983 {
984 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
985 exit(0);
986 }
987 Key_Get();
988 keys_vt100();
989 LINES = Numbers[li__];
990 COLS = Numbers[co__];
991 if ((lines_string = getenv("LINES")) != NULL)
992 {
993 value = atoi(lines_string);
994 if (value > 0)
995 LINES = value;
996 }
997 if ((columns_string = getenv("COLUMNS")) != NULL)
998 {
999 value = atoi(columns_string);
1000 if (value > 0)
1001 COLS = value;
1002 }
1003 #ifdef TIOCGWINSZ
1004 /*
1005 | get the window size
1006 */
1007 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1008 {
1009 if (ws.ws_row > 0)
1010 LINES = ws.ws_row;
1011 if (ws.ws_col > 0)
1012 COLS = ws.ws_col;
1013 }
1014 #endif
1015 virtual_scr = newwin(LINES, COLS, 0, 0);
1016 stdscr = newwin(LINES, COLS, 0, 0);
1017 curscr = newwin(LINES, COLS, 0, 0);
1018 wmove(stdscr, 0, 0);
1019 werase(stdscr);
1020 Repaint_screen = TRUE;
1021 initialized = TRUE;
1022 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1023
1024 #ifdef SIGWINCH
1025 /*
1026 | reset size of windows and LINES and COLS if term window
1027 | changes size
1028 */
1029 signal(SIGWINCH, reinitscr);
1030 #endif /* SIGWINCH */
1031
1032 /*
1033 | check if scrolling is available
1034 */
1035
1036 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1037 (String_table[dl__])) || ((String_table[cs__])
1038 && (String_table[sr__]));
1039
1040 }
1041
1042 #ifndef CAP
1043 int
Get_int()1044 Get_int() /* get a two-byte integer from the terminfo file */
1045 {
1046 int High_byte;
1047 int Low_byte;
1048 int temp;
1049
1050 Low_byte = *((unsigned char *) TERM_data_ptr++);
1051 High_byte = *((unsigned char *) TERM_data_ptr++);
1052 if (Flip_Bytes)
1053 {
1054 temp = Low_byte;
1055 Low_byte = High_byte;
1056 High_byte = temp;
1057 }
1058 if ((High_byte == 255) && (Low_byte == 255))
1059 return (-1);
1060 else
1061 return(Low_byte + (High_byte * 256));
1062 }
1063
1064 int
INFO_PARSE()1065 INFO_PARSE() /* parse off the data in the terminfo data file */
1066 {
1067 int offset;
1068 int magic_number = 0;
1069 int counter = 0;
1070 int Num_names = 0;
1071 int Num_bools = 0;
1072 int Num_ints = 0;
1073 int Num_strings = 0;
1074 int string_table_len = 0;
1075 char *temp_ptr;
1076
1077 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1078 Data_Line_len = read(Fildes, Data_Line, 10240);
1079 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1080 return(0);
1081 /*
1082 | get magic number
1083 */
1084 magic_number = Get_int();
1085 /*
1086 | if magic number not right, reverse byte order and check again
1087 */
1088 if (magic_number != 282)
1089 {
1090 Flip_Bytes = TRUE;
1091 TERM_data_ptr--;
1092 TERM_data_ptr--;
1093 magic_number = Get_int();
1094 if (magic_number != 282)
1095 return(0);
1096 }
1097 /*
1098 | get the number of each type in the terminfo data file
1099 */
1100 Num_names = Get_int();
1101 Num_bools = Get_int();
1102 Num_ints = Get_int();
1103 Num_strings = Get_int();
1104 string_table_len = Get_int();
1105 Strings = malloc(string_table_len);
1106 while (Num_names > 0)
1107 {
1108 TERM_data_ptr++;
1109 Num_names--;
1110 }
1111 counter = 0;
1112 while (Num_bools)
1113 {
1114 Num_bools--;
1115 Booleans[counter++] = *TERM_data_ptr++;
1116 }
1117 if ((unsigned long)(TERM_data_ptr) & 1) /* force alignment */
1118 TERM_data_ptr++;
1119 counter = 0;
1120 while (Num_ints)
1121 {
1122 Num_ints--;
1123 Numbers[counter] = Get_int();
1124 counter++;
1125 }
1126 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1127 memcpy(Strings, temp_ptr, string_table_len);
1128 counter = bt__;
1129 while (Num_strings)
1130 {
1131 Num_strings--;
1132 if ((offset=Get_int()) != -1)
1133 {
1134 if (String_table[counter] == NULL)
1135 String_table[counter] = Strings + offset;
1136 }
1137 else
1138 String_table[counter] = NULL;
1139 counter++;
1140 }
1141 close(Fildes);
1142 free(Data_Line);
1143 return(TRUE);
1144 }
1145 #endif /* ifndef CAP */
1146
1147 int
AtoI()1148 AtoI() /* convert ascii text to integers */
1149 {
1150 int Temp;
1151
1152 Temp = 0;
1153 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1154 {
1155 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1156 TERM_data_ptr++;
1157 }
1158 return(Temp);
1159 }
1160
1161 void
Key_Get()1162 Key_Get() /* create linked list with all key sequences obtained from terminal database */
1163 {
1164 int Counter;
1165 int Klen;
1166 int key_def;
1167 struct KEY_STACK *Spoint;
1168
1169 Max_Key_len = 0;
1170 Counter = 0;
1171 key_def = kb__;
1172 while (key_def <= kf63__)
1173 {
1174 if (key_def == ke__)
1175 key_def = K1__;
1176 else if (key_def == (K5__ + 1))
1177 key_def = kcbt__;
1178 else if (key_def == (kcbt__ + 1))
1179 key_def = kbeg__;
1180 else if (key_def == (kUND__ + 1))
1181 key_def = kf11__;
1182 if (String_table[key_def] != NULL)
1183 {
1184 if (KEY_TOS == NULL)
1185 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1186 else
1187 {
1188 Spoint = KEY_TOS;
1189 while (Spoint->next != NULL)
1190 Spoint = Spoint->next;
1191 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1192 Spoint = Spoint->next;
1193 }
1194 Spoint->next = NULL;
1195 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1196 Spoint->element->string = String_table[key_def];
1197 Spoint->element->length = strlen(String_table[key_def]);
1198 Spoint->element->value = Key_vals[Counter];
1199 Klen = strlen(Spoint->element->string);
1200 if (Klen > Max_Key_len)
1201 Max_Key_len = Klen;
1202 /*
1203 | Some terminal types accept keystrokes of the form
1204 | \E[A and \EOA, substituting '[' for 'O'. Make a
1205 | duplicate of such key strings (since the
1206 | database will only have one version) so new_curse
1207 | can understand both.
1208 */
1209 if ((Spoint->element->length > 1) &&
1210 ((String_table[key_def][1] == '[') ||
1211 (String_table[key_def][1] == 'O')))
1212 {
1213 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1214 Spoint = Spoint->next;
1215 Spoint->next = NULL;
1216 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1217 Spoint->element->length = strlen(String_table[key_def]);
1218 Spoint->element->string = malloc(Spoint->element->length + 1);
1219 strcpy(Spoint->element->string, String_table[key_def]);
1220 Spoint->element->value = Key_vals[Counter];
1221 Klen = strlen(Spoint->element->string);
1222 if (Klen > Max_Key_len)
1223 Max_Key_len = Klen;
1224
1225 if (String_table[key_def][1] == '[')
1226 Spoint->element->string[1] = 'O';
1227 else
1228 Spoint->element->string[1] = '[';
1229 }
1230 }
1231 key_def++;
1232 Counter++;
1233 }
1234 }
1235
1236 /*
1237 | insert information about keys for a vt100 terminal
1238 */
1239
1240 void
keys_vt100()1241 keys_vt100()
1242 {
1243 int counter;
1244 int Klen;
1245 struct KEY_STACK *Spoint;
1246
1247 Spoint = KEY_TOS;
1248 while (Spoint->next != NULL)
1249 Spoint = Spoint->next;
1250 for (counter = 0; vt100[counter].length != 0; counter++)
1251 {
1252 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1253 Spoint = Spoint->next;
1254 Spoint->next = NULL;
1255 Spoint->element = &vt100[counter];
1256 Klen = strlen(Spoint->element->string);
1257 if (Klen > Max_Key_len)
1258 Max_Key_len = Klen;
1259 }
1260 }
1261
1262 #ifdef CAP
1263 char *
String_Get(param)1264 String_Get(param) /* read the string */
1265 char *param;
1266 {
1267 char *String;
1268 char *Temp;
1269 int Counter;
1270
1271 if (param == NULL)
1272 {
1273 while (*TERM_data_ptr != '=')
1274 TERM_data_ptr++;
1275 Temp = ++TERM_data_ptr;
1276 Counter = 1;
1277 while ((*Temp != ':') && (*Temp != (char)NULL))
1278 {
1279 Counter++;
1280 Temp++;
1281 }
1282 if (Counter == 1) /* no data */
1283 return(NULL);
1284 String = Temp = malloc(Counter);
1285 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1286 {
1287 if (*TERM_data_ptr == '\\')
1288 {
1289 TERM_data_ptr++;
1290 if (*TERM_data_ptr == 'n')
1291 *Temp = '\n';
1292 else if (*TERM_data_ptr == 't')
1293 *Temp = '\t';
1294 else if (*TERM_data_ptr == 'b')
1295 *Temp = '\b';
1296 else if (*TERM_data_ptr == 'r')
1297 *Temp = '\r';
1298 else if (*TERM_data_ptr == 'f')
1299 *Temp = '\f';
1300 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1301 *Temp = '\033'; /* escape */
1302 else if (*TERM_data_ptr == '\\')
1303 *Temp = '\\';
1304 else if (*TERM_data_ptr == '\'')
1305 *Temp = '\'';
1306 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1307 {
1308 Counter = 0;
1309 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1310 {
1311 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1312 TERM_data_ptr++; /* ? */
1313 }
1314 *Temp = Counter;
1315 TERM_data_ptr--;
1316 }
1317 TERM_data_ptr++;
1318 Temp++;
1319 }
1320 else if (*TERM_data_ptr == '^')
1321 {
1322 TERM_data_ptr++;
1323 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1324 *Temp = *TERM_data_ptr - '@';
1325 else if (*TERM_data_ptr == '?')
1326 *Temp = 127;
1327 TERM_data_ptr++;
1328 Temp++;
1329 }
1330 else
1331 *Temp++ = *TERM_data_ptr++;
1332 }
1333 *Temp = (char)NULL;
1334 param = String;
1335 }
1336 else
1337 {
1338 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1339 TERM_data_ptr++;
1340 }
1341 return(param);
1342 }
1343
1344 int
tc_Get_int(param)1345 tc_Get_int(param) /* read the integer */
1346 int param;
1347 {
1348 int Itemp;
1349
1350 if (param == 0)
1351 {
1352 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1353 TERM_data_ptr++;
1354 TERM_data_ptr++;
1355 Itemp = AtoI();
1356 param = Itemp;
1357 }
1358 else
1359 {
1360 while (*TERM_data_ptr != ':')
1361 TERM_data_ptr++;
1362 }
1363 return(param);
1364 }
1365
1366 void
Find_term()1367 Find_term() /* find terminal description in termcap file */
1368 {
1369 char *Name;
1370 char *Ftemp;
1371
1372 Ftemp = Name = malloc(strlen(TERMINAL_TYPE) + 2);
1373 strcpy(Name, TERMINAL_TYPE);
1374 while (*Ftemp != (char)NULL)
1375 Ftemp++;
1376 *Ftemp++ = '|';
1377 *Ftemp = (char)NULL;
1378 CFOUND = FALSE;
1379 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1380 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1381 {
1382 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1383 {
1384 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1385 {
1386 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1387 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1388 TERM_data_ptr++;
1389 if (*TERM_data_ptr == '|')
1390 TERM_data_ptr++;
1391 else if (!CFOUND)
1392 *TERM_data_ptr = (char)NULL;
1393 }
1394 }
1395 }
1396 if (!CFOUND)
1397 {
1398 printf("terminal type %s not found\n", TERMINAL_TYPE);
1399 exit(0);
1400 }
1401 }
1402
1403 void
CAP_PARSE()1404 CAP_PARSE() /* parse off the data in the termcap data file */
1405 {
1406 int offset;
1407 int found;
1408
1409 do
1410 {
1411 while (*TERM_data_ptr != (char)NULL)
1412 {
1413 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1414 {
1415 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1416 {
1417 found = TRUE;
1418 Booleans[offset] = TRUE;
1419 }
1420 }
1421 if (!found)
1422 {
1423 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1424 {
1425 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1426 {
1427 found = TRUE;
1428 Numbers[offset] = tc_Get_int(Numbers[offset]);
1429 }
1430 }
1431 }
1432 if (!found)
1433 {
1434 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1435 {
1436 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1437 {
1438 found = TRUE;
1439 String_table[offset] = String_Get(String_table[offset]);
1440 }
1441 }
1442 }
1443
1444 if (!strncmp(TERM_data_ptr, "tc=", 3))
1445 tc_ = String_Get(NULL);
1446 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1447 TERM_data_ptr++;
1448 if (*TERM_data_ptr == ':')
1449 TERM_data_ptr++;
1450 }
1451 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1452 if (tc_ != NULL)
1453 {
1454 TERMINAL_TYPE = tc_;
1455 rewind(TFP);
1456 Find_term();
1457 tc_ = NULL;
1458 CAP_PARSE();
1459 }
1460 else
1461 fclose(TFP);
1462 }
1463 #endif /* ifdef CAP */
1464
1465 struct _line *
Screenalloc(columns)1466 Screenalloc(columns)
1467 int columns;
1468 {
1469 int i;
1470 struct _line *tmp;
1471
1472 tmp = (struct _line *) malloc(sizeof (struct _line));
1473 tmp->row = malloc(columns + 1);
1474 tmp->attributes = malloc(columns + 1);
1475 tmp->prev_screen = NULL;
1476 tmp->next_screen = NULL;
1477 for (i = 0; i < columns; i++)
1478 {
1479 tmp->row[i] = ' ';
1480 tmp->attributes[i] = '\0';
1481 }
1482 tmp->scroll = tmp->changed = FALSE;
1483 tmp->row[0] = '\0';
1484 tmp->attributes[0] = '\0';
1485 tmp->row[columns] = '\0';
1486 tmp->attributes[columns] = '\0';
1487 tmp->last_char = 0;
1488 return(tmp);
1489 }
1490
newwin(lines,cols,start_l,start_c)1491 WINDOW *newwin(lines, cols, start_l, start_c)
1492 int lines, cols; /* number of lines and columns to be in window */
1493 int start_l, start_c; /* starting line and column to be inwindow */
1494 {
1495 WINDOW *Ntemp;
1496 struct _line *temp_screen;
1497 int i;
1498
1499 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1500 Ntemp->SR = start_l;
1501 Ntemp->SC = start_c;
1502 Ntemp->Num_lines = lines;
1503 Ntemp->Num_cols = cols;
1504 Ntemp->LX = 0;
1505 Ntemp->LY = 0;
1506 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1507 Ntemp->SCROLL_CLEAR = FALSE;
1508 Ntemp->Attrib = FALSE;
1509 Ntemp->first_line = temp_screen = Screenalloc(cols);
1510 Ntemp->first_line->number = 0;
1511 Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
1512
1513 Ntemp->line_array[0] = Ntemp->first_line;
1514
1515 for (i = 1; i < lines; i++)
1516 {
1517 temp_screen->next_screen = Screenalloc(cols);
1518 temp_screen->next_screen->number = i;
1519 temp_screen->next_screen->prev_screen = temp_screen;
1520 temp_screen = temp_screen->next_screen;
1521 Ntemp->line_array[i] = temp_screen;
1522 }
1523 Ntemp->first_line->prev_screen = NULL;
1524 temp_screen->next_screen = NULL;
1525 return(Ntemp);
1526 }
1527
1528 #ifdef CAP
1529 void
Cap_Out(string,p_list,place)1530 Cap_Out(string, p_list, place) /* interpret the output string if necessary */
1531 char *string;
1532 int p_list[]; /* stack of values */
1533 int place; /* place keeper of top of stack */
1534 {
1535 char *Otemp; /* temporary string pointer to parse output */
1536 int delay;
1537 int p1, p2, temp;
1538 float chars;
1539
1540 if (string == NULL)
1541 return;
1542
1543 if (p_list != NULL)
1544 {
1545 p1 = p_list[--place];
1546 p2 = p_list[--place];
1547 }
1548 delay = 0;
1549 Otemp = string;
1550 if ((*Otemp >= '0') && (*Otemp <= '9'))
1551 {
1552 delay = atoi(Otemp);
1553 while ((*Otemp >= '0') && (*Otemp <= '9'))
1554 Otemp++;
1555 if (*Otemp == '*')
1556 Otemp++;
1557 }
1558 while (*Otemp != (char)NULL)
1559 {
1560 if (*Otemp == '%')
1561 {
1562 Otemp++;
1563 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1564 {
1565 if (*Otemp == 'd')
1566 printf("%d", p1);
1567 else if (*Otemp == '2')
1568 printf("%02d", p1);
1569 else if (*Otemp == '3')
1570 printf("%03d", p1);
1571 else if (*Otemp == '+')
1572 {
1573 Otemp++;
1574 p1 += *Otemp;
1575 putchar(p1);
1576 }
1577 else if (*Otemp == '.')
1578 putchar(p1);
1579 p1 = p2;
1580 p2 = 0;
1581 }
1582 else if (*Otemp == '>')
1583 {
1584 Otemp++;
1585 if (p1 > *Otemp)
1586 {
1587 Otemp++;
1588 p1 += *Otemp;
1589 }
1590 else
1591 Otemp++;
1592 }
1593 else if (*Otemp == 'r')
1594 {
1595 temp = p1;
1596 p1 = p2;
1597 p2 = temp;
1598 }
1599 else if (*Otemp == 'i')
1600 {
1601 p1++;
1602 p2++;
1603 }
1604 else if (*Otemp == '%')
1605 putchar(*Otemp);
1606 else if (*Otemp == 'n')
1607 {
1608 p1 ^= 0140;
1609 p2 ^= 0140;
1610 }
1611 else if (*Otemp == 'B')
1612 {
1613 p1 = (16 * (p1/10)) + (p1 % 10);
1614 p2 = (16 * (p2/10)) + (p2 % 10);
1615 }
1616 else if (*Otemp == 'D')
1617 {
1618 p1 = (p1 - 2 * (p1 % 16));
1619 p2 = (p2 - 2 * (p2 % 16));
1620 }
1621 }
1622 else
1623 putchar (*Otemp);
1624 Otemp++;
1625 }
1626 if (delay != 0)
1627 {
1628 chars = delay * chars_per_millisecond;
1629 delay = chars;
1630 if ((chars - delay) > 0.0)
1631 delay++;
1632 for (; delay > 0; delay--)
1633 putchar(*String_table[pc__]);
1634 }
1635 fflush(stdout);
1636 }
1637
1638 #else
1639
1640 char *Otemp; /* temporary string pointer to parse output */
1641 float chars;
1642 int p[10];
1643 int variable[27];
1644
1645 int
Operation(Temp_Stack,place)1646 Operation(Temp_Stack, place) /* handle conditional operations */
1647 int Temp_Stack[];
1648 int place;
1649 {
1650 int temp;
1651
1652 if (*Otemp == 'd')
1653 {
1654 Otemp++;
1655 temp = Temp_Stack[--place];
1656 printf("%d", temp);
1657 }
1658 else if (!strncmp(Otemp, "2d", 2))
1659 {
1660 temp = Temp_Stack[--place];
1661 printf("%2d", temp);
1662 Otemp++;
1663 Otemp++;
1664 }
1665 else if (!strncmp(Otemp, "3d", 2))
1666 {
1667 temp = Temp_Stack[--place];
1668 printf("%0d", temp);
1669 Otemp++;
1670 Otemp++;
1671 }
1672 else if (!strncmp(Otemp, "02d", 3))
1673 {
1674 temp = Temp_Stack[--place];
1675 printf("%02d", temp);
1676 Otemp++;
1677 Otemp++;
1678 Otemp++;
1679 }
1680 else if (!strncmp(Otemp, "03d", 3))
1681 {
1682 temp = Temp_Stack[--place];
1683 printf("%03d", temp);
1684 Otemp++;
1685 Otemp++;
1686 Otemp++;
1687 }
1688 else if (*Otemp == '+')
1689 {
1690 Otemp++;
1691 temp = Temp_Stack[--place];
1692 temp += Temp_Stack[--place];
1693 Temp_Stack[place++] = temp;
1694 }
1695 else if (*Otemp == '-')
1696 {
1697 Otemp++;
1698 temp = Temp_Stack[--place];
1699 temp -= Temp_Stack[--place];
1700 Temp_Stack[place++] = temp;
1701 }
1702 else if (*Otemp == '*')
1703 {
1704 Otemp++;
1705 temp = Temp_Stack[--place];
1706 temp *= Temp_Stack[--place];
1707 Temp_Stack[place++] = temp;
1708 }
1709 else if (*Otemp == '/')
1710 {
1711 Otemp++;
1712 temp = Temp_Stack[--place];
1713 temp /= Temp_Stack[--place];
1714 Temp_Stack[place++] = temp;
1715 }
1716 else if (*Otemp == 'm')
1717 {
1718 Otemp++;
1719 temp = Temp_Stack[--place];
1720 temp %= Temp_Stack[--place];
1721 Temp_Stack[place++] = temp;
1722 }
1723 else if (*Otemp == '&')
1724 {
1725 Otemp++;
1726 temp = Temp_Stack[--place];
1727 temp &= Temp_Stack[--place];
1728 Temp_Stack[place++] = temp;
1729 }
1730 else if (*Otemp == '|')
1731 {
1732 Otemp++;
1733 temp = Temp_Stack[--place];
1734 temp |= Temp_Stack[--place];
1735 Temp_Stack[place++] = temp;
1736 }
1737 else if (*Otemp == '^')
1738 {
1739 Otemp++;
1740 temp = Temp_Stack[--place];
1741 temp ^= Temp_Stack[--place];
1742 Temp_Stack[place++] = temp;
1743 }
1744 else if (*Otemp == '=')
1745 {
1746 Otemp++;
1747 temp = Temp_Stack[--place];
1748 temp = (temp == Temp_Stack[--place]);
1749 Temp_Stack[place++] = temp;
1750 }
1751 else if (*Otemp == '>')
1752 {
1753 Otemp++;
1754 temp = Temp_Stack[--place];
1755 temp = temp > Temp_Stack[--place];
1756 Temp_Stack[place++] = temp;
1757 }
1758 else if (*Otemp == '<')
1759 {
1760 Otemp++;
1761 temp = Temp_Stack[--place];
1762 temp = temp < Temp_Stack[--place];
1763 Temp_Stack[place++] = temp;
1764 }
1765 else if (*Otemp == 'c')
1766 {
1767 Otemp++;
1768 putchar(Temp_Stack[--place]);
1769 }
1770 else if (*Otemp == 'i')
1771 {
1772 Otemp++;
1773 p[1]++;
1774 p[2]++;
1775 }
1776 else if (*Otemp == '%')
1777 {
1778 putchar(*Otemp);
1779 Otemp++;
1780 }
1781 else if (*Otemp == '!')
1782 {
1783 temp = ! Temp_Stack[--place];
1784 Temp_Stack[place++] = temp;
1785 Otemp++;
1786 }
1787 else if (*Otemp == '~')
1788 {
1789 temp = ~Temp_Stack[--place];
1790 Temp_Stack[place++] = temp;
1791 Otemp++;
1792 }
1793 else if (*Otemp == 'p')
1794 {
1795 Otemp++;
1796 Temp_Stack[place++] = p[*Otemp - '0'];
1797 Otemp++;
1798 }
1799 else if (*Otemp == 'P')
1800 {
1801 Otemp++;
1802 Temp_Stack[place++] = variable[*Otemp - 'a'];
1803 Otemp++;
1804 }
1805 else if (*Otemp == 'g')
1806 {
1807 Otemp++;
1808 variable[*Otemp - 'a'] = Temp_Stack[--place];
1809 Otemp++;
1810 }
1811 else if (*Otemp == '\'')
1812 {
1813 Otemp++;
1814 Temp_Stack[place++] = *Otemp;
1815 Otemp++;
1816 Otemp++;
1817 }
1818 else if (*Otemp == '{')
1819 {
1820 Otemp++;
1821 temp = atoi(Otemp);
1822 Temp_Stack[place++] = temp;
1823 while (*Otemp != '}')
1824 Otemp++;
1825 Otemp++;
1826 }
1827 return(place);
1828 }
1829
1830 void
Info_Out(string,p_list,place)1831 Info_Out(string, p_list, place) /* interpret the output string if necessary */
1832 char *string;
1833 int p_list[];
1834 int place;
1835 {
1836 char *tchar;
1837 int delay;
1838 int temp;
1839 int Cond_FLAG;
1840 int EVAL;
1841 int Cond_Stack[128];
1842 int Cond_place;
1843 int Stack[128];
1844 int Top_of_stack;
1845
1846 if (string == NULL)
1847 return;
1848
1849 Cond_FLAG = FALSE;
1850 Cond_place = 0;
1851 Top_of_stack = 0;
1852 p[0] = 0;
1853 p[1] = 0;
1854 p[2] = 0;
1855 p[3] = 0;
1856 p[4] = 0;
1857 p[5] = 0;
1858 p[6] = 0;
1859 p[7] = 0;
1860 p[8] = 0;
1861 p[9] = 0;
1862 if (p_list != NULL)
1863 {
1864 for (temp = 1; (place != 0); temp++)
1865 {
1866 p[temp] = p_list[--place];
1867 }
1868 }
1869 delay = 0;
1870 Otemp = string;
1871 while (*Otemp != '\0')
1872 {
1873 if (*Otemp == '%')
1874 {
1875 Otemp++;
1876 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1877 {
1878 if (*Otemp == '?')
1879 {
1880 Otemp++;
1881 Cond_FLAG = TRUE;
1882 EVAL = TRUE;
1883 while (EVAL)
1884 {
1885 /*
1886 | find the end of the
1887 | conditional statement
1888 */
1889 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != '\0'))
1890 {
1891 /*
1892 | move past '%'
1893 */
1894 Otemp++;
1895 Cond_place = Operation(Cond_Stack, Cond_place);
1896 }
1897
1898 /*
1899 | if condition is true
1900 */
1901 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1902 {
1903 /*
1904 | end conditional
1905 | parsing
1906 */
1907 EVAL = FALSE;
1908 Otemp++;
1909 Otemp++;
1910 }
1911 else /* condition is false */
1912 {
1913 /*
1914 | find 'else' or end
1915 | of if statement
1916 */
1917 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != '\0'))
1918 Otemp++;
1919 /*
1920 | if an 'else' found
1921 */
1922 if ((*Otemp != '\0') && (!strncmp(Otemp, "%e", 2)))
1923 {
1924 Otemp++;
1925 Otemp++;
1926 tchar = Otemp;
1927 /*
1928 | check for 'then' part
1929 */
1930 while ((*tchar != '\0') && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1931 tchar++;
1932 /*
1933 | if end of string
1934 */
1935 if (*tchar == '\0')
1936 {
1937 EVAL = FALSE;
1938 Cond_FLAG = FALSE;
1939 Otemp = tchar;
1940 }
1941 /*
1942 | if end of if found,
1943 | set up to parse
1944 | info
1945 */
1946 else if (!strncmp(tchar, "%;", 2))
1947 EVAL = FALSE;
1948 /*
1949 | otherwise, check
1950 | conditional in
1951 | 'else'
1952 */
1953 }
1954 /*
1955 | if end of if found,
1956 | get out of if
1957 | statement
1958 */
1959 else if ((*Otemp != '\0') && (!strncmp(Otemp, "%;", 2)))
1960 {
1961 EVAL = FALSE;
1962 Otemp++;
1963 Otemp++;
1964 }
1965 else /* Otemp == NULL */
1966 {
1967 EVAL = FALSE;
1968 Cond_FLAG = FALSE;
1969 }
1970 }
1971 }
1972 }
1973 else
1974 {
1975 Otemp++;
1976 Cond_FLAG = FALSE;
1977 if (*Otemp != ';')
1978 {
1979 while ((*Otemp != '\0') && (strncmp(Otemp, "%;", 2)))
1980 Otemp++;
1981 if (*Otemp != '\0')
1982 {
1983 Otemp++;
1984 Otemp++;
1985 }
1986 }
1987 else
1988 Otemp++;
1989 }
1990 }
1991 else
1992 {
1993 Top_of_stack = Operation(Stack, Top_of_stack);
1994 }
1995 }
1996 else if (!strncmp(Otemp, "$<", 2))
1997 {
1998 Otemp++;
1999 Otemp++;
2000 delay = atoi(Otemp);
2001 while (*Otemp != '>')
2002 Otemp++;
2003 Otemp++;
2004 chars = delay * chars_per_millisecond;
2005 delay = chars;
2006 if ((chars - delay) > 0.0)
2007 delay++;
2008 if (String_table[pc__] == NULL)
2009 temp = 0;
2010 else
2011 temp = *String_table[pc__];
2012 for (; delay > 0; delay--)
2013 putc(temp, stdout);
2014 }
2015 else
2016 {
2017 putchar(*Otemp);
2018 Otemp++;
2019 }
2020 }
2021 fflush(stdout);
2022 }
2023 #endif
2024
2025 void
wmove(window,row,column)2026 wmove(window, row, column) /* move cursor to indicated position in window */
2027 WINDOW *window;
2028 int row, column;
2029 {
2030 if ((row < window->Num_lines) && (column < window->Num_cols))
2031 {
2032 window->LX = column;
2033 window->LY = row;
2034 }
2035 }
2036
2037 void
clear_line(line,column,cols)2038 clear_line(line, column, cols)
2039 struct _line *line;
2040 int column;
2041 int cols;
2042 {
2043 int j;
2044
2045 if (column > line->last_char)
2046 {
2047 for (j = line->last_char; j < column; j++)
2048 {
2049 line->row[j] = ' ';
2050 line->attributes[j] = '\0';
2051 }
2052 }
2053 line->last_char = column;
2054 line->row[column] = '\0';
2055 line->attributes[column] = '\0';
2056 line->changed = TRUE;
2057 }
2058
2059 void
werase(window)2060 werase(window) /* clear the specified window */
2061 WINDOW *window;
2062 {
2063 int i;
2064 struct _line *tmp;
2065
2066 window->SCROLL_CLEAR = CLEAR;
2067 window->scroll_up = window->scroll_down = 0;
2068 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2069 clear_line(tmp, 0, window->Num_cols);
2070 }
2071
2072 void
wclrtoeol(window)2073 wclrtoeol(window) /* erase from current cursor position to end of line */
2074 WINDOW *window;
2075 {
2076 int column, row;
2077 struct _line *tmp;
2078
2079 window->SCROLL_CLEAR = CHANGE;
2080 column = window->LX;
2081 row = window->LY;
2082 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2083 tmp = tmp->next_screen;
2084 clear_line(tmp, column, window->Num_cols);
2085 }
2086
2087 void
wrefresh(window)2088 wrefresh(window) /* flush all previous output */
2089 WINDOW *window;
2090 {
2091 wnoutrefresh(window);
2092 #ifdef DIAG
2093 {
2094 struct _line *temp;
2095 int value;
2096 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2097 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2098 {
2099 if (temp->number == -1)
2100 fprintf(stderr, "line moved ");
2101 if (temp->scroll)
2102 fprintf(stderr, "scroll_x is set: ");
2103 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2104 }
2105 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2106 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2107 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2108 {
2109 if (temp->number == -1)
2110 fprintf(stderr, "line moved ");
2111 if (temp->scroll)
2112 fprintf(stderr, "scroll_x is set: ");
2113 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2114 }
2115 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2116 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2117 fprintf(stderr, "line=%s|\n", temp->row);
2118 }
2119 #endif
2120 doupdate();
2121 virtual_scr->SCROLL_CLEAR = FALSE;
2122 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2123 fflush(stdout);
2124 }
2125
2126 void
touchwin(window)2127 touchwin(window)
2128 WINDOW *window;
2129 {
2130 struct _line *user_line;
2131 int line_counter = 0;
2132
2133 for (line_counter = 0, user_line = window->first_line;
2134 line_counter < window->Num_lines; line_counter++)
2135 {
2136 user_line->changed = TRUE;
2137 }
2138 window->SCROLL_CLEAR = TRUE;
2139 }
2140
2141 void
wnoutrefresh(window)2142 wnoutrefresh(window)
2143 WINDOW *window;
2144 {
2145 struct _line *user_line;
2146 struct _line *virtual_line;
2147 int line_counter = 0;
2148 int user_col = 0;
2149 int virt_col = 0;
2150
2151 if (window->SR >= virtual_scr->Num_lines)
2152 return;
2153 user_line = window->first_line;
2154 virtual_line = virtual_scr->first_line;
2155 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2156 virtual_scr->LX = window->LX + window->SC;
2157 virtual_scr->LY = window->LY + window->SR;
2158 virtual_scr->scroll_up = window->scroll_up;
2159 virtual_scr->scroll_down = window->scroll_down;
2160 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2161 return;
2162 for (line_counter = 0; line_counter < window->SR; line_counter++)
2163 {
2164 virtual_line = virtual_line->next_screen;
2165 }
2166 for (line_counter = 0; (line_counter < window->Num_lines)
2167 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2168 line_counter++)
2169 {
2170 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2171 {
2172 for (user_col = 0, virt_col = window->SC;
2173 (virt_col < virtual_scr->Num_cols)
2174 && (user_col < user_line->last_char);
2175 virt_col++, user_col++)
2176 {
2177 virtual_line->row[virt_col] = user_line->row[user_col];
2178 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2179 }
2180 for (user_col = user_line->last_char,
2181 virt_col = window->SC + user_line->last_char;
2182 (virt_col < virtual_scr->Num_cols)
2183 && (user_col < window->Num_cols);
2184 virt_col++, user_col++)
2185 {
2186 virtual_line->row[virt_col] = ' ';
2187 virtual_line->attributes[virt_col] = '\0';
2188 }
2189 }
2190 if (virtual_scr->Num_cols != window->Num_cols)
2191 {
2192 if (virtual_line->last_char < (user_line->last_char + window->SC))
2193 {
2194 if (virtual_line->row[virtual_line->last_char] == '\0')
2195 virtual_line->row[virtual_line->last_char] = ' ';
2196 virtual_line->last_char =
2197 min(virtual_scr->Num_cols,
2198 (user_line->last_char + window->SC));
2199 }
2200 }
2201 else
2202 virtual_line->last_char = user_line->last_char;
2203 virtual_line->row[virtual_line->last_char] = '\0';
2204 virtual_line->changed = user_line->changed;
2205 virtual_line = virtual_line->next_screen;
2206 user_line = user_line->next_screen;
2207 }
2208 window->SCROLL_CLEAR = FALSE;
2209 window->scroll_up = window->scroll_down = 0;
2210 last_window_refreshed = window;
2211 }
2212
2213 void
flushinp()2214 flushinp() /* flush input */
2215 {
2216 }
2217
2218 void
ungetch(c)2219 ungetch(c) /* push a character back on input */
2220 int c;
2221 {
2222 if (bufp < 100)
2223 in_buff[bufp++] = c;
2224 }
2225
2226 #ifdef BSD_SELECT
2227 int
timed_getchar()2228 timed_getchar()
2229 {
2230 struct timeval tv;
2231 fd_set fds;
2232 int ret_val;
2233 int nfds = 1;
2234 char temp;
2235
2236 FD_ZERO(&fds);
2237 tv.tv_sec = 0;
2238 tv.tv_usec = 500000; /* half a second */
2239 FD_SET(0, &fds);
2240 Time_Out = FALSE; /* just in case */
2241
2242 ret_val = select(nfds, &fds, 0, 0, &tv);
2243
2244 /*
2245 | if ret_val is less than zero, there was no input
2246 | otherwise, get a character and return it
2247 */
2248
2249 if (ret_val <= 0)
2250 {
2251 Time_Out = TRUE;
2252 return(-1);
2253 }
2254
2255 return(read(0, &temp, 1)? temp : -1);
2256 }
2257 #endif
2258
2259 int
wgetch(window)2260 wgetch(window) /* get character from specified window */
2261 WINDOW *window;
2262 {
2263 int in_value;
2264 char temp;
2265 #ifndef SYS5
2266 int old_arg;
2267 #endif /* SYS5 */
2268
2269 #ifdef BSD_SELECT
2270 if (Noblock)
2271 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2272 else
2273 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2274 #else /* BSD_SELECT */
2275 #ifdef SYS5
2276 in_value = ((bufp > 0) ? in_buff[--bufp] :
2277 (read(0, &temp, 1)> 0) ? temp : -1);
2278 #else /* SYS5 */
2279 if (Noblock)
2280 {
2281 Time_Out = FALSE;
2282 old_arg = fcntl(0, F_GETFL, 0);
2283 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2284 }
2285 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2286 if (Noblock)
2287 {
2288 fcntl(0, F_SETFL, old_arg);
2289 if (Time_Out)
2290 in_value = -1;
2291 }
2292 #endif /* SYS5 */
2293 #endif /* BSD_SELECT */
2294
2295 if (in_value != -1)
2296 {
2297 in_value &= 0xff;
2298 if ((Parity) && (Num_bits < 8))
2299 /* strip eighth bit if parity in use */
2300 in_value &= 0177;
2301 }
2302 else if (interrupt_flag)
2303 {
2304 interrupt_flag = FALSE;
2305 in_value = wgetch(window);
2306 }
2307
2308 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2309 in_value = Get_key(in_value);
2310 return(in_value);
2311 }
2312
2313 #ifndef BSD_SELECT
2314 void
Clear(arg)2315 Clear(arg) /* notify that time out has occurred */
2316 int arg;
2317 {
2318 Time_Out = TRUE;
2319 #ifdef DEBUG
2320 fprintf(stderr, "inside Clear()\n");
2321 fflush(stderr);
2322 #endif /* DEBUG */
2323 }
2324 #endif /* BSD_SELECT */
2325
2326 int
Get_key(first_char)2327 Get_key(first_char) /* try to decode key sequence */
2328 int first_char; /* first character of sequence */
2329 {
2330 int in_char;
2331 int Count;
2332 char string[128];
2333 char *Gtemp;
2334 int Found;
2335 #ifdef SYS5
2336 struct termio Gterminal;
2337 #else
2338 struct sgttyb Gterminal;
2339 #endif
2340 struct KEY_STACK *St_point;
2341 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2342 int value;
2343 #endif /* BSD_SELECT */
2344
2345 Count = 0;
2346 Gtemp = string;
2347 string[Count++] = first_char;
2348 string[Count] = '\0';
2349 Time_Out = FALSE;
2350 #ifndef BSD_SELECT
2351 signal(SIGALRM, Clear);
2352 value = alarm(1);
2353 #endif /* BSD_SELECT */
2354 Noblock = TRUE;
2355 #ifdef SYS5
2356 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2357 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2358 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2359 #endif
2360 Count = 1;
2361 Found = FALSE;
2362 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2363 {
2364 in_char = wgetch(stdscr);
2365 #ifdef DEBUG
2366 fprintf(stderr, "back in GetKey()\n");
2367 fflush(stderr);
2368 #endif /* DEBUG */
2369 if (in_char != -1)
2370 {
2371 string[Count++] = in_char;
2372 string[Count] = '\0';
2373 St_point = KEY_TOS;
2374 while ((St_point != NULL) && (!Found))
2375 {
2376 if (!strcmp(string, St_point->element->string))
2377 Found = TRUE;
2378 else
2379 St_point = St_point->next;
2380 }
2381 }
2382 }
2383 #ifndef BSD_SELECT
2384 if (!Time_Out)
2385 value = alarm(0);
2386 #endif /* BSD_SELECT */
2387 #ifdef SYS5
2388 /* value = ioctl(0, TCSETA, &Terminal);*/
2389 #else
2390 value = ioctl(0, TIOCSETP, &Terminal);
2391 /* value = fcntl(0, F_SETFL, old_arg);*/
2392 #endif
2393 Noblock = FALSE;
2394 if (Found)
2395 {
2396 return(St_point->element->value);
2397 }
2398 else
2399 {
2400 while (Count > 1)
2401 {
2402 if ((string[--Count] != -1) &&
2403 ((unsigned char) (string[Count]) != 255))
2404 {
2405 #ifdef DIAG
2406 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2407 #endif
2408 ungetch(string[Count]);
2409 }
2410 }
2411 return(first_char);
2412 }
2413 }
2414
2415 void
waddch(window,c)2416 waddch(window, c) /* output the character in the specified window */
2417 WINDOW *window;
2418 int c;
2419 {
2420 int column, j;
2421 int shift; /* number of spaces to shift if a tab */
2422 struct _line *tmpline;
2423
2424 #ifdef DIAG
2425 /*printf("starting waddch \n");fflush(stdout);*/
2426 #endif
2427 column = window->LX;
2428 if (c == '\t')
2429 {
2430 shift = (column + 1) % 8;
2431 if (shift == 0)
2432 shift++;
2433 else
2434 shift = 9 - shift;
2435 while (shift > 0)
2436 {
2437 shift--;
2438 waddch(window, ' ');
2439 }
2440 }
2441 else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
2442 {
2443 if ((c == '~') && (Booleans[hz__]))
2444 c = '@';
2445
2446 if (( c != '\b') && (c != '\n') && (c != '\r'))
2447 {
2448 tmpline = window->line_array[window->LY];
2449 tmpline->row[column] = c;
2450 tmpline->attributes[column] = window->Attrib;
2451 tmpline->changed = TRUE;
2452 if (column >= tmpline->last_char)
2453 {
2454 if (column > tmpline->last_char)
2455 for (j = tmpline->last_char; j < column; j++)
2456 {
2457 tmpline->row[j] = ' ';
2458 tmpline->attributes[j] = '\0';
2459 }
2460 tmpline->row[column + 1] = '\0';
2461 tmpline->attributes[column + 1] = '\0';
2462 tmpline->last_char = column + 1;
2463 }
2464 }
2465 if (c == '\n')
2466 {
2467 wclrtoeol(window);
2468 window->LX = window->Num_cols;
2469 }
2470 else if (c == '\r')
2471 window->LX = 0;
2472 else if (c == '\b')
2473 window->LX--;
2474 else
2475 window->LX++;
2476 }
2477 if (window->LX >= window->Num_cols)
2478 {
2479 window->LX = 0;
2480 window->LY++;
2481 if (window->LY >= window->Num_lines)
2482 {
2483 window->LY = window->Num_lines - 1;
2484 /* window->LY = row;
2485 wmove(window, 0, 0);
2486 wdeleteln(window);
2487 wmove(window, row, 0);*/
2488 }
2489 }
2490 window->SCROLL_CLEAR = CHANGE;
2491 }
2492
2493 void
winsertln(window)2494 winsertln(window) /* insert a blank line into the specified window */
2495 WINDOW *window;
2496 {
2497 int row, column;
2498 struct _line *tmp;
2499 struct _line *tmp1;
2500
2501 window->scroll_down += 1;
2502 window->SCROLL_CLEAR = SCROLL;
2503 column = window->LX;
2504 row = window->LY;
2505 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2506 tmp = tmp->next_screen;
2507 if (tmp->prev_screen != NULL)
2508 tmp->prev_screen->next_screen = NULL;
2509 tmp1 = tmp;
2510 clear_line(tmp1, 0, window->Num_cols);
2511 tmp1->number = -1;
2512 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2513 tmp = tmp->next_screen;
2514 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2515 {
2516 tmp1->next_screen = tmp->next_screen;
2517 tmp->next_screen = tmp1;
2518 tmp->changed = TRUE;
2519 tmp->next_screen->prev_screen = tmp;
2520 }
2521 else if (window->Num_lines > 1)
2522 {
2523 if (tmp->prev_screen != NULL)
2524 tmp->prev_screen->next_screen = tmp1;
2525 tmp1->prev_screen = tmp->prev_screen;
2526 tmp->prev_screen = tmp1;
2527 tmp1->next_screen = tmp;
2528 tmp->changed = TRUE;
2529 tmp->scroll = DOWN;
2530 }
2531 if (window->LY == 0)
2532 window->first_line = tmp1;
2533
2534 for (row = 0, tmp1 = window->first_line;
2535 row < window->Num_lines; row++)
2536 {
2537 window->line_array[row] = tmp1;
2538 tmp1 = tmp1->next_screen;
2539 }
2540 }
2541
2542 void
wdeleteln(window)2543 wdeleteln(window) /* delete a line in the specified window */
2544 WINDOW *window;
2545 {
2546 int row, column;
2547 struct _line *tmp;
2548 struct _line *tmpline;
2549
2550 if (window->Num_lines > 1)
2551 {
2552 window->scroll_up += 1;
2553 window->SCROLL_CLEAR = SCROLL;
2554 column = window->LX;
2555 row = window->LY;
2556 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2557 tmp = tmp->next_screen;
2558 if (window->LY == 0)
2559 window->first_line = tmp->next_screen;
2560 if (tmp->prev_screen != NULL)
2561 tmp->prev_screen->next_screen = tmp->next_screen;
2562 if (tmp->next_screen != NULL)
2563 {
2564 tmp->next_screen->changed = TRUE;
2565 tmp->next_screen->scroll = UP;
2566 tmp->next_screen->prev_screen = tmp->prev_screen;
2567 }
2568 tmpline = tmp;
2569 clear_line(tmpline, 0, window->Num_cols);
2570 tmpline->number = -1;
2571 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2572 tmp = tmp->next_screen;
2573 if (tmp != NULL)
2574 {
2575 tmp->next_screen = tmpline;
2576 tmp->next_screen->prev_screen = tmp;
2577 tmp->changed = TRUE;
2578 tmp = tmp->next_screen;
2579 }
2580 else
2581 tmp = tmpline;
2582 tmp->next_screen = NULL;
2583
2584 for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
2585 {
2586 window->line_array[row] = tmp;
2587 tmp = tmp->next_screen;
2588 }
2589 }
2590 else
2591 {
2592 clear_line(window->first_line, 0, window->Num_cols);
2593 }
2594 }
2595
2596 void
wclrtobot(window)2597 wclrtobot(window) /* delete from current position to end of the window */
2598 WINDOW *window;
2599 {
2600 int row, column;
2601 struct _line *tmp;
2602
2603 window->SCROLL_CLEAR |= CLEAR;
2604 column = window->LX;
2605 row = window->LY;
2606 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2607 tmp = tmp->next_screen;
2608 clear_line(tmp, column, window->Num_cols);
2609 for (row = (window->LY + 1); row < window->Num_lines; row++)
2610 {
2611 tmp = tmp->next_screen;
2612 clear_line(tmp, 0, window->Num_cols);
2613 }
2614 wmove(window, row, column);
2615 }
2616
2617 void
wstandout(window)2618 wstandout(window) /* begin standout mode in window */
2619 WINDOW *window;
2620 {
2621 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2622 window->Attrib |= A_STANDOUT;
2623 }
2624
2625 void
wstandend(window)2626 wstandend(window) /* end standout mode in window */
2627 WINDOW *window;
2628 {
2629 window->Attrib &= ~A_STANDOUT;
2630 }
2631
2632 void
waddstr(window,string)2633 waddstr(window, string) /* write 'string' in window */
2634 WINDOW *window;
2635 char *string;
2636 {
2637 char *wstring;
2638
2639 for (wstring = string; *wstring != '\0'; wstring++)
2640 waddch(window, *wstring);
2641 }
2642
2643 void
clearok(window,flag)2644 clearok(window, flag) /* erase screen and redraw at next refresh */
2645 WINDOW *window;
2646 int flag;
2647 {
2648 Repaint_screen = TRUE;
2649 }
2650
2651
2652 void
echo()2653 echo() /* turn on echoing */
2654 {
2655 int value;
2656
2657 #ifdef SYS5
2658 Terminal.c_lflag |= ECHO; /* enable echo */
2659 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2660 #else
2661 Terminal.sg_flags |= ECHO; /* enable echo */
2662 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2663 #endif
2664 }
2665
2666 void
noecho()2667 noecho() /* turn off echoing */
2668 {
2669 int value;
2670
2671 #ifdef SYS5
2672 Terminal.c_lflag &= ~ECHO; /* disable echo */
2673 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2674 #else
2675 Terminal.sg_flags &= ~ECHO; /* disable echo */
2676 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2677 #endif
2678 }
2679
2680 void
raw()2681 raw() /* set to read characters immediately */
2682 {
2683 int value;
2684
2685 #ifdef SYS5
2686 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2687 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2688 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2689 #ifdef FLUSHO
2690 Terminal.c_lflag &= ~FLUSHO;
2691 #endif
2692 #ifdef PENDIN
2693 Terminal.c_lflag &= ~PENDIN;
2694 #endif
2695 #ifdef IEXTEN
2696 Terminal.c_lflag &= ~IEXTEN;
2697 #endif
2698 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2699 Terminal.c_cc[VTIME] = 0; /* timeout value */
2700 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2701 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2702 #else
2703 Terminal.sg_flags |= RAW; /* enable raw mode */
2704 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2705 #endif
2706 }
2707
2708 void
noraw()2709 noraw() /* set to normal character read mode */
2710 {
2711 int value;
2712
2713 #ifdef SYS5
2714 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2715 Terminal.c_lflag |= ISIG; /* enable signal checking */
2716 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2717 Terminal.c_cc[VEOL] = '\0'; /* EOL = 0 */
2718 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2719 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2720 #else
2721 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2722 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2723 /* old_arg = fcntl(0, F_GETFL, 0);
2724 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2725 #endif
2726 }
2727
2728 void
nl()2729 nl()
2730 {
2731 int value;
2732
2733 #ifdef SYS5
2734 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2735 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2736 #endif
2737 }
2738
2739 void
nonl()2740 nonl()
2741 {
2742 int value;
2743
2744 #ifdef SYS5
2745 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2746 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2747 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2748 #endif
2749 }
2750
2751 void
saveterm()2752 saveterm()
2753 {
2754 }
2755
2756 void
fixterm()2757 fixterm()
2758 {
2759 }
2760
2761 void
resetterm()2762 resetterm()
2763 {
2764 }
2765
2766 void
nodelay(window,flag)2767 nodelay(window, flag)
2768 WINDOW *window;
2769 int flag;
2770 {
2771 }
2772
2773 void
idlok(window,flag)2774 idlok(window, flag)
2775 WINDOW *window;
2776 int flag;
2777 {
2778 }
2779
2780 void
keypad(window,flag)2781 keypad(window, flag)
2782 WINDOW *window;
2783 int flag;
2784 {
2785 if (flag)
2786 String_Out(String_table[ks__], NULL, 0);
2787 else
2788 String_Out(String_table[ke__], NULL, 0);
2789 }
2790
2791 void
savetty()2792 savetty() /* save current tty stats */
2793 {
2794 int value;
2795
2796 #ifdef SYS5
2797 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2798 #else
2799 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2800 #endif
2801 }
2802
2803 void
resetty()2804 resetty() /* restore previous tty stats */
2805 {
2806 int value;
2807
2808 #ifdef SYS5
2809 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2810 #else
2811 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2812 #endif
2813 }
2814
2815 void
endwin()2816 endwin() /* end windows */
2817 {
2818 keypad(stdscr, FALSE);
2819 initialized = FALSE;
2820 delwin(curscr);
2821 delwin(virtual_scr);
2822 delwin(stdscr);
2823 #ifndef SYS5
2824 {
2825 int old_arg, value;
2826 /* old_arg = fcntl(0, F_GETFL, 0);
2827 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2828 }
2829 #endif
2830 }
2831
2832 void
delwin(window)2833 delwin(window) /* delete the window structure */
2834 WINDOW *window;
2835 {
2836 int i;
2837
2838 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2839 {
2840 window->first_line = window->first_line->next_screen;
2841 free(window->first_line->prev_screen->row);
2842 free(window->first_line->prev_screen->attributes);
2843 free(window->first_line->prev_screen);
2844 }
2845 if (window == last_window_refreshed)
2846 last_window_refreshed = 0;
2847 if (window->first_line != NULL)
2848 {
2849 free(window->first_line->row);
2850 free(window->first_line->attributes);
2851 free(window->first_line);
2852 free(window);
2853 }
2854 }
2855
2856 #ifndef __STDC__
2857 void
wprintw(va_alist)2858 wprintw(va_alist)
2859 va_dcl
2860 #else /* __STDC__ */
2861 void
2862 wprintw(WINDOW *window, const char *format, ...)
2863 #endif /* __STDC__ */
2864 {
2865 #ifndef __STDC__
2866 WINDOW *window;
2867 char *format;
2868 va_list ap;
2869 #else
2870 va_list ap;
2871 #endif
2872 int value;
2873 char *fpoint;
2874 char *wtemp;
2875
2876 #ifndef __STDC__
2877 va_start(ap);
2878 window = va_arg(ap, WINDOW *);
2879 format = va_arg(ap, char *);
2880 #else /* __STDC__ */
2881 va_start(ap, format);
2882 #endif /* __STDC__ */
2883
2884 fpoint = (char *) format;
2885 while (*fpoint != '\0')
2886 {
2887 if (*fpoint == '%')
2888 {
2889 fpoint++;
2890 if (*fpoint == 'd')
2891 {
2892 value = va_arg(ap, int);
2893 iout(window, value);
2894 }
2895 else if (*fpoint == 'c')
2896 {
2897 value = va_arg(ap, int);
2898 waddch(window, value);
2899 }
2900 else if (*fpoint == 's')
2901 {
2902 wtemp = va_arg(ap, char *);
2903 waddstr(window, wtemp);
2904 }
2905 fpoint++;
2906 }
2907 else if (*fpoint == '\\')
2908 {
2909 fpoint++;
2910 if (*fpoint == 'n')
2911 waddch(window, '\n');
2912 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2913 {
2914 value = 0;
2915 while ((*fpoint >= '0') && (*fpoint <= '9'))
2916 {
2917 value = (value * 8) + (*fpoint - '0');
2918 fpoint++;
2919 }
2920 waddch(window, value);
2921 }
2922 fpoint++;
2923 }
2924 else
2925 waddch(window, *fpoint++);
2926 }
2927 #ifdef __STDC__
2928 va_end(ap);
2929 #endif /* __STDC__ */
2930 }
2931
2932 void
iout(window,value)2933 iout(window, value) /* output characters */
2934 WINDOW *window;
2935 int value;
2936 {
2937 int i;
2938
2939 if ((i = value / 10) != 0)
2940 iout(window, i);
2941 waddch(window, ((value % 10) + '0'));
2942 }
2943
2944 int
Comp_line(line1,line2)2945 Comp_line(line1, line2) /* compare lines */
2946 struct _line *line1;
2947 struct _line *line2;
2948 {
2949 int count1;
2950 int i;
2951 char *att1, *att2;
2952 char *c1, *c2;
2953
2954 if (line1->last_char != line2->last_char)
2955 return(2);
2956
2957 c1 = line1->row;
2958 c2 = line2->row;
2959 att1 = line1->attributes;
2960 att2 = line2->attributes;
2961 i = 0;
2962 while ((c1[i] != '\0') && (c2[i] != '\0') && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2963 i++;
2964 count1 = i + 1;
2965 if ((count1 == 1) && (c1[i] == '\0') && (c2[i] == '\0'))
2966 count1 = 0; /* both lines blank */
2967 else if ((c1[i] == '\0') && (c2[i] == '\0'))
2968 count1 = -1; /* equal */
2969 else
2970 count1 = 1; /* lines unequal */
2971 return(count1);
2972 }
2973
2974 struct _line *
Insert_line(row,end_row,window)2975 Insert_line(row, end_row, window) /* insert line into screen */
2976 int row;
2977 int end_row;
2978 WINDOW *window;
2979 {
2980 int i;
2981 struct _line *tmp;
2982 struct _line *tmp1;
2983
2984 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2985 tmp = tmp->next_screen;
2986 if ((end_row + window->SR) == 0)
2987 curscr->first_line = curscr->first_line->next_screen;
2988 top_of_win = tmp;
2989 /*
2990 | find bottom line to delete
2991 */
2992 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2993 tmp = tmp->next_screen;
2994 if (tmp->prev_screen != NULL)
2995 tmp->prev_screen->next_screen = tmp->next_screen;
2996 if (tmp->next_screen != NULL)
2997 tmp->next_screen->prev_screen = tmp->prev_screen;
2998 tmp1 = tmp;
2999 /*
3000 | clear deleted line
3001 */
3002 clear_line(tmp, 0, window->Num_cols);
3003 tmp1->number = -1;
3004 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3005 tmp = tmp->next_screen;
3006 top_of_win = tmp;
3007 for (i = 0, tmp = top_of_win; i < row; i++)
3008 tmp = tmp->next_screen;
3009 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
3010 tmp->prev_screen->next_screen = tmp1;
3011 tmp1->prev_screen = tmp->prev_screen;
3012 tmp->prev_screen = tmp1;
3013 tmp1->next_screen = tmp;
3014 if ((row + window->SR) == 0)
3015 curscr->first_line = tmp1;
3016 if (tmp1->next_screen != NULL)
3017 tmp1 = tmp1->next_screen;
3018
3019 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3020 {
3021 Position(window, (window->SR + end_row), 0);
3022 String_Out(String_table[dl__], NULL, 0);
3023 }
3024 Position(window, (window->SR + row), 0);
3025 if (String_table[al__] != NULL)
3026 String_Out(String_table[al__], NULL, 0);
3027 else
3028 String_Out(String_table[sr__], NULL, 0);
3029
3030 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3031 top_of_win = top_of_win->next_screen;
3032 return(tmp1);
3033 }
3034
3035
3036 struct _line *
Delete_line(row,end_row,window)3037 Delete_line(row, end_row, window) /* delete a line on screen */
3038 int row;
3039 int end_row;
3040 WINDOW *window;
3041 {
3042 int i;
3043 struct _line *tmp;
3044 struct _line *tmp1;
3045 struct _line *tmp2;
3046
3047 i = 0;
3048 tmp = curscr->first_line;
3049 while (i < window->SR)
3050 {
3051 i++;
3052 tmp = tmp->next_screen;
3053 }
3054 /*
3055 | find line to delete
3056 */
3057 top_of_win = tmp;
3058 if ((row + window->SR) == 0)
3059 curscr->first_line = top_of_win->next_screen;
3060 for (i = 0, tmp = top_of_win; i < row; i++)
3061 tmp = tmp->next_screen;
3062 if (tmp->prev_screen != NULL)
3063 tmp->prev_screen->next_screen = tmp->next_screen;
3064 if (tmp->next_screen != NULL)
3065 tmp->next_screen->prev_screen = tmp->prev_screen;
3066 tmp2 = tmp->next_screen;
3067 tmp1 = tmp;
3068 /*
3069 | clear deleted line
3070 */
3071 clear_line(tmp1, 0, window->Num_cols);
3072 tmp1->number = -1;
3073 /*
3074 | find location to insert deleted line
3075 */
3076 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3077 tmp = tmp->next_screen;
3078 top_of_win = tmp;
3079 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3080 tmp = tmp->next_screen;
3081 tmp1->next_screen = tmp;
3082 tmp1->prev_screen = tmp->prev_screen;
3083 if (tmp1->prev_screen != NULL)
3084 tmp1->prev_screen->next_screen = tmp1;
3085 tmp->prev_screen = tmp1;
3086
3087 Position(window, (window->SR + row), 0);
3088 String_Out(String_table[dl__], NULL, 0);
3089 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3090 {
3091 Position(window, (window->SR + end_row), 0);
3092 String_Out(String_table[al__], NULL, 0);
3093 }
3094 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3095 {
3096 Position(window, (window->SR + end_row), 0);
3097 putchar('\n');
3098 }
3099
3100 if (row == (window->Num_lines-1))
3101 tmp2 = tmp1;
3102 if ((row + window->SR) == 0)
3103 curscr->first_line = top_of_win = tmp2;
3104 return(tmp2);
3105 }
3106
3107 void
CLEAR_TO_EOL(window,row,column)3108 CLEAR_TO_EOL(window, row, column)
3109 WINDOW *window;
3110 int row, column;
3111 {
3112 int x, y;
3113 struct _line *tmp1;
3114
3115 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3116 tmp1 = tmp1->next_screen;
3117 for (x = column; x<window->Num_cols; x++)
3118 {
3119 tmp1->row[x] = ' ';
3120 tmp1->attributes[x] = '\0';
3121 }
3122 tmp1->row[column] = '\0';
3123 tmp1->last_char = column;
3124 if (column < COLS)
3125 {
3126 if (STAND)
3127 {
3128 STAND = FALSE;
3129 Position(window, row, column);
3130 attribute_off();
3131 }
3132 if (String_table[ce__] != NULL)
3133 String_Out(String_table[ce__], NULL, 0);
3134 else
3135 {
3136 for (x = column; x < window->Num_cols; x++)
3137 putchar(' ');
3138 Curr_x = x;
3139 }
3140 }
3141 }
3142
3143 int
check_delete(window,line,offset,pointer_new,pointer_old)3144 check_delete(window, line, offset, pointer_new, pointer_old)
3145 WINDOW *window;
3146 int line, offset;
3147 struct _line *pointer_new, *pointer_old;
3148 {
3149 int end_old;
3150 int end_new;
3151 int k;
3152 int changed;
3153 char *old_lin;
3154 char *new_lin;
3155 char *old_att;
3156 char *new_att;
3157
3158 changed = FALSE;
3159 new_lin = pointer_new->row;
3160 new_att = pointer_new->attributes;
3161 old_lin = pointer_old->row;
3162 old_att = pointer_old->attributes;
3163 end_old = end_new = offset;
3164 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != '\0') && (new_lin[end_old] != '\0'))
3165 end_old++;
3166 if (old_lin[end_old] != '\0')
3167 {
3168 k = 0;
3169 while ((old_lin[end_old+k] == new_lin[end_new+k]) && (new_att[end_new+k] == old_att[end_old+k]) && (new_lin[end_new+k] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10))
3170 k++;
3171 if ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0)))
3172 {
3173 if (new_lin[end_new+k] == '\0')
3174 {
3175 Position(window, line, (end_new+k));
3176 CLEAR_TO_EOL(window, line, (end_new+k));
3177 }
3178 Position(window, line, offset);
3179 for (k = offset; k < end_old; k++)
3180 Char_del(old_lin, old_att, offset, window->Num_cols);
3181 while ((old_lin[offset] != '\0') && (offset < COLS))
3182 offset++;
3183 pointer_old->last_char = offset;
3184 changed = TRUE;
3185 }
3186 }
3187 return(changed);
3188 }
3189
3190 /*
3191 | Check if characters were inserted in the middle of a line, and if
3192 | so, insert them.
3193 */
3194
3195 int
check_insert(window,line,offset,pointer_new,pointer_old)3196 check_insert(window, line, offset, pointer_new, pointer_old)
3197 WINDOW *window;
3198 int line, offset;
3199 struct _line *pointer_new, *pointer_old;
3200 {
3201 int changed;
3202 int end_old, end_new;
3203 int k;
3204 int same = FALSE;
3205 int old_off;
3206 int insert;
3207 char *old_lin;
3208 char *new_lin;
3209 char *old_att;
3210 char *new_att;
3211
3212 changed = FALSE;
3213 new_lin = pointer_new->row;
3214 new_att = pointer_new->attributes;
3215 old_lin = pointer_old->row;
3216 old_att = pointer_old->attributes;
3217 end_old = end_new = offset;
3218 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != '\0') && (old_lin[end_new] != '\0'))
3219 end_new++;
3220 if (new_lin[end_new] != '\0')
3221 {
3222 k = 0;
3223 while ((old_lin[end_old+k] == new_lin[end_new+k]) && (old_att[end_old+k] == new_att[end_new+k]) && (new_lin[end_new+k] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10))
3224 k++;
3225 /*
3226 | check for commonality between rest of lines (are the old
3227 | and new lines the same, except for a chunk in the middle?)
3228 | if the rest of the lines are common, do not insert text
3229 */
3230 old_off = end_new;
3231 while ((old_lin[old_off] != '\0') && (new_lin[old_off] != '\0') && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3232 old_off++;
3233 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3234 same = TRUE;
3235 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0))))
3236 {
3237 Position(window, line, offset);
3238 insert = FALSE;
3239 if (String_table[ic__] == NULL)
3240 {
3241 String_Out(String_table[im__], NULL, 0);
3242 insert = TRUE;
3243 }
3244 for (k = offset; k < end_new; k++)
3245 {
3246 if (!insert)
3247 String_Out(String_table[ic__], NULL, 0);
3248 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3249 }
3250 if (insert)
3251 String_Out(String_table[ei__], NULL, 0);
3252 while ((old_lin[offset] != '\0') && (offset < COLS))
3253 offset++;
3254 pointer_old->last_char = offset;
3255 changed = TRUE;
3256 }
3257 }
3258 return(changed);
3259 }
3260
3261 void
doupdate()3262 doupdate()
3263 {
3264 WINDOW *window;
3265 int similar;
3266 int diff;
3267 int begin_old, begin_new;
3268 int end_old, end_new;
3269 int count1, j;
3270 int from_top, tmp_ft, offset;
3271 int changed;
3272 int first_time;
3273 int first_same;
3274 int last_same;
3275 int list[10];
3276 int bottom;
3277
3278 struct _line *curr;
3279 struct _line *virt;
3280 struct _line *old;
3281
3282 struct _line *new;
3283
3284 struct _line *old1, *new1;
3285
3286 char *cur_lin;
3287 char *vrt_lin;
3288 char *cur_att;
3289 char *vrt_att;
3290 char *att1, *att2;
3291 char *c1, *c2;
3292
3293 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3294
3295 window = virtual_scr;
3296
3297 if ((nc_attributes & A_NC_BIG5) != 0)
3298 NC_chinese = TRUE;
3299
3300 if (Repaint_screen)
3301 {
3302 if (String_table[cl__])
3303 String_Out(String_table[cl__], NULL, 0);
3304 else
3305 {
3306 from_top = 0;
3307 while (from_top < LINES)
3308 {
3309 Position(curscr, from_top, 0);
3310 if (String_table[ce__] != NULL)
3311 String_Out(String_table[ce__], NULL, 0);
3312 else
3313 {
3314 for (j = 0; j < window->Num_cols; j++)
3315 putchar(' ');
3316 }
3317 from_top++;
3318 }
3319 }
3320 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3321 {
3322 Position(curscr, from_top, 0);
3323 for (j = 0; (curr->row[j] != '\0') && (j < curscr->Num_cols); j++)
3324 {
3325 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3326 }
3327 if (STAND)
3328 {
3329 STAND = FALSE;
3330 Position(curscr, from_top, j);
3331 attribute_off();
3332 }
3333 }
3334 Repaint_screen = FALSE;
3335 }
3336
3337 similar = 0;
3338 diff = FALSE;
3339 top_of_win = curscr->first_line;
3340
3341 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3342 from_top < window->Num_lines; from_top++)
3343 {
3344 virtual_lines[from_top] = TRUE;
3345 if ((similar = Comp_line(curr, virt)) > 0)
3346 {
3347 virtual_lines[from_top] = FALSE;
3348 diff = TRUE;
3349 }
3350 curr = curr->next_screen;
3351 virt = virt->next_screen;
3352 }
3353
3354 from_top = 0;
3355 virt = window->first_line;
3356 curr = top_of_win;
3357 similar = 0;
3358 /*
3359 | if the window has lines that are different, check for scrolling
3360 */
3361 if (diff)
3362 {
3363 last_same = -1;
3364 changed = FALSE;
3365 for (first_same = window->Num_lines;
3366 (first_same > from_top) && (virtual_lines[first_same - 1]);
3367 first_same--)
3368 ;
3369 for (last_same = 0;
3370 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3371 last_same++)
3372 ;
3373 while ((from_top < first_same) && nc_scrolling_ability)
3374 /* check entire lines for diffs */
3375 {
3376
3377 if (from_top >= last_same)
3378 {
3379 for (last_same = from_top;
3380 (last_same < window->Num_lines) &&
3381 (virtual_lines[last_same] == FALSE);
3382 last_same++)
3383 ;
3384 }
3385 if (!virtual_lines[from_top])
3386 {
3387 diff = TRUE;
3388 /*
3389 | check for lines deleted (scroll up)
3390 */
3391 for (tmp_ft = from_top+1, old = curr->next_screen;
3392 ((window->scroll_up) && (diff) &&
3393 (tmp_ft < last_same) &&
3394 (!virtual_lines[tmp_ft]));
3395 tmp_ft++)
3396 {
3397 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3398 {
3399 /*
3400 | Find the bottom of the
3401 | area that should be
3402 | scrolled.
3403 */
3404 for (bottom = tmp_ft, old1 = old,
3405 new1 = virt, count1 = 0;
3406 (bottom < window->Num_lines) &&
3407 (Comp_line(old1, new1) <= 0);
3408 bottom++, old1 = old1->next_screen,
3409 new1 = new1->next_screen,
3410 count1++)
3411 ;
3412 if (count1 > 3)
3413 {
3414 if (String_table[cs__]) /* scrolling region */
3415 {
3416 list[1] = from_top;
3417 list[0] = min((bottom - 1), (window->Num_lines - 1));
3418 String_Out(String_table[cs__], list, 2);
3419 Curr_y = Curr_x = -1;
3420 }
3421
3422 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3423 {
3424 old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
3425 diff = FALSE;
3426 }
3427
3428 if (String_table[cs__]) /* scrolling region */
3429 {
3430 list[1] = 0;
3431 list[0] = LINES - 1;
3432 String_Out(String_table[cs__], list, 2);
3433 Curr_y = Curr_x = -1;
3434 }
3435
3436 top_of_win = curscr->first_line;
3437 curr = top_of_win;
3438 for (offset = 0; offset < from_top; offset++)
3439 curr = curr->next_screen;
3440 for (offset = from_top, old=curr, new=virt;
3441 offset < window->Num_lines;
3442 old=old->next_screen, new=new->next_screen,
3443 offset++)
3444 {
3445 similar = Comp_line(old, new);
3446 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3447 }
3448 }
3449 }
3450 else
3451 old = old->next_screen;
3452 }
3453 /*
3454 | check for lines inserted (scroll down)
3455 */
3456 for (tmp_ft = from_top-1, old = curr->prev_screen;
3457 ((window->scroll_down) && (tmp_ft >= 0) &&
3458 (diff) &&
3459 (!virtual_lines[tmp_ft]));
3460 tmp_ft--)
3461 {
3462 if (Comp_line(old, virt) == -1)
3463 {
3464 /*
3465 | Find the bottom of the
3466 | area that should be
3467 | scrolled.
3468 */
3469 for (bottom = from_top, old1 = old,
3470 new1 = virt, count1 = 0;
3471 (bottom < window->Num_lines) &&
3472 (Comp_line(old1, new1) <= 0);
3473 bottom++, old1 = old1->next_screen,
3474 new1 = new1->next_screen,
3475 count1++)
3476 ;
3477 if (count1 > 3)
3478 {
3479 if (String_table[cs__]) /* scrolling region */
3480 {
3481 list[1] = tmp_ft;
3482 list[0] = min((bottom - 1), (window->Num_lines - 1));
3483 String_Out(String_table[cs__], list, 2);
3484 Curr_y = Curr_x = -1;
3485 }
3486
3487 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3488 {
3489 old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
3490 diff = FALSE;
3491 }
3492
3493 if (String_table[cs__]) /* scrolling region */
3494 {
3495 list[1] = 0;
3496 list[0] = LINES - 1;
3497 String_Out(String_table[cs__], list, 2);
3498 Curr_y = Curr_x = -1;
3499 }
3500
3501 top_of_win = curscr->first_line;
3502 curr = top_of_win;
3503 for (offset = 0; offset < from_top; offset++)
3504 curr = curr->next_screen;
3505 for (offset = from_top, old=curr, new=virt;
3506 offset < window->Num_lines;
3507 old=old->next_screen, new=new->next_screen,
3508 offset++)
3509 {
3510 similar = Comp_line(old, new);
3511 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3512 }
3513 }
3514 }
3515 else
3516 old = old->prev_screen;
3517 }
3518 }
3519 from_top++;
3520 curr = curr->next_screen;
3521 virt = virt->next_screen;
3522 }
3523 }
3524
3525
3526 /*
3527 | Scrolling done, now need to insert, delete, or modify text
3528 | within lines.
3529 */
3530
3531 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3532 curr = curr->next_screen;
3533 top_of_win = curr;
3534 for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++, curr = curr->next_screen, virt = virt->next_screen)
3535 {
3536
3537 /*
3538 | If either 'insert mode' or 'insert char' are
3539 | available, enter the following 'if' statement,
3540 | else, need to simply rewrite the contents of the line
3541 | at the point where the contents of the line change.
3542 */
3543
3544 if (((String_table[ic__]) || (String_table[im__])) &&
3545 (String_table[dc__]) && (curr->row[0] != '\0') &&
3546 (!NC_chinese))
3547 {
3548 j = 0;
3549 first_time = TRUE;
3550 vrt_lin = virt->row;
3551 vrt_att = virt->attributes;
3552 cur_lin = curr->row;
3553 cur_att = curr->attributes;
3554 while ((vrt_lin[j] != '\0') && (j < window->Num_cols))
3555 {
3556 if ((STAND) && (Booleans[xs__]))
3557 {
3558 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0') && (vrt_att[j]))
3559 j++;
3560 if ((STAND) && (!vrt_att[j]))
3561 {
3562 STAND = FALSE;
3563 Position(window, from_top, j);
3564 attribute_off();
3565 attribute_off();
3566 }
3567 }
3568 else
3569 {
3570 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0'))
3571 j++;
3572 }
3573 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3574 {
3575 Position(window, from_top, j);
3576 /* CLEAR_TO_EOL(window, from_top, j);*/
3577 attribute_off();
3578 attribute_off();
3579 }
3580 if (vrt_lin[j] != '\0')
3581 {
3582 begin_new = j;
3583 begin_old = j;
3584 end_old = j;
3585 end_new = j;
3586 if ((first_time) && (virt->changed))
3587 {
3588 if (curr->last_char <= virt->last_char)
3589 changed = check_insert(window, from_top, j, virt, curr);
3590 }
3591 changed = check_delete(window, from_top, j, virt, curr);
3592 first_time = FALSE;
3593 virt->changed = FALSE;
3594 if (!changed)
3595 changed = check_insert(window, from_top, j, virt, curr);
3596 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3597 {
3598 if ((vrt_lin[j] == ' ') && (cur_lin[j] == '\0') && (vrt_att[j] == cur_att[j]))
3599 cur_lin[j] = ' ';
3600 else
3601 {
3602 Position(window, from_top, j);
3603 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3604 }
3605 }
3606 if ((vrt_lin[j] != '\0'))
3607 j++;
3608 }
3609 if ((STAND) && (!vrt_att[j]))
3610 {
3611 STAND = FALSE;
3612 Position(window, from_top, j);
3613 attribute_off();
3614 }
3615 }
3616 if ((vrt_lin[j] == '\0') && (cur_lin[j] != '\0'))
3617 {
3618 Position(window, from_top, j);
3619 CLEAR_TO_EOL(window, from_top, j);
3620 }
3621 }
3622 else /*if ((similar != -1) && (similar != 0))*/
3623 {
3624 j = 0;
3625 c1 = curr->row;
3626 att1 = curr->attributes;
3627 c2 = virt->row;
3628 att2 = virt->attributes;
3629 while ((j < window->Num_cols) && (c2[j] != '\0'))
3630 {
3631 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != '\0'))
3632 j++;
3633
3634 /*
3635 | if previous character is an eight bit
3636 | char, start redraw from that character
3637 */
3638
3639 if ((NC_chinese) && (highbitset(c1[j - 1])))
3640 j--;
3641 begin_old = j;
3642 begin_new = j;
3643 if ((j < window->Num_cols) && (c2[j] != '\0'))
3644 {
3645 Position(window, from_top, begin_old);
3646 CLEAR_TO_EOL(window, from_top, j);
3647 Position(window, from_top, begin_old);
3648 for (j = begin_old; (c2[j] != '\0') && (j < window->Num_cols); j++)
3649 Char_out(c2[j], att2[j], c1, att1, j);
3650 }
3651 }
3652 if ((c2[j] == '\0') && (c1[j] != '\0'))
3653 {
3654 Position(window, from_top, j);
3655 CLEAR_TO_EOL(window, from_top, j);
3656 }
3657 }
3658 if (STAND)
3659 {
3660 STAND = FALSE;
3661 Position(window, from_top, j);
3662 attribute_off();
3663 }
3664 virt->number = from_top;
3665 }
3666 Position(window, window->LY, window->LX);
3667 }
3668
3669 void
Position(window,row,col)3670 Position(window, row, col) /* position the cursor for output on the screen */
3671 WINDOW *window;
3672 int row;
3673 int col;
3674 {
3675 int list[10];
3676 int place;
3677
3678 int pos_row;
3679 int pos_column;
3680
3681 pos_row = row + window->SR;
3682 pos_column = col + window->SC;
3683 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3684 {
3685 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3686 {
3687 place = 0;
3688 list[place++] = pos_column;
3689 list[place++] = pos_row;
3690 String_Out(String_table[cm__], list, place);
3691 if ((STAND) && (!Booleans[ms__]))
3692 attribute_on();
3693 }
3694 Curr_x = pos_column;
3695 Curr_y = pos_row;
3696 }
3697 }
3698
3699 void
Char_del(line,attrib,offset,maxlen)3700 Char_del(line, attrib, offset, maxlen) /* delete chars from line */
3701 char *line;
3702 char *attrib;
3703 int offset;
3704 int maxlen;
3705 {
3706 int one, two;
3707
3708 for (one = offset, two = offset+1; (line[one] != '\0') && (one < maxlen); one++, two++)
3709 {
3710 line[one] = line[two];
3711 attrib[one] = attrib[two];
3712 }
3713 String_Out(String_table[dc__], NULL, 0);
3714 }
3715
3716 void
Char_ins(line,attrib,newc,newatt,offset,maxlen)3717 Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
3718 char *line;
3719 char *attrib;
3720 char newc;
3721 char newatt;
3722 int offset;
3723 int maxlen;
3724 {
3725 int one, two;
3726
3727 one = 0;
3728 while ((line[one] != '\0') && (one < (maxlen - 2)))
3729 one++;
3730 for (two = one + 1; (two > offset); one--, two--)
3731 {
3732 line[two] = line[one];
3733 attrib[two] = attrib[one];
3734 }
3735 line[offset] = newc;
3736 attrib[offset] = newatt;
3737 Char_out(newc, newatt, line, attrib, offset);
3738 }
3739
3740 void
attribute_on()3741 attribute_on()
3742 {
3743 if (String_table[sa__])
3744 {
3745 attributes_set[0] = 1;
3746 String_Out(String_table[sa__], attributes_set, 1);
3747 }
3748 else if (String_table[so__])
3749 String_Out(String_table[so__], NULL, 0);
3750 }
3751
3752 void
attribute_off()3753 attribute_off()
3754 {
3755 if (String_table[me__])
3756 String_Out(String_table[me__], NULL, 0);
3757 else if (String_table[sa__])
3758 {
3759 attributes_set[0] = 0;
3760 String_Out(String_table[sa__], attributes_set, 1);
3761 }
3762 else if (String_table[se__])
3763 String_Out(String_table[se__], NULL, 0);
3764 }
3765
3766 void
Char_out(newc,newatt,line,attrib,offset)3767 Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
3768 char newc;
3769 char newatt;
3770 char *line;
3771 char *attrib;
3772 int offset;
3773 {
3774
3775
3776 if ((newatt) && (!STAND))
3777 {
3778 STAND = TRUE;
3779 attribute_on();
3780 }
3781 else if ((STAND) && (!newatt))
3782 {
3783 STAND = FALSE;
3784 attribute_off();
3785 }
3786
3787 if ((newatt) && (STAND) && (Booleans[xs__]))
3788 {
3789 attribute_on();
3790 }
3791
3792 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3793 {
3794 putchar(newc);
3795 line[offset] = newc;
3796 attrib[offset] = newatt;
3797 }
3798 Curr_x++;
3799 }
3800
3801 /*
3802 |
3803 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3804 | hacks that notify new_curse to handle characters that have the high
3805 | bit set as the first of two bytes of a multi-byte string.
3806 |
3807 */
3808
3809 void
nc_setattrib(flag)3810 nc_setattrib(flag)
3811 int flag;
3812 {
3813 nc_attributes |= flag;
3814 }
3815
3816 void
nc_clearattrib(flag)3817 nc_clearattrib(flag)
3818 int flag;
3819 {
3820 nc_attributes &= ~flag;
3821 }
3822
3823