sio(4) - Fix double make_dev if used as console
[dragonfly.git] / usr.bin / ee / new_curse.c
blob651ef1c947d43f90f6397d04b8b6b894b778ed9d
1 /*
2 | new_curse.c
4 | A subset of curses developed for use with ae.
6 | written by Hugh Mahon
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.
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.
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.
35 | This notice must be included with this software and any derivatives.
37 | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
38 | All are rights reserved.
40 | $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $
41 | $DragonFly: src/usr.bin/ee/new_curse.c,v 1.4 2005/10/30 23:00:57 swildner Exp $
45 char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
46 "All rights are reserved."};
48 char * new_curse_name= "@(#) new_curse.c $FreeBSD: src/usr.bin/ee/new_curse.c,v 1.4.2.1 2001/06/10 11:06:06 sobomax Exp $";
50 #include "new_curse.h"
51 #include <signal.h>
52 #include <fcntl.h>
54 #ifdef SYS5
55 #include <string.h>
56 #else
57 #include <strings.h>
58 #endif
60 #ifdef BSD_SELECT
61 #include <sys/types.h>
62 #include <sys/time.h>
64 #ifdef SLCT_HDR
65 #include <sys/select.h> /* on AIX */
66 #endif /* SLCT_HDR */
68 #endif /* BSD_SELECT */
70 #ifdef HAS_STDLIB
71 #include <stdlib.h>
72 #endif
74 #if defined(__STDC__)
75 #include <stdarg.h>
76 #else
77 #include <varargs.h>
78 #endif
80 #ifdef HAS_UNISTD
81 #include <unistd.h>
82 #endif
84 #ifdef HAS_SYS_IOCTL
85 #include <sys/ioctl.h>
86 #endif
89 WINDOW *curscr;
90 static WINDOW *virtual_scr;
91 WINDOW *stdscr;
92 WINDOW *last_window_refreshed;
94 #ifdef TIOCGWINSZ
95 struct winsize ws;
96 #endif
98 #define min(a, b) (a < b ? a : b)
99 #define highbitset(a) ((a) & 0x80)
101 #ifndef CAP
102 #define String_Out(table, stack, place) Info_Out(table, stack, place)
103 #else
104 #define String_Out(table, stack, place) Cap_Out(table, stack, place)
105 #endif
107 #define bw__ 0 /* booleans */
108 #define am__ 1
109 #define xb__ 2
110 #define xs__ 3 /* hp glitch (standout not erased by overwrite) */
111 #define xn__ 4
112 #define eo__ 5
113 #define gn__ 6 /* generic type terminal */
114 #define hc__ 7 /* hardcopy terminal */
115 #define km__ 8
116 #define hs__ 9
117 #define in__ 10
118 #define da__ 11
119 #define db__ 12
120 #define mi__ 13 /* safe to move during insert mode */
121 #define ms__ 14 /* safe to move during standout mode */
122 #define os__ 15
123 #define es__ 16
124 #define xt__ 17
125 #define hz__ 18 /* hazeltine glitch */
126 #define ul__ 19
127 #define xo__ 20
128 #define chts__ 21
129 #define nxon__ 22
130 #define nrrmc__ 23
131 #define npc__ 24
132 #define mc5i__ 25
134 #define co__ 0 /* number of columns */ /* numbers */
135 #define it__ 1 /* spaces per tab */
136 #define li__ 2 /* number of lines */
137 #define lm__ 3
138 #define sg__ 4 /* magic cookie glitch */
139 #define pb__ 5
140 #define vt__ 6
141 #define ws__ 7
143 #define cols__ 0
144 #define lines__ 2
145 #define xmc__ 4
146 #define vt__ 6
147 #define wsl__ 7
148 #define nlab__ 8
149 #define lh__ 9
150 #define lw__ 10
152 #define bt__ 0 /* back tab */ /* strings */
153 #define bl__ 1 /* bell */
154 #define cr__ 2 /* carriage return */
155 #define cs__ 3 /* change scroll region */
156 #define ct__ 4 /* clear all tab stops */
157 #define cl__ 5 /* clear screen and home cursor */
158 #define ce__ 6 /* clear to end of line */
159 #define cd__ 7 /* clear to end of display */
160 #define ch__ 8 /* set cursor column */
161 #define CC__ 9 /* term, settable cmd char in */
162 #define cm__ 10 /* screen rel cursor motion, row, column */
163 #define do__ 11 /* down one line */
164 #define ho__ 12 /* home cursor */
165 #define vi__ 13 /* make cursor invisible */
166 #define le__ 14 /* move cursor left one space */
167 #define CM__ 15 /* memory rel cursor addressing */
168 #define ve__ 16 /* make cursor appear normal */
169 #define nd__ 17 /* non-destructive space (cursor right) */
170 #define ll__ 18 /* last line, first col */
171 #define up__ 19 /* cursor up */
172 #define vs__ 20
173 #define dc__ 21 /* delete character */
174 #define dl__ 22 /* delete line */
175 #define ds__ 23
176 #define hd__ 24
177 #define as__ 25
178 #define mb__ 26
179 #define md__ 27 /* turn on bold */
180 #define ti__ 28
181 #define dm__ 29 /* turn on delete mode */
182 #define mh__ 30 /* half bright mode */
183 #define im__ 31 /* insert mode */
184 #define mk__ 32
185 #define mp__ 33
186 #define mr__ 34
187 #define so__ 35 /* enter standout mode */
188 #define us__ 36
189 #define ec__ 37
190 #define ae__ 38
191 #define me__ 39
192 #define te__ 40
193 #define ed__ 41
194 #define ei__ 42 /* exit insert mode */
195 #define se__ 43 /* exit standout mode */
196 #define ue__ 44
197 #define vb__ 45
198 #define ff__ 46
199 #define fs__ 47
200 #define i1__ 48
201 #define i2__ 49
202 #define i3__ 50
203 #define if__ 51
204 #define ic__ 52
205 #define al__ 53
206 #define ip__ 54
207 #define kb__ 55 /* backspace key */
208 #define ka__ 56
209 #define kC__ 57
210 #define kt__ 58
211 #define kD__ 59
212 #define kL__ 60
213 #define kd__ 61
214 #define kM__ 62
215 #define kE__ 63
216 #define kS__ 64
217 #define k0__ 65
218 #define k1__ 66
219 #define kf10__ 67
220 #define k2__ 68
221 #define k3__ 69
222 #define k4__ 70
223 #define k5__ 71
224 #define k6__ 72
225 #define k7__ 73
226 #define k8__ 74
227 #define k9__ 75
228 #define kh__ 76
229 #define kI__ 77
230 #define kA__ 78
231 #define kl__ 79
232 #define kH__ 80
233 #define kN__ 81
234 #define kP__ 82
235 #define kr__ 83
236 #define kF__ 84
237 #define kR__ 85
238 #define kT__ 86
239 #define ku__ 87 /* key up */
240 #define ke__ 88
241 #define ks__ 89
242 #define l0__ 90
243 #define l1__ 91
244 #define la__ 92
245 #define l2__ 93
246 #define l3__ 94
247 #define l4__ 95
248 #define l5__ 96
249 #define l6__ 97
250 #define l7__ 98
251 #define l8__ 99
252 #define l9__ 100
253 #define mo__ 101
254 #define mm__ 102
255 #define nw__ 103
256 #define pc__ 104
257 #define DC__ 105
258 #define DL__ 106
259 #define DO__ 107
260 #define IC__ 118
261 #define SF__ 109
262 #define AL__ 110
263 #define LE__ 111
264 #define RI__ 112
265 #define SR__ 113
266 #define UP__ 114
267 #define pk__ 115
268 #define pl__ 116
269 #define px__ 117
270 #define ps__ 118
271 #define pf__ 119
272 #define po__ 120
273 #define rp__ 121
274 #define r1__ 122
275 #define r2__ 123
276 #define r3__ 124
277 #define rf__ 125
278 #define rc__ 126
279 #define cv__ 127
280 #define sc__ 128
281 #define sf__ 129
282 #define sr__ 130
283 #define sa__ 131 /* sgr */
284 #define st__ 132
285 #define wi__ 133
286 #define ta__ 134
287 #define ts__ 135
288 #define uc__ 136
289 #define hu__ 137
290 #define iP__ 138
291 #define K1__ 139
292 #define K2__ 140
293 #define K3__ 141
294 #define K4__ 142
295 #define K5__ 143
296 #define pO__ 144
297 #define ml__ 145
298 #define mu__ 146
299 #define rmp__ 145
300 #define acsc__ 146
301 #define pln__ 147
302 #define kcbt__ 148
303 #define smxon__ 149
304 #define rmxon__ 150
305 #define smam__ 151
306 #define rmam__ 152
307 #define xonc__ 153
308 #define xoffc__ 154
309 #define enacs__ 155
310 #define smln__ 156
311 #define rmln__ 157
312 #define kbeg__ 158
313 #define kcan__ 159
314 #define kclo__ 160
315 #define kcmd__ 161
316 #define kcpy__ 162
317 #define kcrt__ 163
318 #define kend__ 164
319 #define kent__ 165
320 #define kext__ 166
321 #define kfnd__ 167
322 #define khlp__ 168
323 #define kmrk__ 169
324 #define kmsg__ 170
325 #define kmov__ 171
326 #define knxt__ 172
327 #define kopn__ 173
328 #define kopt__ 174
329 #define kprv__ 175
330 #define kprt__ 176
331 #define krdo__ 177
332 #define kref__ 178
333 #define krfr__ 179
334 #define krpl__ 180
335 #define krst__ 181
336 #define kres__ 182
337 #define ksav__ 183
338 #define kspd__ 184
339 #define kund__ 185
340 #define kBEG__ 186
341 #define kCAN__ 187
342 #define kCMD__ 188
343 #define kCPY__ 189
344 #define kCRT__ 190
345 #define kDC__ 191
346 #define kDL__ 192
347 #define kslt__ 193
348 #define kEND__ 194
349 #define kEOL__ 195
350 #define kEXT__ 196
351 #define kFND__ 197
352 #define kHLP__ 198
353 #define kHOM__ 199
354 #define kIC__ 200
355 #define kLFT__ 201
356 #define kMSG__ 202
357 #define kMOV__ 203
358 #define kNXT__ 204
359 #define kOPT__ 205
360 #define kPRV__ 206
361 #define kPRT__ 207
362 #define kRDO__ 208
363 #define kRPL__ 209
364 #define kRIT__ 210
365 #define kRES__ 211
366 #define kSAV__ 212
367 #define kSPD__ 213
368 #define kUND__ 214
369 #define rfi__ 215
370 #define kf11__ 216
371 #define kf12__ 217
372 #define kf13__ 218
373 #define kf14__ 219
374 #define kf15__ 220
375 #define kf16__ 221
376 #define kf17__ 222
377 #define kf18__ 223
378 #define kf19__ 224
379 #define kf20__ 225
380 #define kf21__ 226
381 #define kf22__ 227
382 #define kf23__ 228
383 #define kf24__ 229
384 #define kf25__ 230
385 #define kf26__ 231
386 #define kf27__ 232
387 #define kf28__ 233
388 #define kf29__ 234
389 #define kf30__ 235
390 #define kf31__ 236
391 #define kf32__ 237
392 #define kf33__ 238
393 #define kf34__ 239
394 #define kf35__ 240
395 #define kf36__ 241
396 #define kf37__ 242
397 #define kf38__ 243
398 #define kf39__ 244
399 #define kf40__ 245
400 #define kf41__ 246
401 #define kf42__ 247
402 #define kf43__ 248
403 #define kf44__ 249
404 #define kf45__ 250
405 #define kf46__ 251
406 #define kf47__ 252
407 #define kf48__ 253
408 #define kf49__ 254
409 #define kf50__ 255
410 #define kf51__ 256
411 #define kf52__ 257
412 #define kf53__ 258
413 #define kf54__ 259
414 #define kf55__ 260
415 #define kf56__ 261
416 #define kf57__ 262
417 #define kf58__ 263
418 #define kf59__ 264
419 #define kf60__ 265
420 #define kf61__ 266
421 #define kf62__ 267
422 #define kf63__ 268
423 #define el1__ 269
424 #define mgc__ 270
425 #define smgl__ 271
426 #define smgr__ 272
428 #ifdef CAP
429 char *Boolean_names[] = {
430 "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
431 "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
434 char *Number_names[] = {
435 "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
438 char *String_names[] = {
439 "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
440 "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
441 "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
442 "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
443 "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
444 "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
445 "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
446 "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
447 "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
448 "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
449 "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
450 "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
451 "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
452 "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
453 "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
454 "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
455 "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
456 "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
457 "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
458 "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
459 "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
460 "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
461 "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
462 "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
463 "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
465 #endif
467 char *new_curse = "October 1987";
469 char in_buff[100]; /* buffer for ungetch */
470 int bufp; /* next free position in in_buff */
472 char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
473 int CFOUND = FALSE;
474 int Data_Line_len = 0;
475 int Max_Key_len; /* max length of a sequence sent by a key */
476 char *Data_Line = NULL;
477 char *TERM_PATH = NULL;
478 char *TERM_data_ptr = NULL;
479 char *Term_File_name = NULL; /* name of file containing terminal description */
480 FILE *TFP; /* file pointer to file with terminal des. */
481 int Fildes; /* file descriptor for terminfo file */
482 int STAND = FALSE; /* is standout mode activated? */
483 int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
484 int Time_Out; /* set when time elapsed while trying to read function key */
485 int Curr_x; /* current x position on screen */
486 int Curr_y; /* current y position on the screen */
487 int LINES;
488 int COLS;
489 int Move_It; /* flag to move cursor if magic cookie glitch */
490 int initialized = FALSE; /* tells whether new_curse is initialized */
491 float speed;
492 float chars_per_millisecond;
493 int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
494 int Intr; /* storeage for interrupt character */
495 int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
496 int Noblock; /* for BSD systems */
497 int Num_bits; /* number of bits per character */
498 int Flip_Bytes; /* some systems have byte order reversed */
499 int interrupt_flag = FALSE; /* set true if SIGWINCH received */
501 #ifndef CAP
502 char *Strings;
503 #endif
505 struct KEYS {
506 int length; /* length of string sent by key */
507 char *string; /* string sent by key */
508 int value; /* CURSES value of key (9-bit) */
511 struct KEY_STACK {
512 struct KEYS *element;
513 struct KEY_STACK *next;
516 struct KEY_STACK *KEY_TOS = NULL;
517 struct KEY_STACK *KEY_POINT;
521 | Not all systems have good terminal information, so we will define
522 | keyboard information here for the most widely used terminal type,
523 | the VT100.
527 struct KEYS vt100[] =
529 { 3, "\033[A", 0403 }, /* key up */
530 { 3, "\033[C", 0405 }, /* key right */
531 { 3, "\033[D", 0404 }, /* key left */
533 { 4, "\033[6~", 0522 }, /* key next page */
534 { 4, "\033[5~", 0523 }, /* key prev page */
535 { 3, "\033[[", 0550 }, /* key end */
536 { 3, "\033[@", 0406 }, /* key home */
537 { 4, "\033[2~", 0513 }, /* key insert char */
539 { 3, "\033[y", 0410 }, /* key F0 */
540 { 3, "\033[P", 0411 }, /* key F1 */
541 { 3, "\033[Q", 0412 }, /* key F2 */
542 { 3, "\033[R", 0413 }, /* key F3 */
543 { 3, "\033[S", 0414 }, /* key F4 */
544 { 3, "\033[t", 0415 }, /* key F5 */
545 { 3, "\033[u", 0416 }, /* key F6 */
546 { 3, "\033[v", 0417 }, /* key F7 */
547 { 3, "\033[l", 0420 }, /* key F8 */
548 { 3, "\033[w", 0421 }, /* key F9 */
549 { 3, "\033[x", 0422 }, /* key F10 */
551 { 5, "\033[10~", 0410 }, /* key F0 */
552 { 5, "\033[11~", 0411 }, /* key F1 */
553 { 5, "\033[12~", 0412 }, /* key F2 */
554 { 5, "\033[13~", 0413 }, /* key F3 */
555 { 5, "\033[14~", 0414 }, /* key F4 */
556 { 5, "\033[15~", 0415 }, /* key F5 */
557 { 5, "\033[17~", 0416 }, /* key F6 */
558 { 5, "\033[18~", 0417 }, /* key F7 */
559 { 5, "\033[19~", 0420 }, /* key F8 */
560 { 5, "\033[20~", 0421 }, /* key F9 */
561 { 5, "\033[21~", 0422 }, /* key F10 */
562 { 5, "\033[23~", 0423 }, /* key F11 */
563 { 5, "\033[24~", 0424 }, /* key F12 */
564 { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
565 { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
566 { 3, "\033[r", 0536 }, /* kb2 center of keypad */
567 { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
568 { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
571 | The following are the same keys as above, but with
572 | a different character following the escape char.
575 { 3, "\033OA", 0403 }, /* key up */
576 { 3, "\033OC", 0405 }, /* key right */
577 { 3, "\033OD", 0404 }, /* key left */
578 { 3, "\033OB", 0402 }, /* key down */
579 { 4, "\033O6~", 0522 }, /* key next page */
580 { 4, "\033O5~", 0523 }, /* key prev page */
581 { 3, "\033O[", 0550 }, /* key end */
582 { 3, "\033O@", 0406 }, /* key home */
583 { 4, "\033O2~", 0513 }, /* key insert char */
585 { 3, "\033Oy", 0410 }, /* key F0 */
586 { 3, "\033OP", 0411 }, /* key F1 */
587 { 3, "\033OQ", 0412 }, /* key F2 */
588 { 3, "\033OR", 0413 }, /* key F3 */
589 { 3, "\033OS", 0414 }, /* key F4 */
590 { 3, "\033Ot", 0415 }, /* key F5 */
591 { 3, "\033Ou", 0416 }, /* key F6 */
592 { 3, "\033Ov", 0417 }, /* key F7 */
593 { 3, "\033Ol", 0420 }, /* key F8 */
594 { 3, "\033Ow", 0421 }, /* key F9 */
595 { 3, "\033Ox", 0422 }, /* key F10 */
597 { 5, "\033O10~", 0410 }, /* key F0 */
598 { 5, "\033O11~", 0411 }, /* key F1 */
599 { 5, "\033O12~", 0412 }, /* key F2 */
600 { 5, "\033O13~", 0413 }, /* key F3 */
601 { 5, "\033O14~", 0414 }, /* key F4 */
602 { 5, "\033O15~", 0415 }, /* key F5 */
603 { 5, "\033O17~", 0416 }, /* key F6 */
604 { 5, "\033O18~", 0417 }, /* key F7 */
605 { 5, "\033O19~", 0420 }, /* key F8 */
606 { 5, "\033O20~", 0421 }, /* key F9 */
607 { 5, "\033O21~", 0422 }, /* key F10 */
608 { 5, "\033O23~", 0423 }, /* key F11 */
609 { 5, "\033O24~", 0424 }, /* key F12 */
610 { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
611 { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
612 { 3, "\033Or", 0536 }, /* kb2 center of keypad */
613 { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
614 { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
616 { 0, "", 0 } /* end */
619 struct Parameters {
620 int value;
621 struct Parameters *next;
624 int Key_vals[] = {
625 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
626 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
627 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
628 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
629 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
630 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
631 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
632 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
633 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
634 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
635 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
636 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
637 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
640 int attributes_set[9];
642 static int nc_attributes = 0; /* global attributes for new_curse to observe */
644 #ifdef SYS5
645 struct termio Terminal;
646 struct termio Saved_tty;
647 #else
648 struct sgttyb Terminal;
649 struct sgttyb Saved_tty;
650 #endif
652 char *tc_;
654 int Booleans[128];
655 int Numbers[128];
656 char *String_table[1024];
658 int *virtual_lines;
660 static char nc_scrolling_ability = FALSE;
662 #ifdef CAP
664 #if __STDC__ || defined(__cplusplus)
665 #define P_(s) s
666 #else
667 #define P_(s) ()
668 #endif /* __STDC__ */
670 int tc_Get_int P_((int));
671 void CAP_PARSE P_((void));
672 void Find_term P_((void));
674 #undef P_
676 #endif /* CAP */
679 #ifndef __STDC__
680 #ifndef HAS_STDLIB
681 extern char *fgets();
682 extern char *malloc();
683 extern char *getenv();
684 FILE *fopen(); /* declaration for open function */
685 #endif /* HAS_STDLIB */
686 #endif /* __STDC__ */
688 #ifdef SIGWINCH
691 | Copy the contents of one window to another.
694 void
695 copy_window(WINDOW *origin, WINDOW *destination)
697 int row, column;
698 struct _line *orig, *dest;
700 orig = origin->first_line;
701 dest = destination->first_line;
703 for (row = 0;
704 row < (min(origin->Num_lines, destination->Num_lines));
705 row++)
707 for (column = 0;
708 column < (min(origin->Num_cols, destination->Num_cols));
709 column++)
711 dest->row[column] = orig->row[column];
712 dest->attributes[column] = orig->attributes[column];
714 dest->changed = orig->changed;
715 dest->scroll = orig->scroll;
716 dest->last_char = min(orig->last_char, destination->Num_cols);
717 orig = orig->next_screen;
718 dest = dest->next_screen;
720 destination->LX = min((destination->Num_cols - 1), origin->LX);
721 destination->LY = min((destination->Num_lines - 1), origin->LY);
722 destination->Attrib = origin->Attrib;
723 destination->scroll_up = origin->scroll_up;
724 destination->scroll_down = origin->scroll_down;
725 destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
728 void
729 reinitscr(int foo)
731 WINDOW *local_virt;
732 WINDOW *local_std;
733 WINDOW *local_cur;
735 signal(SIGWINCH, reinitscr);
736 #ifdef TIOCGWINSZ
737 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
739 if (ws.ws_row == LINES && ws.ws_col == COLS)
740 return;
741 if (ws.ws_row > 0)
742 LINES = ws.ws_row;
743 if (ws.ws_col > 0)
744 COLS = ws.ws_col;
746 #endif /* TIOCGWINSZ */
747 local_virt = newwin(LINES, COLS, 0, 0);
748 local_std = newwin(LINES, COLS, 0, 0);
749 local_cur = newwin(LINES, COLS, 0, 0);
750 copy_window(virtual_scr, local_virt);
751 copy_window(stdscr, local_std);
752 copy_window(curscr, local_cur);
753 delwin(virtual_scr);
754 delwin(stdscr);
755 delwin(curscr);
756 virtual_scr = local_virt;
757 stdscr = local_std;
758 curscr = local_cur;
759 free(virtual_lines);
760 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
761 interrupt_flag = TRUE;
763 #endif /* SIGWINCH */
765 void
766 initscr(void) /* initialize terminal for operations */
768 int value;
769 char *lines_string;
770 char *columns_string;
771 #ifdef CAP
772 char *pointer;
773 #endif /* CAP */
775 #ifdef DIAG
776 printf("starting initscr \n");fflush(stdout);
777 #endif
778 if (initialized)
779 return;
780 #ifdef BSD_SELECT
781 setbuf(stdin, NULL);
782 #endif /* BSD_SELECT */
783 Flip_Bytes = FALSE;
784 Parity = 0;
785 Time_Out = FALSE;
786 bufp = 0;
787 Move_It = FALSE;
788 Noblock = FALSE;
789 #ifdef SYS5
790 value = ioctl(0, TCGETA, &Terminal);
791 if (Terminal.c_cflag & PARENB)
793 if (Terminal.c_cflag & PARENB)
794 Parity = 1;
795 else
796 Parity = 2;
798 if ((Terminal.c_cflag & CS8) == CS8)
800 Num_bits = 8;
802 else if ((Terminal.c_cflag & CS7) == CS7)
803 Num_bits = 7;
804 else if ((Terminal.c_cflag & CS6) == CS6)
805 Num_bits = 6;
806 else
807 Num_bits = 5;
808 value = Terminal.c_cflag & 037;
809 switch (value) {
810 case 01: speed = 50.0;
811 break;
812 case 02: speed = 75.0;
813 break;
814 case 03: speed = 110.0;
815 break;
816 case 04: speed = 134.5;
817 break;
818 case 05: speed = 150.0;
819 break;
820 case 06: speed = 200.0;
821 break;
822 case 07: speed = 300.0;
823 break;
824 case 010: speed = 600.0;
825 break;
826 case 011: speed = 900.0;
827 break;
828 case 012: speed = 1200.0;
829 break;
830 case 013: speed = 1800.0;
831 break;
832 case 014: speed = 2400.0;
833 break;
834 case 015: speed = 3600.0;
835 break;
836 case 016: speed = 4800.0;
837 break;
838 case 017: speed = 7200.0;
839 break;
840 case 020: speed = 9600.0;
841 break;
842 case 021: speed = 19200.0;
843 break;
844 case 022: speed = 38400.0;
845 break;
846 default: speed = 0.0;
848 #else
849 value = ioctl(0, TIOCGETP, &Terminal);
850 if (Terminal.sg_flags & EVENP)
851 Parity = 2;
852 else if (Terminal.sg_flags & ODDP)
853 Parity = 1;
854 value = Terminal.sg_ospeed;
855 switch (value) {
856 case 01: speed = 50.0;
857 break;
858 case 02: speed = 75.0;
859 break;
860 case 03: speed = 110.0;
861 break;
862 case 04: speed = 134.5;
863 break;
864 case 05: speed = 150.0;
865 break;
866 case 06: speed = 200.0;
867 break;
868 case 07: speed = 300.0;
869 break;
870 case 010: speed = 600.0;
871 break;
872 case 011: speed = 1200.0;
873 break;
874 case 012: speed = 1800.0;
875 break;
876 case 013: speed = 2400.0;
877 break;
878 case 014: speed = 4800.0;
879 break;
880 case 015: speed = 9600.0;
881 break;
882 default: speed = 0.0;
884 #endif
885 chars_per_millisecond = (0.001 * speed) / 8.0;
886 TERMINAL_TYPE = getenv("TERM");
887 if (TERMINAL_TYPE == NULL)
889 printf("unknown terminal type\n");
890 exit(0);
892 #ifndef CAP
893 Fildes = -1;
894 TERM_PATH = getenv("TERMINFO");
895 if (TERM_PATH != NULL)
897 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
898 Term_File_name = malloc(Data_Line_len);
899 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
900 Fildes = open(Term_File_name, O_RDONLY);
902 if (Fildes == -1)
904 TERM_PATH = "/usr/lib/terminfo";
905 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
906 Term_File_name = malloc(Data_Line_len);
907 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
908 Fildes = open(Term_File_name, O_RDONLY);
910 if (Fildes == -1)
912 TERM_PATH = "/usr/share/lib/terminfo";
913 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
914 Term_File_name = malloc(Data_Line_len);
915 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
916 Fildes = open(Term_File_name, O_RDONLY);
918 if (Fildes == -1)
920 TERM_PATH = "/usr/share/terminfo";
921 Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
922 Term_File_name = malloc(Data_Line_len);
923 sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
924 Fildes = open(Term_File_name, O_RDONLY);
926 if (Fildes == -1)
928 free(Term_File_name);
929 Term_File_name = NULL;
931 else
932 TERM_INFO = INFO_PARSE();
933 #else
935 | termcap information can be in the TERMCAP env variable, if so
936 | use that, otherwise check the /etc/termcap file
938 if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
940 if (*Term_File_name != '/')
941 Term_File_name = "/etc/termcap";
943 else
945 Term_File_name = "/etc/termcap";
947 if ((TFP = fopen(Term_File_name, "r")) == NULL)
949 printf("unable to open /etc/termcap file \n");
950 exit(0);
952 for (value = 0; value < 1024; value++)
953 String_table[value] = NULL;
954 for (value = 0; value < 128; value++)
955 Booleans[value] = 0;
956 for (value = 0; value < 128; value++)
957 Numbers[value] = 0;
958 Data_Line = malloc(512);
959 if (pointer && *pointer != '/')
961 TERM_data_ptr = pointer;
962 CAP_PARSE();
964 else
966 Find_term();
967 CAP_PARSE();
969 #endif
970 if (String_table[pc__] == NULL)
971 String_table[pc__] = "\0";
972 if ((String_table[cm__] == NULL) || (Booleans[hc__]))
974 fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
975 exit(0);
977 Key_Get();
978 keys_vt100();
979 LINES = Numbers[li__];
980 COLS = Numbers[co__];
981 if ((lines_string = getenv("LINES")) != NULL)
983 value = atoi(lines_string);
984 if (value > 0)
985 LINES = value;
987 if ((columns_string = getenv("COLUMNS")) != NULL)
989 value = atoi(columns_string);
990 if (value > 0)
991 COLS = value;
993 #ifdef TIOCGWINSZ
995 | get the window size
997 if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
999 if (ws.ws_row > 0)
1000 LINES = ws.ws_row;
1001 if (ws.ws_col > 0)
1002 COLS = ws.ws_col;
1004 #endif
1005 virtual_scr = newwin(LINES, COLS, 0, 0);
1006 stdscr = newwin(LINES, COLS, 0, 0);
1007 curscr = newwin(LINES, COLS, 0, 0);
1008 wmove(stdscr, 0, 0);
1009 werase(stdscr);
1010 Repaint_screen = TRUE;
1011 initialized = TRUE;
1012 virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1014 #ifdef SIGWINCH
1016 | reset size of windows and LINES and COLS if term window
1017 | changes size
1019 signal(SIGWINCH, reinitscr);
1020 #endif /* SIGWINCH */
1023 | check if scrolling is available
1026 nc_scrolling_ability = ((String_table[al__] != NULL) &&
1027 (String_table[dl__])) || ((String_table[cs__])
1028 && (String_table[sr__]));
1032 #ifndef CAP
1033 int
1034 Get_int(void) /* get a two-byte integer from the terminfo file */
1036 int High_byte;
1037 int Low_byte;
1038 int temp;
1040 Low_byte = *((unsigned char *) TERM_data_ptr++);
1041 High_byte = *((unsigned char *) TERM_data_ptr++);
1042 if (Flip_Bytes)
1044 temp = Low_byte;
1045 Low_byte = High_byte;
1046 High_byte = temp;
1048 if ((High_byte == 255) && (Low_byte == 255))
1049 return (-1);
1050 else
1051 return(Low_byte + (High_byte * 256));
1054 int
1055 INFO_PARSE(void) /* parse off the data in the terminfo data file */
1057 int offset;
1058 int magic_number = 0;
1059 int counter = 0;
1060 int Num_names = 0;
1061 int Num_bools = 0;
1062 int Num_ints = 0;
1063 int Num_strings = 0;
1064 int string_table_len = 0;
1065 char *temp_ptr;
1067 TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1068 Data_Line_len = read(Fildes, Data_Line, 10240);
1069 if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1070 return(0);
1072 | get magic number
1074 magic_number = Get_int();
1076 | if magic number not right, reverse byte order and check again
1078 if (magic_number != 282)
1080 Flip_Bytes = TRUE;
1081 TERM_data_ptr--;
1082 TERM_data_ptr--;
1083 magic_number = Get_int();
1084 if (magic_number != 282)
1085 return(0);
1088 | get the number of each type in the terminfo data file
1090 Num_names = Get_int();
1091 Num_bools = Get_int();
1092 Num_ints = Get_int();
1093 Num_strings = Get_int();
1094 string_table_len = Get_int();
1095 Strings = malloc(string_table_len);
1096 while (Num_names > 0)
1098 TERM_data_ptr++;
1099 Num_names--;
1101 counter = 0;
1102 while (Num_bools)
1104 Num_bools--;
1105 Booleans[counter++] = *TERM_data_ptr++;
1107 if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
1108 TERM_data_ptr++;
1109 counter = 0;
1110 while (Num_ints)
1112 Num_ints--;
1113 Numbers[counter] = Get_int();
1114 counter++;
1116 temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1117 memcpy(Strings, temp_ptr, string_table_len);
1118 counter = bt__;
1119 while (Num_strings)
1121 Num_strings--;
1122 if ((offset=Get_int()) != -1)
1124 if (String_table[counter] == NULL)
1125 String_table[counter] = Strings + offset;
1127 else
1128 String_table[counter] = NULL;
1129 counter++;
1131 close(Fildes);
1132 free(Data_Line);
1133 return(TRUE);
1135 #endif /* ifndef CAP */
1137 int
1138 AtoI(void) /* convert ascii text to integers */
1140 int Temp;
1142 Temp = 0;
1143 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1145 Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1146 TERM_data_ptr++;
1148 return(Temp);
1151 void
1152 Key_Get(void) /* create linked list with all key sequences obtained from terminal database */
1154 int Counter;
1155 int Klen;
1156 int key_def;
1157 struct KEY_STACK *Spoint;
1159 Max_Key_len = 0;
1160 Counter = 0;
1161 key_def = kb__;
1162 while (key_def <= kf63__)
1164 if (key_def == ke__)
1165 key_def = K1__;
1166 else if (key_def == (K5__ + 1))
1167 key_def = kcbt__;
1168 else if (key_def == (kcbt__ + 1))
1169 key_def = kbeg__;
1170 else if (key_def == (kUND__ + 1))
1171 key_def = kf11__;
1172 if (String_table[key_def] != NULL)
1174 if (KEY_TOS == NULL)
1175 Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1176 else
1178 Spoint = KEY_TOS;
1179 while (Spoint->next != NULL)
1180 Spoint = Spoint->next;
1181 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1182 Spoint = Spoint->next;
1184 Spoint->next = NULL;
1185 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1186 Spoint->element->string = String_table[key_def];
1187 Spoint->element->length = strlen(String_table[key_def]);
1188 Spoint->element->value = Key_vals[Counter];
1189 Klen = strlen(Spoint->element->string);
1190 if (Klen > Max_Key_len)
1191 Max_Key_len = Klen;
1193 | Some terminal types accept keystrokes of the form
1194 | \E[A and \EOA, substituting '[' for 'O'. Make a
1195 | duplicate of such key strings (since the
1196 | database will only have one version) so new_curse
1197 | can understand both.
1199 if ((Spoint->element->length > 1) &&
1200 ((String_table[key_def][1] == '[') ||
1201 (String_table[key_def][1] == 'O')))
1203 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1204 Spoint = Spoint->next;
1205 Spoint->next = NULL;
1206 Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1207 Spoint->element->length = strlen(String_table[key_def]);
1208 Spoint->element->string = malloc(Spoint->element->length + 1);
1209 strcpy(Spoint->element->string, String_table[key_def]);
1210 Spoint->element->value = Key_vals[Counter];
1211 Klen = strlen(Spoint->element->string);
1212 if (Klen > Max_Key_len)
1213 Max_Key_len = Klen;
1215 if (String_table[key_def][1] == '[')
1216 Spoint->element->string[1] = 'O';
1217 else
1218 Spoint->element->string[1] = '[';
1221 key_def++;
1222 Counter++;
1227 | insert information about keys for a vt100 terminal
1230 void
1231 keys_vt100(void)
1233 int counter;
1234 int Klen;
1235 struct KEY_STACK *Spoint;
1237 Spoint = KEY_TOS;
1238 while (Spoint->next != NULL)
1239 Spoint = Spoint->next;
1240 for (counter = 0; vt100[counter].length != 0; counter++)
1242 Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1243 Spoint = Spoint->next;
1244 Spoint->next = NULL;
1245 Spoint->element = &vt100[counter];
1246 Klen = strlen(Spoint->element->string);
1247 if (Klen > Max_Key_len)
1248 Max_Key_len = Klen;
1252 #ifdef CAP
1253 char *
1254 String_Get(char *param) /* read the string */
1256 char *String;
1257 char *Temp;
1258 int Counter;
1260 if (param == NULL)
1262 while (*TERM_data_ptr != '=')
1263 TERM_data_ptr++;
1264 Temp = ++TERM_data_ptr;
1265 Counter = 1;
1266 while ((*Temp != ':') && (*Temp != (char)NULL))
1268 Counter++;
1269 Temp++;
1271 if (Counter == 1) /* no data */
1272 return(NULL);
1273 String = Temp = malloc(Counter);
1274 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1276 if (*TERM_data_ptr == '\\')
1278 TERM_data_ptr++;
1279 if (*TERM_data_ptr == 'n')
1280 *Temp = '\n';
1281 else if (*TERM_data_ptr == 't')
1282 *Temp = '\t';
1283 else if (*TERM_data_ptr == 'b')
1284 *Temp = '\b';
1285 else if (*TERM_data_ptr == 'r')
1286 *Temp = '\r';
1287 else if (*TERM_data_ptr == 'f')
1288 *Temp = '\f';
1289 else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1290 *Temp = '\033'; /* escape */
1291 else if (*TERM_data_ptr == '\\')
1292 *Temp = '\\';
1293 else if (*TERM_data_ptr == '\'')
1294 *Temp = '\'';
1295 else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1297 Counter = 0;
1298 while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1300 Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1301 TERM_data_ptr++; /* ? */
1303 *Temp = Counter;
1304 TERM_data_ptr--;
1306 TERM_data_ptr++;
1307 Temp++;
1309 else if (*TERM_data_ptr == '^')
1311 TERM_data_ptr++;
1312 if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1313 *Temp = *TERM_data_ptr - '@';
1314 else if (*TERM_data_ptr == '?')
1315 *Temp = 127;
1316 TERM_data_ptr++;
1317 Temp++;
1319 else
1320 *Temp++ = *TERM_data_ptr++;
1322 *Temp = (char)NULL;
1323 param = String;
1325 else
1327 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1328 TERM_data_ptr++;
1330 return(param);
1333 int
1334 tc_Get_int(int param) /* read the integer */
1336 int Itemp;
1338 if (param == 0)
1340 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1341 TERM_data_ptr++;
1342 TERM_data_ptr++;
1343 Itemp = AtoI();
1344 param = Itemp;
1346 else
1348 while (*TERM_data_ptr != ':')
1349 TERM_data_ptr++;
1351 return(param);
1354 void
1355 Find_term(void) /* find terminal description in termcap file */
1357 char *Name;
1358 char *Ftemp;
1360 Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
1361 strcpy(Name, TERMINAL_TYPE);
1362 while (*Ftemp != (char)NULL)
1363 Ftemp++;
1364 *Ftemp++ = '|';
1365 *Ftemp = (char)NULL;
1366 CFOUND = FALSE;
1367 Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1368 while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1370 if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1372 while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1374 CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1375 while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1376 TERM_data_ptr++;
1377 if (*TERM_data_ptr == '|')
1378 TERM_data_ptr++;
1379 else if (!CFOUND)
1380 *TERM_data_ptr = (char)NULL;
1384 if (!CFOUND)
1386 printf("terminal type %s not found\n", TERMINAL_TYPE);
1387 exit(0);
1391 void
1392 CAP_PARSE(void) /* parse off the data in the termcap data file */
1394 int offset;
1395 int found;
1399 while (*TERM_data_ptr != (char)NULL)
1401 for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1403 if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1405 found = TRUE;
1406 Booleans[offset] = TRUE;
1409 if (!found)
1411 for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1413 if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1415 found = TRUE;
1416 Numbers[offset] = tc_Get_int(Numbers[offset]);
1420 if (!found)
1422 for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1424 if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1426 found = TRUE;
1427 String_table[offset] = String_Get(String_table[offset]);
1432 if (!strncmp(TERM_data_ptr, "tc=", 3))
1433 tc_ = String_Get(NULL);
1434 while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1435 TERM_data_ptr++;
1436 if (*TERM_data_ptr == ':')
1437 TERM_data_ptr++;
1439 } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1440 if (tc_ != NULL)
1442 TERMINAL_TYPE = tc_;
1443 rewind(TFP);
1444 Find_term();
1445 free(tc_);
1446 tc_ = NULL;
1447 CAP_PARSE();
1449 else
1450 fclose(TFP);
1452 #endif /* ifdef CAP */
1454 struct _line *
1455 Screenalloc(int columns)
1457 int i;
1458 struct _line *tmp;
1460 tmp = (struct _line *) malloc(sizeof (struct _line));
1461 tmp->row = malloc(columns + 1);
1462 tmp->attributes = malloc(columns + 1);
1463 tmp->prev_screen = NULL;
1464 tmp->next_screen = NULL;
1465 for (i = 0; i < columns; i++)
1467 tmp->row[i] = ' ';
1468 tmp->attributes[i] = (char) NULL;
1470 tmp->scroll = tmp->changed = FALSE;
1471 tmp->row[0] = (char) NULL;
1472 tmp->attributes[0] = (char) NULL;
1473 tmp->row[columns] = (char) NULL;
1474 tmp->attributes[columns] = (char) NULL;
1475 tmp->last_char = 0;
1476 return(tmp);
1480 lines, cols: number of lines and columns to be in window
1481 start_l, start_c: starting line and column to be in window
1483 WINDOW *
1484 newwin(int lines, int cols, int start_l, int start_c)
1486 WINDOW *Ntemp;
1487 struct _line *temp_screen;
1488 int i;
1490 Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1491 Ntemp->SR = start_l;
1492 Ntemp->SC = start_c;
1493 Ntemp->Num_lines = lines;
1494 Ntemp->Num_cols = cols;
1495 Ntemp->LX = 0;
1496 Ntemp->LY = 0;
1497 Ntemp->scroll_down = Ntemp->scroll_up = 0;
1498 Ntemp->SCROLL_CLEAR = FALSE;
1499 Ntemp->Attrib = FALSE;
1500 Ntemp->first_line = temp_screen = Screenalloc(cols);
1501 Ntemp->first_line->number = 0;
1502 for (i = 1; i < lines; i++)
1504 temp_screen->next_screen = Screenalloc(cols);
1505 temp_screen->next_screen->number = i;
1506 temp_screen->next_screen->prev_screen = temp_screen;
1507 temp_screen = temp_screen->next_screen;
1509 Ntemp->first_line->prev_screen = NULL;
1510 temp_screen->next_screen = NULL;
1511 return(Ntemp);
1514 #ifdef CAP
1516 p_list: stack of values
1517 place: place keeper of top of stack
1519 void
1520 Cap_Out(char *string, int *p_list, int place)
1521 /* interpret the output string if necessary */
1523 char *Otemp; /* temporary string pointer to parse output */
1524 int delay;
1525 int p1, p2, temp;
1526 float chars;
1528 if (string == NULL)
1529 return;
1531 if (p_list != NULL)
1533 p1 = p_list[--place];
1534 p2 = p_list[--place];
1536 delay = 0;
1537 Otemp = string;
1538 if ((*Otemp >= '0') && (*Otemp <= '9'))
1540 delay = atoi(Otemp);
1541 while ((*Otemp >= '0') && (*Otemp <= '9'))
1542 Otemp++;
1543 if (*Otemp == '*')
1544 Otemp++;
1546 while (*Otemp != (char)NULL)
1548 if (*Otemp == '%')
1550 Otemp++;
1551 if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1553 if (*Otemp == 'd')
1554 printf("%d", p1);
1555 else if (*Otemp == '2')
1556 printf("%02d", p1);
1557 else if (*Otemp == '3')
1558 printf("%03d", p1);
1559 else if (*Otemp == '+')
1561 Otemp++;
1562 p1 += *Otemp;
1563 putchar(p1);
1565 else if (*Otemp == '.')
1566 putchar(p1);
1567 p1 = p2;
1568 p2 = 0;
1570 else if (*Otemp == '>')
1572 Otemp++;
1573 if (p1 > *Otemp)
1575 Otemp++;
1576 p1 += *Otemp;
1578 else
1579 Otemp++;
1581 else if (*Otemp == 'r')
1583 temp = p1;
1584 p1 = p2;
1585 p2 = temp;
1587 else if (*Otemp == 'i')
1589 p1++;
1590 p2++;
1592 else if (*Otemp == '%')
1593 putchar(*Otemp);
1594 else if (*Otemp == 'n')
1596 p1 ^= 0140;
1597 p2 ^= 0140;
1599 else if (*Otemp == 'B')
1601 p1 = (16 * (p1/10)) + (p1 % 10);
1602 p2 = (16 * (p2/10)) + (p2 % 10);
1604 else if (*Otemp == 'D')
1606 p1 = (p1 - 2 * (p1 % 16));
1607 p2 = (p2 - 2 * (p2 % 16));
1610 else
1611 putchar (*Otemp);
1612 Otemp++;
1614 if (delay != 0)
1616 chars = delay * chars_per_millisecond;
1617 delay = chars;
1618 if ((chars - delay) > 0.0)
1619 delay++;
1620 for (; delay > 0; delay--)
1621 putchar(*String_table[pc__]);
1623 fflush(stdout);
1626 #else
1628 char *Otemp; /* temporary string pointer to parse output */
1629 float chars;
1630 int p[10];
1631 int variable[27];
1633 int
1634 Operation(int *Temp_Stack, int place) /* handle conditional operations */
1636 int temp;
1638 if (*Otemp == 'd')
1640 Otemp++;
1641 temp = Temp_Stack[--place];
1642 printf("%d", temp);
1644 else if (!strncmp(Otemp, "2d", 2))
1646 temp = Temp_Stack[--place];
1647 printf("%2d", temp);
1648 Otemp++;
1649 Otemp++;
1651 else if (!strncmp(Otemp, "3d", 2))
1653 temp = Temp_Stack[--place];
1654 printf("%0d", temp);
1655 Otemp++;
1656 Otemp++;
1658 else if (!strncmp(Otemp, "02d", 3))
1660 temp = Temp_Stack[--place];
1661 printf("%02d", temp);
1662 Otemp++;
1663 Otemp++;
1664 Otemp++;
1666 else if (!strncmp(Otemp, "03d", 3))
1668 temp = Temp_Stack[--place];
1669 printf("%03d", temp);
1670 Otemp++;
1671 Otemp++;
1672 Otemp++;
1674 else if (*Otemp == '+')
1676 Otemp++;
1677 temp = Temp_Stack[--place];
1678 temp += Temp_Stack[--place];
1679 Temp_Stack[place++] = temp;
1681 else if (*Otemp == '-')
1683 Otemp++;
1684 temp = Temp_Stack[--place];
1685 temp -= Temp_Stack[--place];
1686 Temp_Stack[place++] = temp;
1688 else if (*Otemp == '*')
1690 Otemp++;
1691 temp = Temp_Stack[--place];
1692 temp *= Temp_Stack[--place];
1693 Temp_Stack[place++] = temp;
1695 else if (*Otemp == '/')
1697 Otemp++;
1698 temp = Temp_Stack[--place];
1699 temp /= Temp_Stack[--place];
1700 Temp_Stack[place++] = temp;
1702 else if (*Otemp == 'm')
1704 Otemp++;
1705 temp = Temp_Stack[--place];
1706 temp %= Temp_Stack[--place];
1707 Temp_Stack[place++] = temp;
1709 else if (*Otemp == '&')
1711 Otemp++;
1712 temp = Temp_Stack[--place];
1713 temp &= Temp_Stack[--place];
1714 Temp_Stack[place++] = temp;
1716 else if (*Otemp == '|')
1718 Otemp++;
1719 temp = Temp_Stack[--place];
1720 temp |= Temp_Stack[--place];
1721 Temp_Stack[place++] = temp;
1723 else if (*Otemp == '^')
1725 Otemp++;
1726 temp = Temp_Stack[--place];
1727 temp ^= Temp_Stack[--place];
1728 Temp_Stack[place++] = temp;
1730 else if (*Otemp == '=')
1732 Otemp++;
1733 temp = Temp_Stack[--place];
1734 temp = (temp == Temp_Stack[--place]);
1735 Temp_Stack[place++] = temp;
1737 else if (*Otemp == '>')
1739 Otemp++;
1740 temp = Temp_Stack[--place];
1741 temp = temp > Temp_Stack[--place];
1742 Temp_Stack[place++] = temp;
1744 else if (*Otemp == '<')
1746 Otemp++;
1747 temp = Temp_Stack[--place];
1748 temp = temp < Temp_Stack[--place];
1749 Temp_Stack[place++] = temp;
1751 else if (*Otemp == 'c')
1753 Otemp++;
1754 putchar(Temp_Stack[--place]);
1756 else if (*Otemp == 'i')
1758 Otemp++;
1759 p[1]++;
1760 p[2]++;
1762 else if (*Otemp == '%')
1764 putchar(*Otemp);
1765 Otemp++;
1767 else if (*Otemp == '!')
1769 temp = ! Temp_Stack[--place];
1770 Temp_Stack[place++] = temp;
1771 Otemp++;
1773 else if (*Otemp == '~')
1775 temp = ~Temp_Stack[--place];
1776 Temp_Stack[place++] = temp;
1777 Otemp++;
1779 else if (*Otemp == 'p')
1781 Otemp++;
1782 Temp_Stack[place++] = p[*Otemp - '0'];
1783 Otemp++;
1785 else if (*Otemp == 'P')
1787 Otemp++;
1788 Temp_Stack[place++] = variable[*Otemp - 'a'];
1789 Otemp++;
1791 else if (*Otemp == 'g')
1793 Otemp++;
1794 variable[*Otemp - 'a'] = Temp_Stack[--place];
1795 Otemp++;
1797 else if (*Otemp == '\'')
1799 Otemp++;
1800 Temp_Stack[place++] = *Otemp;
1801 Otemp++;
1802 Otemp++;
1804 else if (*Otemp == '{')
1806 Otemp++;
1807 temp = atoi(Otemp);
1808 Temp_Stack[place++] = temp;
1809 while (*Otemp != '}')
1810 Otemp++;
1811 Otemp++;
1813 return(place);
1816 void
1817 Info_Out(char *string, int *p_list, int place)
1818 /* interpret the output string if necessary */
1820 char *tchar;
1821 int delay;
1822 int temp;
1823 int Cond_FLAG;
1824 int EVAL;
1825 int Cond_Stack[128];
1826 int Cond_place;
1827 int Stack[128];
1828 int Top_of_stack;
1830 if (string == NULL)
1831 return;
1833 Cond_FLAG = FALSE;
1834 Cond_place = 0;
1835 Top_of_stack = 0;
1836 p[0] = 0;
1837 p[1] = 0;
1838 p[2] = 0;
1839 p[3] = 0;
1840 p[4] = 0;
1841 p[5] = 0;
1842 p[6] = 0;
1843 p[7] = 0;
1844 p[8] = 0;
1845 p[9] = 0;
1846 if (p_list != NULL)
1848 for (temp = 1; (place != 0); temp++)
1850 p[temp] = p_list[--place];
1853 delay = 0;
1854 Otemp = string;
1855 while (*Otemp != (char) NULL)
1857 if (*Otemp == '%')
1859 Otemp++;
1860 if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1862 if (*Otemp == '?')
1864 Otemp++;
1865 Cond_FLAG = TRUE;
1866 EVAL = TRUE;
1867 while (EVAL)
1870 | find the end of the
1871 | conditional statement
1873 while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
1876 | move past '%'
1878 Otemp++;
1879 Cond_place = Operation(Cond_Stack, Cond_place);
1883 | if condition is true
1885 if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1888 | end conditional
1889 | parsing
1891 EVAL = FALSE;
1892 Otemp++;
1893 Otemp++;
1895 else /* condition is false */
1898 | find 'else' or end
1899 | of if statement
1901 while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
1902 Otemp++;
1904 | if an 'else' found
1906 if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
1908 Otemp++;
1909 Otemp++;
1910 tchar = Otemp;
1912 | check for 'then' part
1914 while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1915 tchar++;
1917 | if end of string
1919 if (*tchar == (char) NULL)
1921 EVAL = FALSE;
1922 Cond_FLAG = FALSE;
1923 Otemp = tchar;
1926 | if end of if found,
1927 | set up to parse
1928 | info
1930 else if (!strncmp(tchar, "%;", 2))
1931 EVAL = FALSE;
1933 | otherwise, check
1934 | conditional in
1935 | 'else'
1939 | if end of if found,
1940 | get out of if
1941 | statement
1943 else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
1945 EVAL = FALSE;
1946 Otemp++;
1947 Otemp++;
1949 else /* Otemp == NULL */
1951 EVAL = FALSE;
1952 Cond_FLAG = FALSE;
1957 else
1959 Otemp++;
1960 Cond_FLAG = FALSE;
1961 if (*Otemp != ';')
1963 while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
1964 Otemp++;
1965 if (*Otemp != (char) NULL)
1967 Otemp++;
1968 Otemp++;
1971 else
1972 Otemp++;
1975 else
1977 Top_of_stack = Operation(Stack, Top_of_stack);
1980 else if (!strncmp(Otemp, "$<", 2))
1982 Otemp++;
1983 Otemp++;
1984 delay = atoi(Otemp);
1985 while (*Otemp != '>')
1986 Otemp++;
1987 Otemp++;
1988 chars = delay * chars_per_millisecond;
1989 delay = chars;
1990 if ((chars - delay) > 0.0)
1991 delay++;
1992 if (String_table[pc__] == NULL)
1993 temp = 0;
1994 else
1995 temp = *String_table[pc__];
1996 for (; delay > 0; delay--)
1997 putc(temp, stdout);
1999 else
2001 putchar(*Otemp);
2002 Otemp++;
2005 fflush(stdout);
2007 #endif
2009 void
2010 wmove(WINDOW *window, int row, int column)
2011 /* move cursor to indicated position in window */
2013 if ((row < window->Num_lines) && (column < window->Num_cols))
2015 window->LX = column;
2016 window->LY = row;
2020 void
2021 clear_line(struct _line *line, int column, int cols)
2023 int j;
2025 if (column > line->last_char)
2026 line->row[line->last_char] = ' ';
2027 line->last_char = column;
2028 line->row[column] = (char) NULL;
2029 line->attributes[column] = (char) NULL;
2030 line->changed = TRUE;
2031 for (j = column + 1; j < cols; j++)
2033 line->row[j] = ' ';
2034 line->attributes[j] = (char) NULL;
2038 void
2039 werase(WINDOW *window) /* clear the specified window */
2041 int i;
2042 struct _line *tmp;
2044 window->SCROLL_CLEAR = CLEAR;
2045 window->scroll_up = window->scroll_down = 0;
2046 for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2047 clear_line(tmp, 0, window->Num_cols);
2050 void
2051 wclrtoeol(WINDOW *window)
2052 /* erase from current cursor position to end of line */
2054 int column, row;
2055 struct _line *tmp;
2057 window->SCROLL_CLEAR = CHANGE;
2058 column = window->LX;
2059 row = window->LY;
2060 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2061 tmp = tmp->next_screen;
2062 clear_line(tmp, column, window->Num_cols);
2065 void
2066 wrefresh(WINDOW *window) /* flush all previous output */
2068 wnoutrefresh(window);
2069 #ifdef DIAG
2071 struct _line *temp;
2072 int value;
2073 fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2074 for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2076 if (temp->number == -1)
2077 fprintf(stderr, "line moved ");
2078 if (temp->scroll)
2079 fprintf(stderr, "scroll_x is set: ");
2080 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2082 fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2083 fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2084 for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2086 if (temp->number == -1)
2087 fprintf(stderr, "line moved ");
2088 if (temp->scroll)
2089 fprintf(stderr, "scroll_x is set: ");
2090 fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2092 fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2093 for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2094 fprintf(stderr, "line=%s|\n", temp->row);
2096 #endif
2097 doupdate();
2098 virtual_scr->SCROLL_CLEAR = FALSE;
2099 virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2100 fflush(stdout);
2103 void
2104 touchwin(WINDOW *window)
2106 struct _line *user_line;
2107 int line_counter = 0;
2109 for (line_counter = 0, user_line = window->first_line;
2110 line_counter < window->Num_lines; line_counter++)
2112 user_line->changed = TRUE;
2114 window->SCROLL_CLEAR = TRUE;
2117 void
2118 wnoutrefresh(WINDOW *window)
2120 struct _line *user_line;
2121 struct _line *virtual_line;
2122 int line_counter = 0;
2123 int user_col = 0;
2124 int virt_col = 0;
2126 if (window->SR >= virtual_scr->Num_lines)
2127 return;
2128 user_line = window->first_line;
2129 virtual_line = virtual_scr->first_line;
2130 virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2131 virtual_scr->LX = window->LX + window->SC;
2132 virtual_scr->LY = window->LY + window->SR;
2133 virtual_scr->scroll_up = window->scroll_up;
2134 virtual_scr->scroll_down = window->scroll_down;
2135 if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2136 return;
2137 for (line_counter = 0; line_counter < window->SR; line_counter++)
2139 virtual_line = virtual_line->next_screen;
2141 for (line_counter = 0; (line_counter < window->Num_lines)
2142 && ((line_counter + window->SR) < virtual_scr->Num_lines);
2143 line_counter++)
2145 if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2147 for (user_col = 0, virt_col = window->SC;
2148 (virt_col < virtual_scr->Num_cols)
2149 && (user_col < window->Num_cols);
2150 virt_col++, user_col++)
2152 virtual_line->row[virt_col] = user_line->row[user_col];
2153 virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2156 if (virtual_scr->Num_cols != window->Num_cols)
2158 if (virtual_line->last_char < (user_line->last_char + window->SC))
2160 if (virtual_line->row[virtual_line->last_char] == (char) NULL)
2161 virtual_line->row[virtual_line->last_char] = ' ';
2162 virtual_line->last_char =
2163 min(virtual_scr->Num_cols,
2164 (user_line->last_char + window->SC));
2166 else if (virtual_line->last_char > (user_line->last_char + window->SC))
2168 virtual_line->row[min(virtual_scr->Num_cols,
2169 (user_line->last_char + window->SC))] = ' ';
2172 else
2173 virtual_line->last_char = user_line->last_char;
2174 virtual_line->row[virtual_line->last_char] = (char) NULL;
2175 virtual_line->changed = user_line->changed;
2176 virtual_line = virtual_line->next_screen;
2177 user_line = user_line->next_screen;
2179 window->SCROLL_CLEAR = FALSE;
2180 window->scroll_up = window->scroll_down = 0;
2181 last_window_refreshed = window;
2184 void
2185 flushinp(void) /* flush input */
2189 void
2190 ungetch(int c) /* push a character back on input */
2192 if (bufp < 100)
2193 in_buff[bufp++] = c;
2196 #ifdef BSD_SELECT
2197 int
2198 timed_getchar(void)
2200 struct timeval tv;
2201 fd_set fds;
2202 int ret_val;
2203 int nfds = 1;
2204 char temp;
2206 FD_ZERO(&fds);
2207 tv.tv_sec = 0;
2208 tv.tv_usec = 500000; /* half a second */
2209 FD_SET(0, &fds);
2210 Time_Out = FALSE; /* just in case */
2212 ret_val = select(nfds, &fds, 0, 0, &tv);
2215 | if ret_val is less than zero, there was no input
2216 | otherwise, get a character and return it
2219 if (ret_val <= 0)
2221 Time_Out = TRUE;
2222 return(-1);
2225 return(read(0, &temp, 1)? temp : -1);
2227 #endif
2229 int
2230 wgetch(WINDOW *window) /* get character from specified window */
2232 int in_value;
2233 char temp;
2234 #ifndef SYS5
2235 int old_arg;
2236 #endif /* SYS5 */
2238 #ifdef BSD_SELECT
2239 if (Noblock)
2240 in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2241 else
2242 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2243 #else /* BSD_SELECT */
2244 #ifdef SYS5
2245 in_value = ((bufp > 0) ? in_buff[--bufp] :
2246 (read(0, &temp, 1)> 0) ? temp : -1);
2247 #else /* SYS5 */
2248 if (Noblock)
2250 Time_Out = FALSE;
2251 old_arg = fcntl(0, F_GETFL, 0);
2252 in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2254 in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2255 if (Noblock)
2257 fcntl(0, F_SETFL, old_arg);
2258 if (Time_Out)
2259 in_value = -1;
2261 #endif /* SYS5 */
2262 #endif /* BSD_SELECT */
2264 if (in_value != -1)
2266 in_value &= 0xff;
2267 if ((Parity) && (Num_bits < 8))
2268 /* strip eighth bit if parity in use */
2269 in_value &= 0177;
2271 else if (interrupt_flag)
2273 interrupt_flag = FALSE;
2274 in_value = wgetch(window);
2277 if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2278 in_value = Get_key(in_value);
2279 return(in_value);
2282 #ifndef BSD_SELECT
2283 void
2284 Clear(int arg) /* notify that time out has occurred */
2286 Time_Out = TRUE;
2287 #ifdef DEBUG
2288 fprintf(stderr, "inside Clear()\n");
2289 fflush(stderr);
2290 #endif /* DEBUG */
2292 #endif /* BSD_SELECT */
2294 /* first_char: first character of sequence */
2295 int
2296 Get_key(int first_char) /* try to decode key sequence */
2298 int in_char;
2299 int Count;
2300 char string[128];
2301 char *Gtemp;
2302 int Found;
2303 #ifdef SYS5
2304 struct termio Gterminal;
2305 #else
2306 struct sgttyb Gterminal;
2307 #endif
2308 struct KEY_STACK *St_point;
2309 #if (!defined( BSD_SELECT)) || (!defined(SYS5))
2310 int value;
2311 #endif /* BSD_SELECT */
2313 Count = 0;
2314 Gtemp = string;
2315 string[Count++] = first_char;
2316 string[Count] = (char) NULL;
2317 Time_Out = FALSE;
2318 #ifndef BSD_SELECT
2319 signal(SIGALRM, Clear);
2320 value = alarm(1);
2321 #endif /* BSD_SELECT */
2322 Noblock = TRUE;
2323 #ifdef SYS5
2324 Gterminal.c_cc[VTIME] = 0; /* timeout value */
2325 Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
2326 Gterminal.c_lflag &= ~ECHO; /* disable echo */
2327 #endif
2328 Count = 1;
2329 Found = FALSE;
2330 while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2332 in_char = wgetch(stdscr);
2333 #ifdef DEBUG
2334 fprintf(stderr, "back in GetKey()\n");
2335 fflush(stderr);
2336 #endif /* DEBUG */
2337 if (in_char != -1)
2339 string[Count++] = in_char;
2340 string[Count] = (char) NULL;
2341 St_point = KEY_TOS;
2342 while ((St_point != NULL) && (!Found))
2344 if (!strcmp(string, St_point->element->string))
2345 Found = TRUE;
2346 else
2347 St_point = St_point->next;
2351 #ifndef BSD_SELECT
2352 if (!Time_Out)
2353 value = alarm(0);
2354 #endif /* BSD_SELECT */
2355 #ifdef SYS5
2356 /* value = ioctl(0, TCSETA, &Terminal);*/
2357 #else
2358 value = ioctl(0, TIOCSETP, &Terminal);
2359 /* value = fcntl(0, F_SETFL, old_arg);*/
2360 #endif
2361 Noblock = FALSE;
2362 if (Found)
2364 return(St_point->element->value);
2366 else
2368 while (Count > 1)
2370 if ((string[--Count] != -1) &&
2371 ((unsigned char) (string[Count]) != 255))
2373 #ifdef DIAG
2374 fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2375 #endif
2376 ungetch(string[Count]);
2379 return(first_char);
2383 void
2384 waddch(WINDOW *window, int c) /* output the character in the specified window */
2386 int row, column;
2387 int shift; /* number of spaces to shift if a tab */
2388 struct _line *tmpline;
2390 #ifdef DIAG
2391 /*printf("starting waddch \n");fflush(stdout);*/
2392 #endif
2393 row = window->LY;
2394 column = window->LX;
2395 if (c == '\t')
2397 shift = (column + 1) % 8;
2398 if (shift == 0)
2399 shift++;
2400 else
2401 shift = 9 - shift;
2402 while (shift > 0)
2404 shift--;
2405 waddch(window, ' ');
2408 else if ((column < window->Num_cols) && (row < window->Num_lines))
2410 if ((c == '~') && (Booleans[hz__]))
2411 c = '@';
2413 if (( c != '\b') && (c != '\n') && (c != '\r'))
2415 row = 0;
2416 tmpline = window->first_line;
2417 while (row < window->LY)
2419 row++;
2420 tmpline = tmpline->next_screen;
2422 tmpline->row[column] = c;
2423 tmpline->attributes[column] = window->Attrib;
2424 tmpline->changed = TRUE;
2425 if (column >= tmpline->last_char)
2427 if (column > tmpline->last_char)
2428 tmpline->row[tmpline->last_char] = ' ';
2429 tmpline->row[column + 1] = (char) NULL;
2430 tmpline->attributes[column + 1] = (char) NULL;
2431 tmpline->last_char = column + 1;
2434 if (c == '\n')
2436 wclrtoeol(window);
2437 window->LX = window->Num_cols;
2439 else if (c == '\r')
2440 window->LX = 0;
2441 else if (c == '\b')
2442 window->LX--;
2443 else
2444 window->LX++;
2446 if (window->LX >= window->Num_cols)
2448 window->LX = 0;
2449 window->LY++;
2450 if (window->LY >= window->Num_lines)
2452 window->LY = window->Num_lines - 1;
2453 /* window->LY = row;
2454 wmove(window, 0, 0);
2455 wdeleteln(window);
2456 wmove(window, row, 0);*/
2459 window->SCROLL_CLEAR = CHANGE;
2462 void
2463 winsertln(WINDOW *window) /* insert a blank line into the specified window */
2465 int row, column;
2466 struct _line *tmp;
2467 struct _line *tmp1;
2469 window->scroll_down += 1;
2470 window->SCROLL_CLEAR = SCROLL;
2471 column = window->LX;
2472 row = window->LY;
2473 for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2474 tmp = tmp->next_screen;
2475 if (tmp->prev_screen != NULL)
2476 tmp->prev_screen->next_screen = NULL;
2477 tmp1 = tmp;
2478 clear_line(tmp1, 0, window->Num_cols);
2479 tmp1->number = -1;
2480 for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2481 tmp = tmp->next_screen;
2482 if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2484 tmp1->next_screen = tmp->next_screen;
2485 tmp->next_screen = tmp1;
2486 tmp->changed = TRUE;
2487 tmp->next_screen->prev_screen = tmp;
2489 else if (window->Num_lines > 1)
2491 if (tmp->prev_screen != NULL)
2492 tmp->prev_screen->next_screen = tmp1;
2493 tmp1->prev_screen = tmp->prev_screen;
2494 tmp->prev_screen = tmp1;
2495 tmp1->next_screen = tmp;
2496 tmp->changed = TRUE;
2497 tmp->scroll = DOWN;
2499 if (window->LY == 0)
2500 window->first_line = tmp1;
2503 void
2504 wdeleteln(WINDOW *window) /* delete a line in the specified window */
2506 int row, column;
2507 struct _line *tmp;
2508 struct _line *tmpline;
2510 if (window->Num_lines > 1)
2512 window->scroll_up += 1;
2513 window->SCROLL_CLEAR = SCROLL;
2514 column = window->LX;
2515 row = window->LY;
2516 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2517 tmp = tmp->next_screen;
2518 if (window->LY == 0)
2519 window->first_line = tmp->next_screen;
2520 if (tmp->prev_screen != NULL)
2521 tmp->prev_screen->next_screen = tmp->next_screen;
2522 if (tmp->next_screen != NULL)
2524 tmp->next_screen->changed = TRUE;
2525 tmp->next_screen->scroll = UP;
2526 tmp->next_screen->prev_screen = tmp->prev_screen;
2528 tmpline = tmp;
2529 clear_line(tmpline, 0, window->Num_cols);
2530 tmpline->number = -1;
2531 for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2532 tmp = tmp->next_screen;
2533 if (tmp != NULL)
2535 tmp->next_screen = tmpline;
2536 tmp->next_screen->prev_screen = tmp;
2537 tmp->changed = TRUE;
2538 tmp = tmp->next_screen;
2540 else
2541 tmp = tmpline;
2542 tmp->next_screen = NULL;
2544 else
2546 clear_line(window->first_line, 0, window->Num_cols);
2550 void
2551 wclrtobot(WINDOW *window)
2552 /* delete from current position to end of the window */
2554 int row, column;
2555 struct _line *tmp;
2557 window->SCROLL_CLEAR |= CLEAR;
2558 column = window->LX;
2559 row = window->LY;
2560 for (row = 0, tmp = window->first_line; row < window->LY; row++)
2561 tmp = tmp->next_screen;
2562 clear_line(tmp, column, window->Num_cols);
2563 for (row = (window->LY + 1); row < window->Num_lines; row++)
2565 tmp = tmp->next_screen;
2566 clear_line(tmp, 0, window->Num_cols);
2568 wmove(window, row, column);
2571 void
2572 wstandout(WINDOW *window) /* begin standout mode in window */
2574 if (Numbers[sg__] < 1) /* if not magic cookie glitch */
2575 window->Attrib |= A_STANDOUT;
2578 void
2579 wstandend(WINDOW *window) /* end standout mode in window */
2581 window->Attrib &= ~A_STANDOUT;
2584 void
2585 waddstr(WINDOW *window, char *string) /* write 'string' in window */
2587 char *wstring;
2589 for (wstring = string; *wstring != (char) NULL; wstring++)
2590 waddch(window, *wstring);
2593 void
2594 clearok(WINDOW *window, int flag) /* erase screen and redraw at next refresh */
2596 Repaint_screen = TRUE;
2600 void
2601 echo(void) /* turn on echoing */
2603 int value;
2605 #ifdef SYS5
2606 Terminal.c_lflag |= ECHO; /* enable echo */
2607 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2608 #else
2609 Terminal.sg_flags |= ECHO; /* enable echo */
2610 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2611 #endif
2614 void
2615 noecho(void) /* turn off echoing */
2617 int value;
2619 #ifdef SYS5
2620 Terminal.c_lflag &= ~ECHO; /* disable echo */
2621 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2622 #else
2623 Terminal.sg_flags &= ~ECHO; /* disable echo */
2624 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2625 #endif
2628 void
2629 raw(void) /* set to read characters immediately */
2631 int value;
2633 #ifdef SYS5
2634 Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
2635 Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
2636 Terminal.c_lflag &= ~ISIG; /* disable signal checking */
2637 #ifdef FLUSHO
2638 Terminal.c_lflag &= ~FLUSHO;
2639 #endif
2640 #ifdef PENDIN
2641 Terminal.c_lflag &= ~PENDIN;
2642 #endif
2643 #ifdef IEXTEN
2644 Terminal.c_lflag &= ~IEXTEN;
2645 #endif
2646 Terminal.c_cc[VMIN] = 1; /* minimum of one character */
2647 Terminal.c_cc[VTIME] = 255; /* timeout value */
2648 Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
2649 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2650 #else
2651 Terminal.sg_flags |= RAW; /* enable raw mode */
2652 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2653 #endif
2656 void
2657 noraw(void) /* set to normal character read mode */
2659 int value;
2661 #ifdef SYS5
2662 Terminal.c_lflag |= ICANON; /* enable canonical operation */
2663 Terminal.c_lflag |= ISIG; /* enable signal checking */
2664 Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
2665 Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
2666 Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
2667 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2668 #else
2669 Terminal.sg_flags &= ~RAW; /* disable raw mode */
2670 value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
2671 /* old_arg = fcntl(0, F_GETFL, 0);
2672 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2673 #endif
2676 void
2677 nl(void)
2679 int value;
2681 #ifdef SYS5
2682 Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
2683 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2684 #endif
2687 void
2688 nonl(void)
2690 int value;
2692 #ifdef SYS5
2693 Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
2694 Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
2695 value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
2696 #endif
2699 void
2700 saveterm(void)
2704 void
2705 fixterm(void)
2709 void
2710 resetterm(void)
2714 void
2715 nodelay(WINDOW *window, int flag)
2719 void
2720 idlok(WINDOW *window, int flag)
2724 void
2725 keypad(WINDOW *window, int flag)
2727 if (flag)
2728 String_Out(String_table[ks__], NULL, 0);
2729 else
2730 String_Out(String_table[ke__], NULL, 0);
2733 void
2734 savetty(void) /* save current tty stats */
2736 int value;
2738 #ifdef SYS5
2739 value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
2740 #else
2741 value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
2742 #endif
2745 void
2746 resetty(void) /* restore previous tty stats */
2748 int value;
2750 #ifdef SYS5
2751 value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
2752 #else
2753 value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
2754 #endif
2757 void
2758 endwin(void) /* end windows */
2760 keypad(stdscr, FALSE);
2761 initialized = FALSE;
2762 delwin(curscr);
2763 delwin(virtual_scr);
2764 delwin(stdscr);
2765 #ifndef SYS5
2767 int old_arg, value;
2768 /* old_arg = fcntl(0, F_GETFL, 0);
2769 value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2771 #endif
2774 void
2775 delwin(WINDOW *window) /* delete the window structure */
2777 int i;
2779 for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2781 window->first_line = window->first_line->next_screen;
2782 free(window->first_line->prev_screen->row);
2783 free(window->first_line->prev_screen->attributes);
2784 free(window->first_line->prev_screen);
2786 if (window == last_window_refreshed)
2787 last_window_refreshed = 0;
2788 if (window->first_line != NULL)
2790 free(window->first_line->row);
2791 free(window->first_line->attributes);
2792 free(window->first_line);
2793 free(window);
2797 void
2798 wprintw(WINDOW *window, const char *format, ...)
2800 va_list ap;
2801 int value;
2802 char *fpoint;
2803 char *wtemp;
2805 va_start(ap, format);
2807 fpoint = (char *) format;
2808 while (*fpoint != (char) NULL)
2810 if (*fpoint == '%')
2812 fpoint++;
2813 if (*fpoint == 'd')
2815 value = va_arg(ap, int);
2816 iout(window, value);
2818 else if (*fpoint == 'c')
2820 value = va_arg(ap, int);
2821 waddch(window, value);
2823 else if (*fpoint == 's')
2825 wtemp = va_arg(ap, char *);
2826 waddstr(window, wtemp);
2828 fpoint++;
2830 else if (*fpoint == '\\')
2832 fpoint++;
2833 if (*fpoint == 'n')
2834 waddch(window, '\n');
2835 else if ((*fpoint >= '0') && (*fpoint <= '9'))
2837 value = 0;
2838 while ((*fpoint >= '0') && (*fpoint <= '9'))
2840 value = (value * 8) + (*fpoint - '0');
2841 fpoint++;
2843 waddch(window, value);
2845 fpoint++;
2847 else
2848 waddch(window, *fpoint++);
2850 va_end(ap);
2853 void
2854 iout(WINDOW *window, int value) /* output characters */
2856 int i;
2858 if ((i = value / 10) != 0)
2859 iout(window, i);
2860 waddch(window, ((value % 10) + '0'));
2863 int
2864 Comp_line(struct _line *line1, struct _line *line2) /* compare lines */
2866 int count1, count2;
2867 int i;
2868 char *att1, *att2;
2869 char *c1, *c2;
2871 c1 = line1->row;
2872 c2 = line2->row;
2873 att1 = line1->attributes;
2874 att2 = line2->attributes;
2875 count2 = strlen(c1) + 1;
2876 count1 = strlen(c2) + 1;
2877 if (count1 > count2)
2879 i = count2;
2880 count2 = count1;
2881 count1 = i;
2883 if (count2 > (count1 + count1))
2884 return(2);
2885 i = 0;
2886 while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2887 i++;
2888 count1 = i + 1;
2889 if ((count1 == 1) && (count2 == 1))
2890 count1 = 0; /* both lines blank */
2891 else if (count2 == count1)
2892 count1 = -1; /* equal */
2893 else
2894 count1 = count2 / count1; /* lines unequal */
2895 return(count1);
2898 struct _line *
2899 Insert_line(int row, int end_row, WINDOW *window) /* insert line into screen */
2901 int i;
2902 struct _line *tmp;
2903 struct _line *tmp1;
2905 for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2906 tmp = tmp->next_screen;
2907 if ((end_row + window->SR) == 0)
2908 curscr->first_line = curscr->first_line->next_screen;
2909 top_of_win = tmp;
2911 | find bottom line to delete
2913 for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2914 tmp = tmp->next_screen;
2915 if (tmp->prev_screen != NULL)
2916 tmp->prev_screen->next_screen = tmp->next_screen;
2917 if (tmp->next_screen != NULL)
2918 tmp->next_screen->prev_screen = tmp->prev_screen;
2919 tmp1 = tmp;
2921 | clear deleted line
2923 clear_line(tmp, 0, window->Num_cols);
2924 tmp1->number = -1;
2925 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2926 tmp = tmp->next_screen;
2927 top_of_win = tmp;
2928 for (i = 0, tmp = top_of_win; i < row; i++)
2929 tmp = tmp->next_screen;
2930 if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
2931 tmp->prev_screen->next_screen = tmp1;
2932 tmp1->prev_screen = tmp->prev_screen;
2933 tmp->prev_screen = tmp1;
2934 tmp1->next_screen = tmp;
2935 if ((row + window->SR) == 0)
2936 curscr->first_line = tmp1;
2937 if (tmp1->next_screen != NULL)
2938 tmp1 = tmp1->next_screen;
2940 if ((!String_table[cs__]) && (end_row < window->Num_lines))
2942 Position(window, (window->SR + end_row), 0);
2943 String_Out(String_table[dl__], NULL, 0);
2945 Position(window, (window->SR + row), 0);
2946 if (String_table[al__] != NULL)
2947 String_Out(String_table[al__], NULL, 0);
2948 else
2949 String_Out(String_table[sr__], NULL, 0);
2951 for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
2952 top_of_win = top_of_win->next_screen;
2953 return(tmp1);
2957 struct _line *
2958 Delete_line(int row, int end_row, struct _line *window)
2959 /* delete a line on screen */
2961 int i;
2962 struct _line *tmp;
2963 struct _line *tmp1;
2964 struct _line *tmp2;
2966 i = 0;
2967 tmp = curscr->first_line;
2968 while (i < window->SR)
2970 i++;
2971 tmp = tmp->next_screen;
2974 | find line to delete
2976 top_of_win = tmp;
2977 if ((row + window->SR) == 0)
2978 curscr->first_line = top_of_win->next_screen;
2979 for (i = 0, tmp = top_of_win; i < row; i++)
2980 tmp = tmp->next_screen;
2981 if (tmp->prev_screen != NULL)
2982 tmp->prev_screen->next_screen = tmp->next_screen;
2983 if (tmp->next_screen != NULL)
2984 tmp->next_screen->prev_screen = tmp->prev_screen;
2985 tmp2 = tmp->next_screen;
2986 tmp1 = tmp;
2988 | clear deleted line
2990 clear_line(tmp1, 0, window->Num_cols);
2991 tmp1->number = -1;
2993 | find location to insert deleted line
2995 for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
2996 tmp = tmp->next_screen;
2997 top_of_win = tmp;
2998 for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
2999 tmp = tmp->next_screen;
3000 tmp1->next_screen = tmp;
3001 tmp1->prev_screen = tmp->prev_screen;
3002 if (tmp1->prev_screen != NULL)
3003 tmp1->prev_screen->next_screen = tmp1;
3004 tmp->prev_screen = tmp1;
3006 Position(window, (window->SR + row), 0);
3007 String_Out(String_table[dl__], NULL, 0);
3008 if ((!String_table[cs__]) && (end_row < window->Num_lines))
3010 Position(window, (window->SR + end_row), 0);
3011 String_Out(String_table[al__], NULL, 0);
3013 else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3015 Position(window, (window->SR + end_row), 0);
3016 putchar('\n');
3019 if (row == (window->Num_lines-1))
3020 tmp2 = tmp1;
3021 if ((row + window->SR) == 0)
3022 curscr->first_line = top_of_win = tmp2;
3023 return(tmp2);
3026 void
3027 CLEAR_TO_EOL(WINDOW *window, int row, int column)
3029 int x, y;
3030 struct _line *tmp1;
3032 for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3033 tmp1 = tmp1->next_screen;
3034 for (x = column; x<window->Num_cols; x++)
3036 tmp1->row[x] = ' ';
3037 tmp1->attributes[x] = (char) NULL;
3039 tmp1->row[column] = (char) NULL;
3040 tmp1->last_char = column;
3041 if (column < COLS)
3043 if (STAND)
3045 STAND = FALSE;
3046 Position(window, row, column);
3047 attribute_off();
3049 if (String_table[ce__] != NULL)
3050 String_Out(String_table[ce__], NULL, 0);
3051 else
3053 for (x = column; x < window->Num_cols; x++)
3054 putchar(' ');
3055 Curr_x = x;
3060 int
3061 check_delete(WINDOW *window, int line, int offset, struct _line *pointer_new,
3062 struct _line *pointer_old)
3064 int end_old;
3065 int end_new;
3066 int k;
3067 int changed;
3068 char *old_lin;
3069 char *new_lin;
3070 char *old_att;
3071 char *new_att;
3073 changed = FALSE;
3074 new_lin = pointer_new->row;
3075 new_att = pointer_new->attributes;
3076 old_lin = pointer_old->row;
3077 old_att = pointer_old->attributes;
3078 end_old = end_new = offset;
3079 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != (char) NULL) && (new_lin[end_old] != (char) NULL))
3080 end_old++;
3081 if (old_lin[end_old] != (char) NULL)
3083 k = 0;
3084 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] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
3085 k++;
3086 if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
3088 if (new_lin[end_new+k] == (char) NULL)
3090 Position(window, line, (end_new+k));
3091 CLEAR_TO_EOL(window, line, (end_new+k));
3093 Position(window, line, offset);
3094 for (k = offset; k < end_old; k++)
3095 Char_del(old_lin, old_att, offset, window->Num_cols);
3096 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3097 offset++;
3098 pointer_old->last_char = offset;
3099 changed = TRUE;
3102 return(changed);
3106 | Check if characters were inserted in the middle of a line, and if
3107 | so, insert them.
3110 int
3111 check_insert(WINDOW *window, int line, int offset, struct _line *pointer_new,
3112 struct _line *pointer_old)
3114 int changed;
3115 int end_old, end_new;
3116 int k;
3117 int same = FALSE;
3118 int old_off;
3119 int insert;
3120 char *old_lin;
3121 char *new_lin;
3122 char *old_att;
3123 char *new_att;
3125 changed = FALSE;
3126 new_lin = pointer_new->row;
3127 new_att = pointer_new->attributes;
3128 old_lin = pointer_old->row;
3129 old_att = pointer_old->attributes;
3130 end_old = end_new = offset;
3131 while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != (char) NULL) && (old_lin[end_new] != (char) NULL))
3132 end_new++;
3133 if (new_lin[end_new] != (char) NULL)
3135 k = 0;
3136 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] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
3137 k++;
3139 | check for commonality between rest of lines (are the old
3140 | and new lines the same, except for a chunk in the middle?)
3141 | if the rest of the lines are common, do not insert text
3143 old_off = end_new;
3144 while ((old_lin[old_off] != (char) NULL) && (new_lin[old_off] != (char) NULL) && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3145 old_off++;
3146 if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3147 same = TRUE;
3148 if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
3150 Position(window, line, offset);
3151 insert = FALSE;
3152 if (String_table[ic__] == NULL)
3154 String_Out(String_table[im__], NULL, 0);
3155 insert = TRUE;
3157 for (k = offset; k < end_new; k++)
3159 if (!insert)
3160 String_Out(String_table[ic__], NULL, 0);
3161 Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3163 if (insert)
3164 String_Out(String_table[ei__], NULL, 0);
3165 while ((old_lin[offset] != (char) NULL) && (offset < COLS))
3166 offset++;
3167 pointer_old->last_char = offset;
3168 changed = TRUE;
3171 return(changed);
3174 void
3175 doupdate(void)
3177 WINDOW *window;
3178 int similar;
3179 int diff;
3180 int begin_old, begin_new;
3181 int end_old, end_new;
3182 int count1, j;
3183 int from_top, tmp_ft, offset;
3184 int changed;
3185 int first_time;
3186 int first_same;
3187 int last_same;
3188 int list[10];
3190 struct _line *curr;
3191 struct _line *virt;
3192 struct _line *old;
3194 struct _line *new;
3196 char *cur_lin;
3197 char *vrt_lin;
3198 char *cur_att;
3199 char *vrt_att;
3200 char *att1, *att2;
3201 char *c1, *c2;
3203 char NC_chinese = FALSE; /* flag to indicate handling Chinese */
3205 window = virtual_scr;
3207 if ((nc_attributes & A_NC_BIG5) != 0)
3208 NC_chinese = TRUE;
3210 if (Repaint_screen)
3212 if (String_table[cl__])
3213 String_Out(String_table[cl__], NULL, 0);
3214 else
3216 from_top = 0;
3217 while (from_top < LINES)
3219 Position(curscr, from_top, 0);
3220 if (String_table[ce__] != NULL)
3221 String_Out(String_table[ce__], NULL, 0);
3222 else
3224 for (j = 0; j < window->Num_cols; j++)
3225 putchar(' ');
3227 from_top++;
3230 for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3232 Position(curscr, from_top, 0);
3233 for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
3235 Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3237 if (STAND)
3239 STAND = FALSE;
3240 Position(curscr, from_top, j);
3241 attribute_off();
3244 Repaint_screen = FALSE;
3247 similar = 0;
3248 diff = FALSE;
3249 top_of_win = curscr->first_line;
3251 for (from_top = 0, curr = top_of_win, virt = window->first_line;
3252 from_top < window->Num_lines; from_top++)
3254 virtual_lines[from_top] = TRUE;
3255 if ((similar = Comp_line(curr, virt)) > 0)
3257 virtual_lines[from_top] = FALSE;
3258 diff = TRUE;
3260 curr = curr->next_screen;
3261 virt = virt->next_screen;
3264 from_top = 0;
3265 virt = window->first_line;
3266 curr = top_of_win;
3267 similar = 0;
3269 | if the window has lines that are different, check for scrolling
3271 if (diff)
3273 last_same = -1;
3274 changed = FALSE;
3275 for (first_same = window->Num_lines;
3276 (first_same > from_top) && (virtual_lines[first_same - 1]);
3277 first_same--)
3279 count1 = first_same - 1;
3280 for (last_same = 0;
3281 (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3282 last_same++)
3284 while ((from_top < first_same) && nc_scrolling_ability)
3285 /* check entire lines for diffs */
3289 if (from_top >= last_same)
3291 for (last_same = from_top;
3292 (last_same < window->Num_lines) &&
3293 (virtual_lines[last_same] == FALSE);
3294 last_same++)
3297 if (!virtual_lines[from_top])
3299 diff = TRUE;
3301 | check for lines deleted (scroll up)
3303 for (tmp_ft = from_top+1, old = curr->next_screen;
3304 ((window->scroll_up) && (diff) &&
3305 (tmp_ft < last_same) &&
3306 (!virtual_lines[tmp_ft]));
3307 tmp_ft++)
3309 if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3311 if (String_table[cs__]) /* scrolling region */
3313 list[1] = from_top;
3314 list[0] = min((last_same - 1), (window->Num_lines - 1));
3315 String_Out(String_table[cs__], list, 2);
3316 Curr_y = Curr_x = -1;
3319 for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3321 old = Delete_line(from_top, min((last_same - 1), (window->Num_lines - 1)), window);
3322 diff = FALSE;
3325 if (String_table[cs__]) /* scrolling region */
3327 list[1] = 0;
3328 list[0] = LINES - 1;
3329 String_Out(String_table[cs__], list, 2);
3330 Curr_y = Curr_x = -1;
3333 top_of_win = curscr->first_line;
3334 curr = top_of_win;
3335 for (offset = 0; offset < from_top; offset++)
3336 curr = curr->next_screen;
3337 for (offset = from_top, old=curr, new=virt;
3338 offset < window->Num_lines;
3339 old=old->next_screen, new=new->next_screen,
3340 offset++)
3342 similar = Comp_line(old, new);
3343 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3346 else
3347 old = old->next_screen;
3350 | check for lines inserted (scroll down)
3352 for (tmp_ft = from_top-1, old = curr->prev_screen;
3353 ((window->scroll_down) && (tmp_ft >= 0) &&
3354 (diff) &&
3355 (!virtual_lines[tmp_ft]));
3356 tmp_ft--)
3358 if (Comp_line(old, virt) == -1)
3360 if (String_table[cs__]) /* scrolling region */
3362 list[1] = tmp_ft;
3363 list[0] = min((last_same - 1), (window->Num_lines - 1));
3364 String_Out(String_table[cs__], list, 2);
3365 Curr_y = Curr_x = -1;
3368 for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3370 old = Insert_line(tmp_ft, min((last_same - 1), (window->Num_lines -1)), window);
3371 diff = FALSE;
3374 if (String_table[cs__]) /* scrolling region */
3376 list[1] = 0;
3377 list[0] = LINES - 1;
3378 String_Out(String_table[cs__], list, 2);
3379 Curr_y = Curr_x = -1;
3382 top_of_win = curscr->first_line;
3383 curr = top_of_win;
3384 for (offset = 0; offset < from_top; offset++)
3385 curr = curr->next_screen;
3386 for (offset = from_top, old=curr, new=virt;
3387 offset < window->Num_lines;
3388 old=old->next_screen, new=new->next_screen,
3389 offset++)
3391 similar = Comp_line(old, new);
3392 virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3395 else
3396 old = old->prev_screen;
3399 from_top++;
3400 curr = curr->next_screen;
3401 virt = virt->next_screen;
3407 | Scrolling done, now need to insert, delete, or modify text
3408 | within lines.
3411 for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3412 curr = curr->next_screen;
3413 top_of_win = curr;
3414 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)
3418 | If either 'insert mode' or 'insert char' are
3419 | available, enter the following 'if' statement,
3420 | else, need to simply rewrite the contents of the line
3421 | at the point where the contents of the line change.
3424 if (((String_table[ic__]) || (String_table[im__])) &&
3425 (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
3426 (!NC_chinese))
3428 j = 0;
3429 first_time = TRUE;
3430 vrt_lin = virt->row;
3431 vrt_att = virt->attributes;
3432 cur_lin = curr->row;
3433 cur_att = curr->attributes;
3434 while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
3436 if ((STAND) && (Booleans[xs__]))
3438 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
3439 j++;
3440 if ((STAND) && (!vrt_att[j]))
3442 STAND = FALSE;
3443 Position(window, from_top, j);
3444 attribute_off();
3445 attribute_off();
3448 else
3450 while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
3451 j++;
3453 if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3455 Position(window, from_top, j);
3456 /* CLEAR_TO_EOL(window, from_top, j);*/
3457 attribute_off();
3458 attribute_off();
3460 if (vrt_lin[j] != (char) NULL)
3462 begin_new = j;
3463 begin_old = j;
3464 end_old = j;
3465 end_new = j;
3466 if ((first_time) && (virt->changed))
3468 if (curr->last_char <= virt->last_char)
3469 changed = check_insert(window, from_top, j, virt, curr);
3471 changed = check_delete(window, from_top, j, virt, curr);
3472 first_time = FALSE;
3473 virt->changed = FALSE;
3474 if (!changed)
3475 changed = check_insert(window, from_top, j, virt, curr);
3476 if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3478 if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
3479 cur_lin[j] = ' ';
3480 else
3482 Position(window, from_top, j);
3483 Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3486 if ((vrt_lin[j] != (char) NULL))
3487 j++;
3489 if ((STAND) && (!vrt_att[j]))
3491 STAND = FALSE;
3492 Position(window, from_top, j);
3493 attribute_off();
3496 if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
3498 Position(window, from_top, j);
3499 CLEAR_TO_EOL(window, from_top, j);
3502 else /*if ((similar != -1) && (similar != 0))*/
3504 j = 0;
3505 c1 = curr->row;
3506 att1 = curr->attributes;
3507 c2 = virt->row;
3508 att2 = virt->attributes;
3509 while ((j < window->Num_cols) && (c2[j] != (char) NULL))
3511 while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
3512 j++;
3515 | if previous character is an eight bit
3516 | char, start redraw from that character
3519 if ((NC_chinese) && (highbitset(c1[j - 1])))
3520 j--;
3521 begin_old = j;
3522 begin_new = j;
3523 if ((j < window->Num_cols) && (c2[j] != (char) NULL))
3525 Position(window, from_top, begin_old);
3526 CLEAR_TO_EOL(window, from_top, j);
3527 Position(window, from_top, begin_old);
3528 for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
3529 Char_out(c2[j], att2[j], c1, att1, j);
3532 if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
3534 Position(window, from_top, j);
3535 CLEAR_TO_EOL(window, from_top, j);
3538 if (STAND)
3540 STAND = FALSE;
3541 Position(window, from_top, j);
3542 attribute_off();
3544 virt->number = from_top;
3546 Position(window, window->LY, window->LX);
3549 void
3550 Position(WINDOW *window, int row, int col)
3551 /* position the cursor for output on the screen */
3553 int list[10];
3554 int place;
3556 int pos_row;
3557 int pos_column;
3559 pos_row = row + window->SR;
3560 pos_column = col + window->SC;
3561 if ((pos_row != Curr_y) || (pos_column != Curr_x))
3563 if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3565 place = 0;
3566 list[place++] = pos_column;
3567 list[place++] = pos_row;
3568 String_Out(String_table[cm__], list, place);
3569 if ((STAND) && (!Booleans[ms__]))
3570 attribute_on();
3572 Curr_x = pos_column;
3573 Curr_y = pos_row;
3577 void
3578 Char_del(char *line, char *attrib, int offset, int maxlen)
3579 /* delete chars from line */
3581 int one, two;
3583 for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
3585 line[one] = line[two];
3586 attrib[one] = attrib[two];
3588 String_Out(String_table[dc__], NULL, 0);
3591 void
3592 Char_ins(char *line, char *attrib, char newc, char newatt, int offset,
3593 int maxlen) /* insert chars in line */
3595 int one, two;
3597 one = 0;
3598 while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
3599 one++;
3600 for (two = one + 1; (two > offset); one--, two--)
3602 line[two] = line[one];
3603 attrib[two] = attrib[one];
3605 line[offset] = newc;
3606 attrib[offset] = newatt;
3607 Char_out(newc, newatt, line, attrib, offset);
3610 void
3611 attribute_on(void)
3613 if (String_table[sa__])
3615 attributes_set[0] = 1;
3616 String_Out(String_table[sa__], attributes_set, 1);
3618 else if (String_table[so__])
3619 String_Out(String_table[so__], NULL, 0);
3622 void
3623 attribute_off(void)
3625 if (String_table[me__])
3626 String_Out(String_table[me__], NULL, 0);
3627 else if (String_table[sa__])
3629 attributes_set[0] = 0;
3630 String_Out(String_table[sa__], attributes_set, 1);
3632 else if (String_table[se__])
3633 String_Out(String_table[se__], NULL, 0);
3636 void
3637 Char_out(char newc, char newatt, char *line, char *attrib, int offset)
3638 /* output character with proper attribute */
3642 if ((newatt) && (!STAND))
3644 STAND = TRUE;
3645 attribute_on();
3647 else if ((STAND) && (!newatt))
3649 STAND = FALSE;
3650 attribute_off();
3653 if ((newatt) && (STAND) && (Booleans[xs__]))
3655 attribute_on();
3658 if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3660 putchar(newc);
3661 line[offset] = newc;
3662 attrib[offset] = newatt;
3664 Curr_x++;
3669 | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3670 | hacks that notify new_curse to handle characters that have the high
3671 | bit set as the first of two bytes of a multi-byte string.
3675 void
3676 nc_setattrib(int flag)
3678 nc_attributes |= flag;
3681 void
3682 nc_clearattrib(int flag)
3684 nc_attributes &= ~flag;