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