new_curse.c revision 192914
1145132Sanholt/*
2145132Sanholt |	new_curse.c
3152909Sanholt |
4145132Sanholt |	A subset of curses developed for use with ae.
5145132Sanholt |
6182080Srnoland |	written by Hugh Mahon
7152909Sanholt |
8152909Sanholt |      Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon
9152909Sanholt |      All rights reserved.
10152909Sanholt |
11152909Sanholt |      Redistribution and use in source and binary forms, with or without
12152909Sanholt |      modification, are permitted provided that the following conditions
13152909Sanholt |      are met:
14182080Srnoland |
15152909Sanholt |          * Redistributions of source code must retain the above copyright
16152909Sanholt |            notice, this list of conditions and the following disclaimer.
17152909Sanholt |          * Redistributions in binary form must reproduce the above
18182080Srnoland |            copyright notice, this list of conditions and the following
19152909Sanholt |            disclaimer in the documentation and/or other materials provided
20152909Sanholt |            with the distribution.
21152909Sanholt |
22152909Sanholt |      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23152909Sanholt |      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24152909Sanholt |      LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25152909Sanholt |      FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26182080Srnoland |      COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27152909Sanholt |      INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28145132Sanholt |      BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29152909Sanholt |      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30152909Sanholt |      CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31145132Sanholt |      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32152909Sanholt |      ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33152909Sanholt |      POSSIBILITY OF SUCH DAMAGE.
34152909Sanholt |
35152909Sanholt |
36152909Sanholt |	All are rights reserved.
37145132Sanholt |
38145132Sanholt |	$Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh Exp $
39145132Sanholt |
40145132Sanholt */
41145132Sanholt
42182080Srnolandchar *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon",
43145132Sanholt				"All rights are reserved."};
44145132Sanholt
45145132Sanholtchar * new_curse_name= "@(#) new_curse.c $Revision: 1.54 $";
46182080Srnoland
47183573Srnoland#include "new_curse.h"
48183573Srnoland#include <signal.h>
49183573Srnoland#include <fcntl.h>
50145132Sanholt
51145132Sanholt#ifdef SYS5
52183573Srnoland#include <string.h>
53182080Srnoland#else
54183573Srnoland#include <strings.h>
55145132Sanholt#endif
56145132Sanholt
57145132Sanholt#ifdef BSD_SELECT
58145132Sanholt#include <sys/types.h>
59145132Sanholt#include <sys/time.h>
60145132Sanholt
61189049Srnoland#ifdef SLCT_HDR
62189049Srnoland#include <sys/select.h>  /* on AIX */
63189049Srnoland#endif /* SLCT_HDR */
64145132Sanholt
65145132Sanholt#endif /* BSD_SELECT */
66145132Sanholt
67183573Srnoland#ifdef HAS_STDLIB
68183573Srnoland#include <stdlib.h>
69183573Srnoland#endif
70145132Sanholt
71183573Srnoland#if defined(__STDC__)
72183573Srnoland#include <stdarg.h>
73145132Sanholt#else
74145132Sanholt#include <varargs.h>
75182080Srnoland#endif
76145132Sanholt
77145132Sanholt#ifdef HAS_UNISTD
78189049Srnoland#include <unistd.h>
79189049Srnoland#endif
80189049Srnoland
81189049Srnoland#ifdef HAS_SYS_IOCTL
82189049Srnoland#include <sys/ioctl.h>
83183573Srnoland#endif
84183573Srnoland
85183573Srnoland
86183573SrnolandWINDOW *curscr;
87183573Srnolandstatic WINDOW *virtual_scr;
88189049SrnolandWINDOW *stdscr;
89189049SrnolandWINDOW *last_window_refreshed;
90183573Srnoland
91189049Srnoland#ifdef TIOCGWINSZ
92183573Srnoland	struct winsize ws;
93183573Srnoland#endif
94183573Srnoland
95189049Srnoland#define min(a, b)	(a < b ? a : b)
96189049Srnoland#define highbitset(a)	((a) & 0x80)
97183573Srnoland
98183573Srnoland#ifndef CAP
99183573Srnoland#define String_Out(table, stack, place) Info_Out(table, stack, place)
100189049Srnoland#else
101183573Srnoland#define String_Out(table, stack, place) Cap_Out(table, stack, place)
102183573Srnoland#endif
103183573Srnoland
104183573Srnoland#define bw__ 0	/* booleans	*/
105189049Srnoland#define am__ 1
106189049Srnoland#define xb__ 2
107189049Srnoland#define xs__ 3	/* hp glitch (standout not erased by overwrite)	*/
108189049Srnoland#define xn__ 4
109189049Srnoland#define eo__ 5
110183573Srnoland#define gn__ 6	/* generic type terminal	*/
111183573Srnoland#define hc__ 7	/* hardcopy terminal		*/
112183573Srnoland#define km__ 8
113183573Srnoland#define hs__ 9
114183573Srnoland#define in__ 10
115183573Srnoland#define da__ 11
116183573Srnoland#define db__ 12
117183573Srnoland#define mi__ 13	/* safe to move during insert mode	*/
118183573Srnoland#define ms__ 14	/* safe to move during standout mode	*/
119183573Srnoland#define os__ 15
120183573Srnoland#define es__ 16
121183573Srnoland#define xt__ 17
122189049Srnoland#define hz__ 18	/* hazeltine glitch	*/
123189049Srnoland#define ul__ 19
124183573Srnoland#define xo__ 20
125183573Srnoland#define chts__ 21
126182080Srnoland#define nxon__ 22
127145132Sanholt#define nrrmc__ 23
128145132Sanholt#define npc__ 24
129145132Sanholt#define mc5i__ 25
130145132Sanholt
131182080Srnoland#define co__ 0	/* number of columns	*/	/* numbers		*/
132182080Srnoland#define it__ 1	/* spaces per tab	*/
133145132Sanholt#define li__ 2	/* number of lines	*/
134145132Sanholt#define lm__ 3
135145132Sanholt#define sg__ 4	/* magic cookie glitch	*/
136189049Srnoland#define pb__ 5
137189049Srnoland#define vt__ 6
138189049Srnoland#define ws__ 7
139145132Sanholt
140145132Sanholt#define cols__ 0
141182080Srnoland#define lines__ 2
142145132Sanholt#define xmc__ 4
143182080Srnoland#define vt__ 6
144145132Sanholt#define wsl__ 7
145145132Sanholt#define nlab__ 8
146145132Sanholt#define lh__ 9
147145132Sanholt#define lw__ 10
148183573Srnoland
149145132Sanholt#define bt__ 0	/* back tab		*/	/* strings	*/
150145132Sanholt#define bl__ 1	/* bell			*/
151182080Srnoland#define cr__ 2	/* carriage return	*/
152182080Srnoland#define cs__ 3	/* change scroll region	*/
153189049Srnoland#define ct__ 4	/* clear all tab stops	*/
154207066Srnoland#define cl__ 5	/* clear screen and home cursor	*/
155182080Srnoland#define ce__ 6	/* clear to end of line	*/
156182080Srnoland#define cd__ 7	/* clear to end of display	*/
157145132Sanholt#define ch__ 8	/* set cursor column	*/
158189049Srnoland#define CC__ 9	/* term, settable cmd char in 	*/
159183573Srnoland#define cm__ 10	/* screen rel cursor motion, row, column	*/
160189049Srnoland#define do__ 11	/* down one line	*/
161145132Sanholt#define ho__ 12	/* home cursor	*/
162145132Sanholt#define vi__ 13	/* make cursor invisible	*/
163145132Sanholt#define le__ 14	/* move cursor left one space	*/
164145132Sanholt#define CM__ 15	/* memory rel cursor addressing	*/
165189049Srnoland#define ve__ 16	/* make cursor appear normal	*/
166145132Sanholt#define nd__ 17	/* non-destructive space (cursor right)	*/
167182080Srnoland#define ll__ 18	/* last line, first col	*/
168171394Skib#define up__ 19	/* cursor up		*/
169182080Srnoland#define vs__ 20
170145132Sanholt#define dc__ 21	/* delete character	*/
171145132Sanholt#define dl__ 22	/* delete line		*/
172145132Sanholt#define ds__ 23
173182080Srnoland#define hd__ 24
174145132Sanholt#define as__ 25
175145132Sanholt#define mb__ 26
176189049Srnoland#define md__ 27	/* turn on bold		*/
177207066Srnoland#define ti__ 28
178145132Sanholt#define dm__ 29	/* turn on delete mode	*/
179189049Srnoland#define mh__ 30	/* half bright mode	*/
180189049Srnoland#define im__ 31	/* insert mode		*/
181189049Srnoland#define mk__ 32
182189049Srnoland#define mp__ 33
183189049Srnoland#define mr__ 34
184189049Srnoland#define so__ 35	/* enter standout mode	*/
185189049Srnoland#define us__ 36
186182080Srnoland#define ec__ 37
187183573Srnoland#define ae__ 38
188183573Srnoland#define me__ 39
189145132Sanholt#define te__ 40
190183573Srnoland#define ed__ 41
191183573Srnoland#define ei__ 42	/* exit insert mode	*/
192183573Srnoland#define se__ 43	/* exit standout mode	*/
193183573Srnoland#define ue__ 44
194183573Srnoland#define vb__ 45
195145132Sanholt#define ff__ 46
196190021Srnoland#define fs__ 47
197145132Sanholt#define i1__ 48
198207066Srnoland#define i2__ 49
199183573Srnoland#define i3__ 50
200183573Srnoland#define if__ 51
201183573Srnoland#define ic__ 52
202183573Srnoland#define al__ 53
203183573Srnoland#define ip__ 54
204145132Sanholt#define kb__ 55		/* backspace key	*/
205145132Sanholt#define ka__ 56
206207066Srnoland#define kC__ 57
207189049Srnoland#define kt__ 58
208182080Srnoland#define kD__ 59
209189049Srnoland#define kL__ 60
210189049Srnoland#define kd__ 61
211189049Srnoland#define kM__ 62
212190021Srnoland#define kE__ 63
213145132Sanholt#define kS__ 64
214145132Sanholt#define k0__ 65
215145132Sanholt#define k1__ 66
216145132Sanholt#define kf10__ 67
217145132Sanholt#define k2__ 68
218145132Sanholt#define k3__ 69
219145132Sanholt#define k4__ 70
220145132Sanholt#define k5__ 71
221182080Srnoland#define k6__ 72
222145132Sanholt#define k7__ 73
223145132Sanholt#define k8__ 74
224145132Sanholt#define k9__ 75
225182080Srnoland#define kh__ 76
226145132Sanholt#define kI__ 77
227145132Sanholt#define kA__ 78
228145132Sanholt#define kl__ 79
229182080Srnoland#define kH__ 80
230145132Sanholt#define kN__ 81
231145132Sanholt#define kP__ 82
232207066Srnoland#define kr__ 83
233145132Sanholt#define kF__ 84
234145132Sanholt#define kR__ 85
235182080Srnoland#define kT__ 86
236145132Sanholt#define ku__ 87	/* key up	*/
237145132Sanholt#define ke__ 88
238145132Sanholt#define ks__ 89
239145132Sanholt#define l0__ 90
240145132Sanholt#define l1__ 91
241182080Srnoland#define la__ 92
242145132Sanholt#define l2__ 93
243145132Sanholt#define l3__ 94
244145132Sanholt#define l4__ 95
245182080Srnoland#define l5__ 96
246189049Srnoland#define l6__ 97
247182080Srnoland#define l7__ 98
248189049Srnoland#define l8__ 99
249145132Sanholt#define l9__ 100
250145132Sanholt#define mo__ 101
251145132Sanholt#define mm__ 102
252145132Sanholt#define nw__ 103
253145132Sanholt#define pc__ 104
254182080Srnoland#define DC__ 105
255182080Srnoland#define DL__ 106
256145132Sanholt#define DO__ 107
257182080Srnoland#define IC__ 118
258145132Sanholt#define SF__ 109
259145132Sanholt#define AL__ 110
260182080Srnoland#define LE__ 111
261145132Sanholt#define RI__ 112
262189049Srnoland#define SR__ 113
263145132Sanholt#define UP__ 114
264145132Sanholt#define pk__ 115
265145132Sanholt#define pl__ 116
266145132Sanholt#define px__ 117
267145132Sanholt#define ps__ 118
268145132Sanholt#define pf__ 119
269145132Sanholt#define po__ 120
270145132Sanholt#define rp__ 121
271145132Sanholt#define r1__ 122
272145132Sanholt#define r2__ 123
273145132Sanholt#define r3__ 124
274145132Sanholt#define rf__ 125
275145132Sanholt#define rc__ 126
276145132Sanholt#define cv__ 127
277145132Sanholt#define sc__ 128
278145132Sanholt#define sf__ 129
279145132Sanholt#define sr__ 130
280145132Sanholt#define sa__ 131	/* sgr	*/
281145132Sanholt#define st__ 132
282145132Sanholt#define wi__ 133
283145132Sanholt#define ta__ 134
284145132Sanholt#define ts__ 135
285145132Sanholt#define uc__ 136
286145132Sanholt#define hu__ 137
287145132Sanholt#define iP__ 138
288145132Sanholt#define K1__ 139
289145132Sanholt#define K2__ 140
290145132Sanholt#define K3__ 141
291145132Sanholt#define K4__ 142
292145132Sanholt#define K5__ 143
293145132Sanholt#define pO__ 144
294145132Sanholt#define ml__ 145
295145132Sanholt#define mu__ 146
296145132Sanholt#define rmp__ 145
297145132Sanholt#define acsc__ 146
298145132Sanholt#define pln__ 147
299145132Sanholt#define kcbt__ 148
300145132Sanholt#define smxon__ 149
301145132Sanholt#define rmxon__ 150
302145132Sanholt#define smam__ 151
303145132Sanholt#define rmam__ 152
304145132Sanholt#define xonc__ 153
305145132Sanholt#define xoffc__ 154
306145132Sanholt#define enacs__ 155
307145132Sanholt#define smln__ 156
308145132Sanholt#define rmln__ 157
309145132Sanholt#define kbeg__ 158
310145132Sanholt#define kcan__ 159
311145132Sanholt#define kclo__ 160
312145132Sanholt#define kcmd__ 161
313145132Sanholt#define kcpy__ 162
314145132Sanholt#define kcrt__ 163
315145132Sanholt#define kend__ 164
316145132Sanholt#define kent__ 165
317145132Sanholt#define kext__ 166
318145132Sanholt#define kfnd__ 167
319145132Sanholt#define khlp__ 168
320145132Sanholt#define kmrk__ 169
321145132Sanholt#define kmsg__ 170
322145132Sanholt#define kmov__ 171
323145132Sanholt#define knxt__ 172
324145132Sanholt#define kopn__ 173
325145132Sanholt#define kopt__ 174
326145132Sanholt#define kprv__ 175
327145132Sanholt#define kprt__ 176
328145132Sanholt#define krdo__ 177
329145132Sanholt#define kref__ 178
330145132Sanholt#define krfr__ 179
331145132Sanholt#define krpl__ 180
332145132Sanholt#define krst__ 181
333145132Sanholt#define kres__ 182
334145132Sanholt#define ksav__ 183
335145132Sanholt#define kspd__ 184
336145132Sanholt#define kund__ 185
337145132Sanholt#define kBEG__ 186
338145132Sanholt#define kCAN__ 187
339145132Sanholt#define kCMD__ 188
340145132Sanholt#define kCPY__ 189
341145132Sanholt#define kCRT__ 190
342145132Sanholt#define kDC__ 191
343145132Sanholt#define kDL__ 192
344145132Sanholt#define kslt__ 193
345145132Sanholt#define kEND__ 194
346145132Sanholt#define kEOL__ 195
347145132Sanholt#define kEXT__ 196
348145132Sanholt#define kFND__ 197
349182080Srnoland#define kHLP__ 198
350145132Sanholt#define kHOM__ 199
351145132Sanholt#define kIC__ 200
352145132Sanholt#define kLFT__ 201
353145132Sanholt#define kMSG__ 202
354182080Srnoland#define kMOV__ 203
355182080Srnoland#define kNXT__ 204
356145132Sanholt#define kOPT__ 205
357145132Sanholt#define kPRV__ 206
358145132Sanholt#define kPRT__ 207
359145132Sanholt#define kRDO__ 208
360145132Sanholt#define kRPL__ 209
361157617Sanholt#define kRIT__ 210
362182080Srnoland#define kRES__ 211
363157617Sanholt#define kSAV__ 212
364162132Sanholt#define kSPD__ 213
365157617Sanholt#define kUND__ 214
366145132Sanholt#define rfi__ 215
367145132Sanholt#define kf11__ 216
368145132Sanholt#define kf12__ 217
369183573Srnoland#define kf13__ 218
370183573Srnoland#define kf14__ 219
371183573Srnoland#define kf15__ 220
372145132Sanholt#define kf16__ 221
373182080Srnoland#define kf17__ 222
374145132Sanholt#define kf18__ 223
375145132Sanholt#define kf19__ 224
376145132Sanholt#define kf20__ 225
377145132Sanholt#define kf21__ 226
378183573Srnoland#define kf22__ 227
379183573Srnoland#define kf23__ 228
380183573Srnoland#define kf24__ 229
381183573Srnoland#define kf25__ 230
382145132Sanholt#define kf26__ 231
383145132Sanholt#define kf27__ 232
384145132Sanholt#define kf28__ 233
385182080Srnoland#define kf29__ 234
386157617Sanholt#define kf30__ 235
387157617Sanholt#define kf31__ 236
388145132Sanholt#define kf32__ 237
389157617Sanholt#define kf33__ 238
390182080Srnoland#define kf34__ 239
391145132Sanholt#define kf35__ 240
392145132Sanholt#define kf36__ 241
393145132Sanholt#define kf37__ 242
394183573Srnoland#define kf38__ 243
395183573Srnoland#define kf39__ 244
396183573Srnoland#define kf40__ 245
397145132Sanholt#define kf41__ 246
398145132Sanholt#define kf42__ 247
399182080Srnoland#define kf43__ 248
400145132Sanholt#define kf44__ 249
401145132Sanholt#define kf45__ 250
402183573Srnoland#define kf46__ 251
403183573Srnoland#define kf47__ 252
404183573Srnoland#define kf48__ 253
405183573Srnoland#define kf49__ 254
406145132Sanholt#define kf50__ 255
407145132Sanholt#define kf51__ 256
408145132Sanholt#define kf52__ 257
409182080Srnoland#define kf53__ 258
410145132Sanholt#define kf54__ 259
411145132Sanholt#define kf55__ 260
412162132Sanholt#define kf56__ 261
413162132Sanholt#define kf57__ 262
414162132Sanholt#define kf58__ 263
415162132Sanholt#define kf59__ 264
416162132Sanholt#define kf60__ 265
417162132Sanholt#define kf61__ 266
418162132Sanholt#define kf62__ 267
419162132Sanholt#define kf63__ 268
420162132Sanholt#define el1__ 269
421162132Sanholt#define mgc__ 270
422162132Sanholt#define smgl__ 271
423162132Sanholt#define smgr__ 272
424162132Sanholt
425162132Sanholt#ifdef CAP
426162132Sanholtchar *Boolean_names[] = {
427162132Sanholt"bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
428162132Sanholt"mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
429145132Sanholt};
430145132Sanholt
431145132Sanholtchar *Number_names[] = {
432145132Sanholt"co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
433162132Sanholt};
434182080Srnoland
435162132Sanholtchar *String_names[] = {
436157617Sanholt"bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
437189049Srnoland"do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
438157617Sanholt"dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
439157617Sanholt"mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
440157617Sanholt"ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
441157617Sanholt"kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
442190400Srnoland"k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
443189049Srnoland"kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
444182080Srnoland"ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
445182080Srnoland"l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
446162132Sanholt"AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
447157617Sanholt"rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
448182080Srnoland"st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
449189049Srnoland"K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
450157617Sanholt"XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
451157617Sanholt"@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
452157617Sanholt"%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
453157617Sanholt"&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
454157617Sanholt"#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
455182080Srnoland"%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
456145132Sanholt"F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
457145132Sanholt"FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
458145132Sanholt"FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
459145132Sanholt"Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
460145132Sanholt"Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
461145132Sanholt};
462182080Srnoland#endif
463182080Srnoland
464145132Sanholtchar *new_curse = "October 1987";
465145132Sanholt
466145132Sanholtchar in_buff[100];	/* buffer for ungetch			*/
467145132Sanholtint bufp;		/* next free position in in_buff	*/
468145132Sanholt
469145132Sanholtchar *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment	*/
470145132Sanholtint CFOUND = FALSE;
471145132Sanholtint Data_Line_len = 0;
472145132Sanholtint Max_Key_len;	/* max length of a sequence sent by a key	*/
473145132Sanholtchar *Data_Line = NULL;
474145132Sanholtchar *TERM_PATH = NULL;
475145132Sanholtchar *TERM_data_ptr = NULL;
476145132Sanholtchar *Term_File_name = NULL;	/* name of file containing terminal description	*/
477145132SanholtFILE *TFP;		/* file pointer to file with terminal des.	*/
478145132Sanholtint Fildes;		/* file descriptor for terminfo file		*/
479145132Sanholtint STAND = FALSE;	/* is standout mode activated?			*/
480145132Sanholtint TERM_INFO = FALSE;	/* is terminfo being used (TRUE), or termcap (FALSE) */
481145132Sanholtint Time_Out;	/* set when time elapsed while trying to read function key */
482145132Sanholtint Curr_x;		/* current x position on screen			*/
483182080Srnolandint Curr_y;		/* current y position on the screen		*/
484145132Sanholtint LINES;
485145132Sanholtint COLS;
486145132Sanholtint Move_It;		/* flag to move cursor if magic cookie glitch	*/
487189049Srnolandint initialized = FALSE;	/* tells whether new_curse is initialized	*/
488189049Srnolandfloat speed;
489145132Sanholtfloat chars_per_millisecond;
490145132Sanholtint Repaint_screen;	/* if an operation to change screen impossible, repaint screen	*/
491182080Srnolandint Intr;		/* storeage for interrupt character		*/
492145132Sanholtint Parity;		/* 0 = no parity, 1 = odd parity, 2 = even parity */
493145132Sanholtint Noblock;		/* for BSD systems				*/
494145132Sanholtint Num_bits;	/* number of bits per character	*/
495145132Sanholtint Flip_Bytes;	/* some systems have byte order reversed	*/
496145132Sanholtint interrupt_flag = FALSE;	/* set true if SIGWINCH received	*/
497182080Srnoland
498182080Srnoland#ifndef CAP
499145132Sanholtchar *Strings;
500145132Sanholt#endif
501145132Sanholt
502145132Sanholt#if !defined(TERMCAP)
503145132Sanholt#define TERMCAP "/etc/termcap"
504145132Sanholt#endif
505145132Sanholt
506145132Sanholtstruct KEYS {
507145132Sanholt	int length;	/* length of string sent by key			*/
508145132Sanholt	char *string;	/* string sent by key				*/
509145132Sanholt	int value;	/* CURSES value of key (9-bit)			*/
510145132Sanholt	};
511145132Sanholt
512145132Sanholtstruct KEY_STACK {
513189049Srnoland	struct KEYS *element;
514145132Sanholt	struct KEY_STACK *next;
515182080Srnoland	};
516182080Srnoland
517182080Srnolandstruct KEY_STACK *KEY_TOS = NULL;
518182080Srnolandstruct KEY_STACK *KEY_POINT;
519182080Srnoland
520182080Srnoland/*
521182080Srnoland |
522145132Sanholt |	Not all systems have good terminal information, so we will define
523189049Srnoland |	keyboard information here for the most widely used terminal type,
524189049Srnoland |	the VT100.
525189049Srnoland |
526189049Srnoland */
527189049Srnoland
528189049Srnolandstruct KEYS vt100[] =
529189049Srnoland	{
530145132Sanholt		{ 3, "\033[A", 0403 },	/* key up 	*/
531145132Sanholt		{ 3, "\033[C", 0405 },	/* key right	*/
532145132Sanholt		{ 3, "\033[D", 0404 },	/* key left	*/
533182080Srnoland
534189049Srnoland		{ 4, "\033[6~", 0522 },	/* key next page	*/
535145132Sanholt		{ 4, "\033[5~", 0523 },	/* key prev page	*/
536145132Sanholt		{ 3, "\033[[", 0550 },	/* key end	*/
537145132Sanholt		{ 3, "\033[@", 0406 },	/* key home	*/
538189049Srnoland		{ 4, "\033[2~", 0513 },	/* key insert char	*/
539145132Sanholt
540145132Sanholt		{ 3, "\033[y", 0410 },	/* key F0	*/
541145132Sanholt		{ 3, "\033[P", 0411 },	/* key F1	*/
542145132Sanholt		{ 3, "\033[Q", 0412 },	/* key F2	*/
543189049Srnoland		{ 3, "\033[R", 0413 },	/* key F3	*/
544189049Srnoland		{ 3, "\033[S", 0414 },	/* key F4	*/
545145132Sanholt		{ 3, "\033[t", 0415 },	/* key F5	*/
546189049Srnoland		{ 3, "\033[u", 0416 },	/* key F6	*/
547189049Srnoland		{ 3, "\033[v", 0417 },	/* key F7	*/
548189049Srnoland		{ 3, "\033[l", 0420 },	/* key F8	*/
549189049Srnoland		{ 3, "\033[w", 0421 },	/* key F9	*/
550145132Sanholt		{ 3, "\033[x", 0422 },	/* key F10	*/
551189049Srnoland
552189049Srnoland		{ 5, "\033[10~", 0410 },	/* key F0	*/
553189049Srnoland		{ 5, "\033[11~", 0411 },	/* key F1	*/
554189049Srnoland		{ 5, "\033[12~", 0412 },	/* key F2	*/
555189049Srnoland		{ 5, "\033[13~", 0413 },	/* key F3	*/
556189049Srnoland		{ 5, "\033[14~", 0414 },	/* key F4	*/
557189049Srnoland		{ 5, "\033[15~", 0415 },	/* key F5	*/
558189049Srnoland		{ 5, "\033[17~", 0416 },	/* key F6	*/
559189049Srnoland		{ 5, "\033[18~", 0417 },	/* key F7	*/
560189049Srnoland		{ 5, "\033[19~", 0420 },	/* key F8	*/
561189049Srnoland		{ 5, "\033[20~", 0421 },	/* key F9	*/
562189049Srnoland		{ 5, "\033[21~", 0422 },	/* key F10	*/
563189049Srnoland		{ 5, "\033[23~", 0423 },	/* key F11	*/
564145132Sanholt		{ 5, "\033[24~", 0424 },	/* key F12	*/
565189049Srnoland		{ 3, "\033[q", 0534 },	/* ka1 upper-left of keypad	*/
566189049Srnoland		{ 3, "\033[s", 0535 },	/* ka3 upper-right of keypad	*/
567145132Sanholt		{ 3, "\033[r", 0536 },	/* kb2 center of keypad	*/
568189049Srnoland 		{ 3, "\033[p", 0537 },	/* kc1 lower-left of keypad	*/
569189049Srnoland		{ 3, "\033[n", 0540 },	/* kc3 lower-right of keypad	*/
570145132Sanholt
571189049Srnoland		/*
572189049Srnoland		 |	The following are the same keys as above, but with
573189049Srnoland		 |	a different character following the escape char.
574189049Srnoland		 */
575145132Sanholt
576190400Srnoland		{ 3, "\033OA", 0403 },	/* key up 	*/
577190400Srnoland		{ 3, "\033OC", 0405 },	/* key right	*/
578190400Srnoland		{ 3, "\033OD", 0404 },	/* key left	*/
579190400Srnoland		{ 3, "\033OB", 0402 },	/* key down	*/
580145132Sanholt		{ 4, "\033O6~", 0522 },	/* key next page	*/
581145132Sanholt		{ 4, "\033O5~", 0523 },	/* key prev page	*/
582189049Srnoland		{ 3, "\033O[", 0550 },	/* key end	*/
583189049Srnoland		{ 3, "\033O@", 0406 },	/* key home	*/
584189049Srnoland		{ 4, "\033O2~", 0513 },	/* key insert char	*/
585189049Srnoland
586145132Sanholt		{ 3, "\033Oy", 0410 },	/* key F0	*/
587145132Sanholt		{ 3, "\033OP", 0411 },	/* key F1	*/
588189049Srnoland		{ 3, "\033OQ", 0412 },	/* key F2	*/
589189049Srnoland		{ 3, "\033OR", 0413 },	/* key F3	*/
590145132Sanholt		{ 3, "\033OS", 0414 },	/* key F4	*/
591145132Sanholt		{ 3, "\033Ot", 0415 },	/* key F5	*/
592189049Srnoland		{ 3, "\033Ou", 0416 },	/* key F6	*/
593145132Sanholt		{ 3, "\033Ov", 0417 },	/* key F7	*/
594145132Sanholt		{ 3, "\033Ol", 0420 },	/* key F8	*/
595145132Sanholt		{ 3, "\033Ow", 0421 },	/* key F9	*/
596145132Sanholt		{ 3, "\033Ox", 0422 },	/* key F10	*/
597189049Srnoland
598145132Sanholt		{ 5, "\033O10~", 0410 },	/* key F0	*/
599145132Sanholt		{ 5, "\033O11~", 0411 },	/* key F1	*/
600182080Srnoland		{ 5, "\033O12~", 0412 },	/* key F2	*/
601182080Srnoland		{ 5, "\033O13~", 0413 },	/* key F3	*/
602145132Sanholt		{ 5, "\033O14~", 0414 },	/* key F4	*/
603189049Srnoland		{ 5, "\033O15~", 0415 },	/* key F5	*/
604145132Sanholt		{ 5, "\033O17~", 0416 },	/* key F6	*/
605189049Srnoland		{ 5, "\033O18~", 0417 },	/* key F7	*/
606145132Sanholt		{ 5, "\033O19~", 0420 },	/* key F8	*/
607189049Srnoland		{ 5, "\033O20~", 0421 },	/* key F9	*/
608189049Srnoland		{ 5, "\033O21~", 0422 },	/* key F10	*/
609189049Srnoland		{ 5, "\033O23~", 0423 },	/* key F11	*/
610145132Sanholt		{ 5, "\033O24~", 0424 },	/* key F12	*/
611145132Sanholt		{ 3, "\033Oq", 0534 },	/* ka1 upper-left of keypad	*/
612182080Srnoland		{ 3, "\033Os", 0535 },	/* ka3 upper-right of keypad	*/
613182080Srnoland		{ 3, "\033Or", 0536 },	/* kb2 center of keypad	*/
614145132Sanholt 		{ 3, "\033Op", 0537 },	/* kc1 lower-left of keypad	*/
615145132Sanholt		{ 3, "\033On", 0540 },	/* kc3 lower-right of keypad	*/
616145132Sanholt
617145132Sanholt		{ 0, "", 0 }	/* end	*/
618182080Srnoland	};
619189049Srnoland
620145132Sanholtstruct Parameters {
621145132Sanholt	int value;
622145132Sanholt	struct Parameters *next;
623145132Sanholt	};
624182080Srnoland
625145132Sanholtint Key_vals[] = {
626145132Sanholt	0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
627145132Sanholt	0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
628182080Srnoland	0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
629145132Sanholt	0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
630189049Srnoland	0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
631145132Sanholt	0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
632189049Srnoland	0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
633189049Srnoland	0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
634182080Srnoland	0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
635189049Srnoland	0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
636189049Srnoland	0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
637182080Srnoland	0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
638189049Srnoland	0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
639189049Srnoland};
640189049Srnoland
641189049Srnolandint attributes_set[9];
642189049Srnoland
643189049Srnolandstatic int nc_attributes = 0;	/* global attributes for new_curse to observe */
644189049Srnoland
645189049Srnoland#ifdef SYS5
646189049Srnolandstruct termio Terminal;
647183573Srnolandstruct termio Saved_tty;
648182080Srnoland#else
649145132Sanholtstruct sgttyb Terminal;
650189049Srnolandstruct sgttyb Saved_tty;
651189049Srnoland#endif
652194996Srnoland
653189049Srnolandchar *tc_;
654189049Srnoland
655194996Srnolandint Booleans[128];
656194996Srnolandint Numbers[128];
657194996Srnolandchar *String_table[1024];
658145132Sanholt
659145132Sanholtint *virtual_lines;
660145132Sanholt
661182080Srnolandstatic char nc_scrolling_ability = FALSE;
662182080Srnoland
663145132Sanholtchar *terminfo_path[] = {
664145132Sanholt        "/usr/lib/terminfo",
665145132Sanholt        "/usr/share/lib/terminfo",
666145132Sanholt        "/usr/share/terminfo",
667182080Srnoland        NULL
668189049Srnoland        };
669145132Sanholt
670145132Sanholt#ifdef CAP
671145132Sanholt
672182080Srnoland#if defined(__STDC__) || defined(__cplusplus)
673145132Sanholt#define P_(s) s
674189049Srnoland#else
675145132Sanholt#define P_(s) ()
676189049Srnoland#endif /* __STDC__ */
677189049Srnoland
678189049Srnolandint tc_Get_int P_((int));
679189049Srnolandvoid CAP_PARSE P_((void));
680145132Sanholtvoid Find_term P_((void));
681189049Srnoland
682182080Srnoland#undef P_
683145132Sanholt
684189049Srnoland#endif /* CAP */
685189049Srnoland
686189049Srnoland
687189049Srnoland#ifndef __STDC__
688189049Srnoland#ifndef HAS_STDLIB
689189049Srnolandextern char *fgets();
690189049Srnolandextern char *malloc();
691189049Srnolandextern char *getenv();
692189049SrnolandFILE *fopen();			/* declaration for open function	*/
693189049Srnoland#endif /* HAS_STDLIB */
694189049Srnoland#endif /* __STDC__ */
695189049Srnoland
696189049Srnoland#ifdef SIGWINCH
697189049Srnoland
698189049Srnoland/*
699183573Srnoland |	Copy the contents of one window to another.
700182080Srnoland */
701194996Srnoland
702189049Srnolandvoid
703189049Srnolandcopy_window(origin, destination)
704189049SrnolandWINDOW *origin, *destination;
705189049Srnoland{
706189049Srnoland	int row, column;
707183573Srnoland	struct _line *orig, *dest;
708145132Sanholt
709183573Srnoland	orig = origin->first_line;
710145132Sanholt	dest = destination->first_line;
711183573Srnoland
712189049Srnoland	for (row = 0;
713189049Srnoland		row < (min(origin->Num_lines, destination->Num_lines));
714183573Srnoland			row++)
715145132Sanholt	{
716145132Sanholt		for (column = 0;
717189049Srnoland		    column < (min(origin->Num_cols, destination->Num_cols));
718189049Srnoland			column++)
719145132Sanholt		{
720189049Srnoland			dest->row[column] = orig->row[column];
721145132Sanholt			dest->attributes[column] = orig->attributes[column];
722189049Srnoland		}
723145132Sanholt		dest->changed = orig->changed;
724190021Srnoland		dest->scroll = orig->scroll;
725145132Sanholt		dest->last_char = min(orig->last_char, destination->Num_cols);
726189049Srnoland		orig = orig->next_screen;
727182080Srnoland		dest = dest->next_screen;
728189049Srnoland	}
729145132Sanholt	destination->LX = min((destination->Num_cols - 1), origin->LX);
730145132Sanholt	destination->LY = min((destination->Num_lines - 1), origin->LY);
731182080Srnoland	destination->Attrib = origin->Attrib;
732182080Srnoland	destination->scroll_up = origin->scroll_up;
733145132Sanholt	destination->scroll_down = origin->scroll_down;
734145132Sanholt	destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
735182080Srnoland}
736145132Sanholt
737145132Sanholtvoid
738145132Sanholtreinitscr(foo)
739182080Srnolandint foo;
740182080Srnoland{
741145132Sanholt	WINDOW *local_virt;
742145132Sanholt	WINDOW *local_std;
743182080Srnoland	WINDOW *local_cur;
744145132Sanholt
745183573Srnoland	signal(SIGWINCH, reinitscr);
746145132Sanholt#ifdef TIOCGWINSZ
747145132Sanholt	if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
748145132Sanholt	{
749145132Sanholt		if (ws.ws_row == LINES && ws.ws_col == COLS)
750157617Sanholt			return;
751157617Sanholt		if (ws.ws_row > 0)
752157617Sanholt			LINES = ws.ws_row;
753182080Srnoland		if (ws.ws_col > 0)
754182080Srnoland			COLS = ws.ws_col;
755182080Srnoland	}
756183573Srnoland#endif /* TIOCGWINSZ */
757184373Srnoland	local_virt = newwin(LINES, COLS, 0, 0);
758184373Srnoland	local_std = newwin(LINES, COLS, 0, 0);
759183573Srnoland	local_cur = newwin(LINES, COLS, 0, 0);
760145132Sanholt	copy_window(virtual_scr, local_virt);
761190021Srnoland	copy_window(stdscr, local_std);
762182080Srnoland	copy_window(curscr, local_cur);
763145132Sanholt	delwin(virtual_scr);
764145132Sanholt	delwin(stdscr);
765182080Srnoland	delwin(curscr);
766145132Sanholt	virtual_scr = local_virt;
767182080Srnoland	stdscr = local_std;
768145132Sanholt	curscr = local_cur;
769145132Sanholt	free(virtual_lines);
770145132Sanholt	virtual_lines = (int *) malloc(LINES * (sizeof(int)));
771145132Sanholt	interrupt_flag = TRUE;
772145132Sanholt}
773182080Srnoland#endif /* SIGWINCH */
774182080Srnoland
775145132Sanholtvoid
776145132Sanholtinitscr()		/* initialize terminal for operations	*/
777182080Srnoland{
778145132Sanholt	int value;
779145132Sanholt	int counter;
780182080Srnoland	char *lines_string;
781182080Srnoland	char *columns_string;
782145132Sanholt#ifdef CAP
783145132Sanholt	char *pointer;
784182080Srnoland#endif /* CAP */
785145132Sanholt
786145132Sanholt#ifdef DIAG
787145132Sanholtprintf("starting initscr \n");fflush(stdout);
788182080Srnoland#endif
789145132Sanholt	if (initialized)
790145132Sanholt		return;
791182080Srnoland#ifdef BSD_SELECT
792145132Sanholt	setbuf(stdin, NULL);
793145132Sanholt#endif /* BSD_SELECT */
794190021Srnoland	Flip_Bytes = FALSE;
795182080Srnoland	Parity = 0;
796145132Sanholt	Time_Out = FALSE;
797145132Sanholt	bufp = 0;
798145132Sanholt	Move_It = FALSE;
799145132Sanholt	Noblock = FALSE;
800145132Sanholt#ifdef SYS5
801182080Srnoland	value = ioctl(0, TCGETA, &Terminal);
802182080Srnoland	if (Terminal.c_cflag & PARENB)
803182080Srnoland	{
804182080Srnoland		if (Terminal.c_cflag & PARENB)
805182080Srnoland			Parity = 1;
806182080Srnoland		else
807182080Srnoland			Parity = 2;
808182080Srnoland	}
809182080Srnoland	if ((Terminal.c_cflag & CS8) == CS8)
810182080Srnoland	{
811182080Srnoland		Num_bits = 8;
812182080Srnoland	}
813182080Srnoland	else if ((Terminal.c_cflag & CS7) == CS7)
814189049Srnoland		Num_bits = 7;
815182080Srnoland	else if ((Terminal.c_cflag & CS6) == CS6)
816182080Srnoland		Num_bits = 6;
817182080Srnoland	else
818182080Srnoland		Num_bits = 5;
819182080Srnoland	value = Terminal.c_cflag & 037;
820182080Srnoland	switch (value) {
821182080Srnoland	case 01:	speed = 50.0;
822182080Srnoland		break;
823182080Srnoland	case 02:	speed = 75.0;
824182080Srnoland		break;
825190021Srnoland	case 03:	speed = 110.0;
826207066Srnoland		break;
827182080Srnoland	case 04:	speed = 134.5;
828182080Srnoland		break;
829182080Srnoland	case 05:	speed = 150.0;
830182080Srnoland		break;
831182080Srnoland	case 06:	speed = 200.0;
832182080Srnoland		break;
833207066Srnoland	case 07:	speed = 300.0;
834182080Srnoland		break;
835182080Srnoland	case 010:	speed = 600.0;
836182080Srnoland		break;
837189049Srnoland	case 011:	speed = 900.0;
838182080Srnoland		break;
839182080Srnoland	case 012:	speed = 1200.0;
840182080Srnoland		break;
841182080Srnoland	case 013:	speed = 1800.0;
842182080Srnoland		break;
843182080Srnoland	case 014:	speed = 2400.0;
844182080Srnoland		break;
845189049Srnoland	case 015:	speed = 3600.0;
846182080Srnoland		break;
847182080Srnoland	case 016:	speed = 4800.0;
848182080Srnoland		break;
849152909Sanholt	case 017:	speed = 7200.0;
850152909Sanholt		break;
851152909Sanholt	case 020:	speed = 9600.0;
852152909Sanholt		break;
853152909Sanholt	case 021:	speed = 19200.0;
854152909Sanholt		break;
855152909Sanholt	case 022:	speed = 38400.0;
856182080Srnoland		break;
857182080Srnoland	default:	speed = 0.0;
858182080Srnoland	}
859182080Srnoland#else
860182080Srnoland	value = ioctl(0, TIOCGETP, &Terminal);
861182080Srnoland	if (Terminal.sg_flags & EVENP)
862182080Srnoland		Parity = 2;
863183573Srnoland	else if (Terminal.sg_flags & ODDP)
864182080Srnoland		Parity = 1;
865182080Srnoland	value = Terminal.sg_ospeed;
866182080Srnoland	switch (value) {
867182080Srnoland	case 01:	speed = 50.0;
868182080Srnoland		break;
869182080Srnoland	case 02:	speed = 75.0;
870189049Srnoland		break;
871189054Srnoland	case 03:	speed = 110.0;
872194540Srnoland		break;
873194540Srnoland	case 04:	speed = 134.5;
874194540Srnoland		break;
875194540Srnoland	case 05:	speed = 150.0;
876189054Srnoland		break;
877194540Srnoland	case 06:	speed = 200.0;
878194540Srnoland		break;
879189054Srnoland	case 07:	speed = 300.0;
880183573Srnoland		break;
881183573Srnoland	case 010:	speed = 600.0;
882183573Srnoland		break;
883183573Srnoland	case 011:	speed = 1200.0;
884183573Srnoland		break;
885189049Srnoland	case 012:	speed = 1800.0;
886190021Srnoland		break;
887190021Srnoland	case 013:	speed = 2400.0;
888190021Srnoland		break;
889190021Srnoland	case 014:	speed = 4800.0;
890183573Srnoland		break;
891190021Srnoland	case 015:	speed = 9600.0;
892183573Srnoland		break;
893189049Srnoland	default:	speed = 0.0;
894189049Srnoland	}
895189049Srnoland#endif
896189049Srnoland	chars_per_millisecond = (0.001 * speed) / 8.0;
897189049Srnoland	TERMINAL_TYPE = getenv("TERM");
898189049Srnoland	if (TERMINAL_TYPE == NULL)
899189049Srnoland	{
900189049Srnoland		printf("unknown terminal type\n");
901189049Srnoland		exit(0);
902189049Srnoland	}
903189049Srnoland#ifndef CAP
904189049Srnoland	Fildes = -1;
905189049Srnoland	TERM_PATH = getenv("TERMINFO");
906189049Srnoland	if (TERM_PATH != NULL)
907183573Srnoland	{
908189049Srnoland		Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
909189049Srnoland		Term_File_name = malloc(Data_Line_len);
910189049Srnoland		sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
911190021Srnoland		Fildes = open(Term_File_name, O_RDONLY);
912189049Srnoland		if (Fildes == -1)
913189130Srnoland		{
914189130Srnoland        		sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
915189130Srnoland        		Fildes = open(Term_File_name, O_RDONLY);
916189130Srnoland		}
917189130Srnoland	}
918189130Srnoland	counter = 0;
919189130Srnoland	while ((Fildes == -1) && (terminfo_path[counter] != NULL))
920182080Srnoland	{
921182080Srnoland		TERM_PATH = terminfo_path[counter];
922182080Srnoland		Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
923182080Srnoland		Term_File_name = malloc(Data_Line_len);
924182080Srnoland		sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
925182080Srnoland		Fildes = open(Term_File_name, O_RDONLY);
926182080Srnoland		if (Fildes == -1)
927189049Srnoland		{
928182080Srnoland        		sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
929189049Srnoland        		Fildes = open(Term_File_name, O_RDONLY);
930182080Srnoland		}
931182080Srnoland		counter++;
932182080Srnoland	}
933189049Srnoland	if (Fildes == -1)
934182080Srnoland	{
935182080Srnoland		free(Term_File_name);
936182080Srnoland		Term_File_name = NULL;
937182080Srnoland	}
938152909Sanholt	else
939152909Sanholt		TERM_INFO = INFO_PARSE();
940152909Sanholt#else
941183573Srnoland	/*
942183573Srnoland	 |	termcap information can be in the TERMCAP env variable, if so
943183573Srnoland	 |	use that, otherwise check the /etc/termcap file
944183573Srnoland	 */
945183573Srnoland	if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
946183573Srnoland	{
947183573Srnoland		if (*Term_File_name != '/')
948183573Srnoland			Term_File_name = TERMCAP;
949183573Srnoland	}
950183573Srnoland	else
951183573Srnoland	{
952183573Srnoland		Term_File_name = TERMCAP;
953183573Srnoland	}
954183573Srnoland	if ((TFP = fopen(Term_File_name, "r")) == NULL)
955183573Srnoland	{
956183573Srnoland		printf("unable to open %s file \n", TERMCAP);
957183573Srnoland		exit(0);
958183573Srnoland	}
959183573Srnoland 	for (value = 0; value < 1024; value++)
960189049Srnoland		String_table[value] = NULL;
961189049Srnoland	for (value = 0; value < 128; value++)
962189049Srnoland		Booleans[value] = 0;
963189049Srnoland	for (value = 0; value < 128; value++)
964189049Srnoland		Numbers[value] = 0;
965189049Srnoland	Data_Line = malloc(512);
966189049Srnoland	if (pointer && *pointer != '/')
967189049Srnoland	{
968189049Srnoland		TERM_data_ptr = pointer;
969189049Srnoland		CAP_PARSE();
970189049Srnoland	}
971189049Srnoland	else
972189049Srnoland	{
973189049Srnoland		Find_term();
974189049Srnoland		CAP_PARSE();
975182080Srnoland	}
976145132Sanholt#endif
977182080Srnoland	if (String_table[pc__] == NULL)
978182080Srnoland		String_table[pc__] = "\0";
979145132Sanholt	if ((String_table[cm__] == NULL) || (Booleans[hc__]))
980145132Sanholt	{
981183573Srnoland		fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
982183573Srnoland		exit(0);
983183573Srnoland	}
984183573Srnoland	Key_Get();
985183573Srnoland	keys_vt100();
986183573Srnoland	LINES = Numbers[li__];
987183573Srnoland	COLS = Numbers[co__];
988182080Srnoland	if ((lines_string = getenv("LINES")) != NULL)
989182080Srnoland	{
990182080Srnoland		value = atoi(lines_string);
991182080Srnoland		if (value > 0)
992182080Srnoland			LINES = value;
993182080Srnoland	}
994182080Srnoland	if ((columns_string = getenv("COLUMNS")) != NULL)
995182080Srnoland	{
996182080Srnoland		value = atoi(columns_string);
997182080Srnoland		if (value > 0)
998182080Srnoland			COLS = value;
999182080Srnoland	}
1000182080Srnoland#ifdef TIOCGWINSZ
1001182080Srnoland	/*
1002182080Srnoland	 |	get the window size
1003182080Srnoland	 */
1004182080Srnoland	if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1005184263Srnoland	{
1006183573Srnoland		if (ws.ws_row > 0)
1007189049Srnoland			LINES = ws.ws_row;
1008183573Srnoland		if (ws.ws_col > 0)
1009183573Srnoland			COLS = ws.ws_col;
1010183573Srnoland	}
1011183573Srnoland#endif
1012183573Srnoland	virtual_scr = newwin(LINES, COLS, 0, 0);
1013189049Srnoland	stdscr = newwin(LINES, COLS, 0, 0);
1014189049Srnoland	curscr = newwin(LINES, COLS, 0, 0);
1015183573Srnoland	wmove(stdscr, 0, 0);
1016183573Srnoland	werase(stdscr);
1017183573Srnoland	Repaint_screen = TRUE;
1018183573Srnoland	initialized = TRUE;
1019183573Srnoland	virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1020183573Srnoland
1021183573Srnoland#ifdef SIGWINCH
1022183573Srnoland	/*
1023183573Srnoland	 |	reset size of windows and LINES and COLS if term window
1024145132Sanholt	 |	changes size
1025145132Sanholt	 */
1026145132Sanholt	signal(SIGWINCH, reinitscr);
1027152909Sanholt#endif /* SIGWINCH */
1028152909Sanholt
1029152909Sanholt	/*
1030152909Sanholt	 |	check if scrolling is available
1031152909Sanholt	 */
1032152909Sanholt
1033152909Sanholt	nc_scrolling_ability = ((String_table[al__] != NULL) &&
1034152909Sanholt				(String_table[dl__])) || ((String_table[cs__])
1035152909Sanholt				&& (String_table[sr__]));
1036152909Sanholt
1037152909Sanholt}
1038152909Sanholt
1039182080Srnoland#ifndef CAP
1040152909Sanholtint
1041152909SanholtGet_int()		/* get a two-byte integer from the terminfo file */
1042152909Sanholt{
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
1061int
1062INFO_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
1144int
1145AtoI()		/* 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
1158void
1159Key_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
1237void
1238keys_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
1260char *
1261String_Get(param)		/* read the string */
1262char *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
1341int
1342tc_Get_int(param)		/* read the integer			*/
1343int 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
1363void
1364Find_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
1400void
1401CAP_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
1462struct _line *
1463Screenalloc(columns)
1464int 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
1488WINDOW *newwin(lines, cols, start_l, start_c)
1489int lines, cols;	/* number of lines and columns to be in window	*/
1490int 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
1526void
1527Cap_Out(string, p_list, place)	/* interpret the output string if necessary */
1528char *string;
1529int p_list[];			/* stack of values	*/
1530int 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
1642int
1643Operation(Temp_Stack, place)	/* handle conditional operations	*/
1644int Temp_Stack[];
1645int 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
1827void
1828Info_Out(string, p_list, place)	/* interpret the output string if necessary */
1829char *string;
1830int p_list[];
1831int 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
2022void
2023wmove(window, row, column)	/* move cursor to indicated position in window */
2024WINDOW *window;
2025int 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
2034void
2035clear_line(line, column, cols)
2036struct _line *line;
2037int column;
2038int 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
2056void
2057werase(window)			/* clear the specified window		*/
2058WINDOW *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
2069void
2070wclrtoeol(window)	/* erase from current cursor position to end of line */
2071WINDOW *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
2084void
2085wrefresh(window)		/* flush all previous output		*/
2086WINDOW *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
2123void
2124touchwin(window)
2125WINDOW *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
2138void
2139wnoutrefresh(window)
2140WINDOW *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
2210void
2211flushinp()			/* flush input				*/
2212{
2213}
2214
2215void
2216ungetch(c)			/* push a character back on input	*/
2217int c;
2218{
2219	if (bufp < 100)
2220		in_buff[bufp++] = c;
2221}
2222
2223#ifdef BSD_SELECT
2224int
2225timed_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
2256int
2257wgetch(window)			/* get character from specified window	*/
2258WINDOW *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
2311void
2312Clear(arg)		/* notify that time out has occurred	*/
2313int arg;
2314{
2315	Time_Out = TRUE;
2316#ifdef DEBUG
2317fprintf(stderr, "inside Clear()\n");
2318fflush(stderr);
2319#endif /* DEBUG */
2320}
2321#endif /* BSD_SELECT */
2322
2323int
2324Get_key(first_char)			/* try to decode key sequence	*/
2325int 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
2363fprintf(stderr, "back in GetKey()\n");
2364fflush(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
2403fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2404#endif
2405				ungetch(string[Count]);
2406			}
2407		}
2408		return(first_char);
2409	}
2410}
2411
2412void
2413waddch(window, c)	/* output the character in the specified window	*/
2414WINDOW *window;
2415int 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
2490void
2491winsertln(window)	/* insert a blank line into the specified window */
2492WINDOW *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
2539void
2540wdeleteln(window)	/* delete a line in the specified window */
2541WINDOW *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
2593void
2594wclrtobot(window)	/* delete from current position to end of the window */
2595WINDOW *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
2614void
2615wstandout(window)	/* begin standout mode in window	*/
2616WINDOW *window;
2617{
2618	if (Numbers[sg__] < 1)	/* if not magic cookie glitch	*/
2619		window->Attrib |= A_STANDOUT;
2620}
2621
2622void
2623wstandend(window)	/* end standout mode in window	*/
2624WINDOW *window;
2625{
2626	window->Attrib &= ~A_STANDOUT;
2627}
2628
2629void
2630waddstr(window, string)	/* write 'string' in window	*/
2631WINDOW *window;
2632char *string;
2633{
2634	char *wstring;
2635
2636	for (wstring = string; *wstring != '\0'; wstring++)
2637		waddch(window, *wstring);
2638}
2639
2640void
2641clearok(window, flag)	/* erase screen and redraw at next refresh	*/
2642WINDOW *window;
2643int flag;
2644{
2645	Repaint_screen = TRUE;
2646}
2647
2648
2649void
2650echo()			/* 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
2663void
2664noecho()		/* 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
2677void
2678raw()			/* 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
2705void
2706noraw()			/* 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
2725void
2726nl()
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
2736void
2737nonl()
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
2748void
2749saveterm()
2750{
2751}
2752
2753void
2754fixterm()
2755{
2756}
2757
2758void
2759resetterm()
2760{
2761}
2762
2763void
2764nodelay(window, flag)
2765WINDOW *window;
2766int flag;
2767{
2768}
2769
2770void
2771idlok(window, flag)
2772WINDOW *window;
2773int flag;
2774{
2775}
2776
2777void
2778keypad(window, flag)
2779WINDOW *window;
2780int 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
2788void
2789savetty()		/* 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
2800void
2801resetty()		/* 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
2812void
2813endwin()		/* 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
2829void
2830delwin(window)		/* delete the window structure			*/
2831WINDOW *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__
2854void
2855wprintw(va_alist)
2856va_dcl
2857#else /* __STDC__ */
2858void
2859wprintw(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
2929void
2930iout(window, value)	/* output characters		*/
2931WINDOW *window;
2932int value;
2933{
2934	int i;
2935
2936	if ((i = value / 10) != 0)
2937		iout(window, i);
2938	waddch(window, ((value % 10) + '0'));
2939}
2940
2941int
2942Comp_line(line1, line2)		/* compare lines	*/
2943struct _line *line1;
2944struct _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
2971struct _line *
2972Insert_line(row, end_row, window)	/* insert line into screen */
2973int row;
2974int end_row;
2975WINDOW *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
3033struct _line *
3034Delete_line(row, end_row, window)	/* delete a line on screen */
3035int row;
3036int end_row;
3037WINDOW *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
3104void
3105CLEAR_TO_EOL(window, row, column)
3106WINDOW *window;
3107int 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
3140int
3141check_delete(window, line, offset, pointer_new, pointer_old)
3142WINDOW *window;
3143int line, offset;
3144struct _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
3192int
3193check_insert(window, line, offset, pointer_new, pointer_old)
3194WINDOW *window;
3195int line, offset;
3196struct _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
3258void
3259doupdate()
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
3666void
3667Position(window, row, col)	/* position the cursor for output on the screen	*/
3668WINDOW *window;
3669int row;
3670int 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
3696void
3697Char_del(line, attrib, offset, maxlen)	/* delete chars from line	*/
3698char *line;
3699char *attrib;
3700int offset;
3701int 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
3713void
3714Char_ins(line, attrib, newc, newatt, offset, maxlen)	/* insert chars in line	*/
3715char *line;
3716char *attrib;
3717char newc;
3718char newatt;
3719int offset;
3720int 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
3737void
3738attribute_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
3749void
3750attribute_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
3763void
3764Char_out(newc, newatt, line, attrib, offset)	/* output character with proper attribute	*/
3765char newc;
3766char newatt;
3767char *line;
3768char *attrib;
3769int 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
3806void
3807nc_setattrib(flag)
3808int flag;
3809{
3810	nc_attributes |= flag;
3811}
3812
3813void
3814nc_clearattrib(flag)
3815int flag;
3816{
3817	nc_attributes &= ~flag;
3818}
3819
3820