1192830Sed/*
2192830Sed |	new_curse.c
3192830Sed |
4192830Sed |	A subset of curses developed for use with ae.
5192830Sed |
6192830Sed |	written by Hugh Mahon
7192830Sed |
8192914Sed |      Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon
9192914Sed |      All rights reserved.
10192914Sed |
11192914Sed |      Redistribution and use in source and binary forms, with or without
12192914Sed |      modification, are permitted provided that the following conditions
13192914Sed |      are met:
14192914Sed |
15192914Sed |          * Redistributions of source code must retain the above copyright
16192914Sed |            notice, this list of conditions and the following disclaimer.
17192914Sed |          * Redistributions in binary form must reproduce the above
18192914Sed |            copyright notice, this list of conditions and the following
19192914Sed |            disclaimer in the documentation and/or other materials provided
20192914Sed |            with the distribution.
21192914Sed |
22192914Sed |      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23192914Sed |      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24192914Sed |      LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25192914Sed |      FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26192914Sed |      COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27192914Sed |      INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28192914Sed |      BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29192914Sed |      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30192914Sed |      CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31192914Sed |      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32192914Sed |      ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33192914Sed |      POSSIBILITY OF SUCH DAMAGE.
34192830Sed |
35192914Sed |
36192830Sed |	All are rights reserved.
37192830Sed |
38192914Sed |	$Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh Exp $
39192830Sed |
40192830Sed */
41192830Sed
42192914Sedchar *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon",
43192830Sed				"All rights are reserved."};
44192830Sed
45192914Sedchar * new_curse_name= "@(#) new_curse.c $Revision: 1.54 $";
46192830Sed
47192830Sed#include "new_curse.h"
48192830Sed#include <signal.h>
49192830Sed#include <fcntl.h>
50192830Sed
51192830Sed#ifdef SYS5
52192830Sed#include <string.h>
53192830Sed#else
54192830Sed#include <strings.h>
55192830Sed#endif
56192830Sed
57192830Sed#ifdef BSD_SELECT
58192830Sed#include <sys/types.h>
59192830Sed#include <sys/time.h>
60192830Sed
61192830Sed#ifdef SLCT_HDR
62192830Sed#include <sys/select.h>  /* on AIX */
63192830Sed#endif /* SLCT_HDR */
64192830Sed
65192830Sed#endif /* BSD_SELECT */
66192830Sed
67192830Sed#ifdef HAS_STDLIB
68192830Sed#include <stdlib.h>
69192830Sed#endif
70192830Sed
71192830Sed#if defined(__STDC__)
72192830Sed#include <stdarg.h>
73192830Sed#else
74192830Sed#include <varargs.h>
75192830Sed#endif
76192830Sed
77192830Sed#ifdef HAS_UNISTD
78192830Sed#include <unistd.h>
79192830Sed#endif
80192830Sed
81192830Sed#ifdef HAS_SYS_IOCTL
82192830Sed#include <sys/ioctl.h>
83192830Sed#endif
84192830Sed
85192830Sed
86192830SedWINDOW *curscr;
87192830Sedstatic WINDOW *virtual_scr;
88192830SedWINDOW *stdscr;
89192830SedWINDOW *last_window_refreshed;
90192830Sed
91192830Sed#ifdef TIOCGWINSZ
92192830Sed	struct winsize ws;
93192830Sed#endif
94192830Sed
95192830Sed#define min(a, b)	(a < b ? a : b)
96192830Sed#define highbitset(a)	((a) & 0x80)
97192830Sed
98192830Sed#ifndef CAP
99192830Sed#define String_Out(table, stack, place) Info_Out(table, stack, place)
100192830Sed#else
101192830Sed#define String_Out(table, stack, place) Cap_Out(table, stack, place)
102192830Sed#endif
103192830Sed
104192830Sed#define bw__ 0	/* booleans	*/
105192830Sed#define am__ 1
106192830Sed#define xb__ 2
107192830Sed#define xs__ 3	/* hp glitch (standout not erased by overwrite)	*/
108192830Sed#define xn__ 4
109192830Sed#define eo__ 5
110192830Sed#define gn__ 6	/* generic type terminal	*/
111192830Sed#define hc__ 7	/* hardcopy terminal		*/
112192830Sed#define km__ 8
113192830Sed#define hs__ 9
114192830Sed#define in__ 10
115192830Sed#define da__ 11
116192830Sed#define db__ 12
117192830Sed#define mi__ 13	/* safe to move during insert mode	*/
118192830Sed#define ms__ 14	/* safe to move during standout mode	*/
119192830Sed#define os__ 15
120192830Sed#define es__ 16
121192830Sed#define xt__ 17
122192830Sed#define hz__ 18	/* hazeltine glitch	*/
123192830Sed#define ul__ 19
124192830Sed#define xo__ 20
125192830Sed#define chts__ 21
126192830Sed#define nxon__ 22
127192830Sed#define nrrmc__ 23
128192830Sed#define npc__ 24
129192830Sed#define mc5i__ 25
130192830Sed
131192830Sed#define co__ 0	/* number of columns	*/	/* numbers		*/
132192830Sed#define it__ 1	/* spaces per tab	*/
133192830Sed#define li__ 2	/* number of lines	*/
134192830Sed#define lm__ 3
135192830Sed#define sg__ 4	/* magic cookie glitch	*/
136192830Sed#define pb__ 5
137192830Sed#define vt__ 6
138192830Sed#define ws__ 7
139192830Sed
140192830Sed#define cols__ 0
141192830Sed#define lines__ 2
142192830Sed#define xmc__ 4
143192830Sed#define vt__ 6
144192830Sed#define wsl__ 7
145192830Sed#define nlab__ 8
146192830Sed#define lh__ 9
147192830Sed#define lw__ 10
148192830Sed
149192830Sed#define bt__ 0	/* back tab		*/	/* strings	*/
150192830Sed#define bl__ 1	/* bell			*/
151192830Sed#define cr__ 2	/* carriage return	*/
152192830Sed#define cs__ 3	/* change scroll region	*/
153192830Sed#define ct__ 4	/* clear all tab stops	*/
154192830Sed#define cl__ 5	/* clear screen and home cursor	*/
155192830Sed#define ce__ 6	/* clear to end of line	*/
156192830Sed#define cd__ 7	/* clear to end of display	*/
157192830Sed#define ch__ 8	/* set cursor column	*/
158192830Sed#define CC__ 9	/* term, settable cmd char in 	*/
159192830Sed#define cm__ 10	/* screen rel cursor motion, row, column	*/
160192830Sed#define do__ 11	/* down one line	*/
161192830Sed#define ho__ 12	/* home cursor	*/
162192830Sed#define vi__ 13	/* make cursor invisible	*/
163192830Sed#define le__ 14	/* move cursor left one space	*/
164192830Sed#define CM__ 15	/* memory rel cursor addressing	*/
165192830Sed#define ve__ 16	/* make cursor appear normal	*/
166192830Sed#define nd__ 17	/* non-destructive space (cursor right)	*/
167192830Sed#define ll__ 18	/* last line, first col	*/
168192830Sed#define up__ 19	/* cursor up		*/
169192830Sed#define vs__ 20
170192830Sed#define dc__ 21	/* delete character	*/
171192830Sed#define dl__ 22	/* delete line		*/
172192830Sed#define ds__ 23
173192830Sed#define hd__ 24
174192830Sed#define as__ 25
175192830Sed#define mb__ 26
176192830Sed#define md__ 27	/* turn on bold		*/
177192830Sed#define ti__ 28
178192830Sed#define dm__ 29	/* turn on delete mode	*/
179192830Sed#define mh__ 30	/* half bright mode	*/
180192830Sed#define im__ 31	/* insert mode		*/
181192830Sed#define mk__ 32
182192830Sed#define mp__ 33
183192830Sed#define mr__ 34
184192830Sed#define so__ 35	/* enter standout mode	*/
185192830Sed#define us__ 36
186192830Sed#define ec__ 37
187192830Sed#define ae__ 38
188192830Sed#define me__ 39
189192830Sed#define te__ 40
190192830Sed#define ed__ 41
191192830Sed#define ei__ 42	/* exit insert mode	*/
192192830Sed#define se__ 43	/* exit standout mode	*/
193192830Sed#define ue__ 44
194192830Sed#define vb__ 45
195192830Sed#define ff__ 46
196192830Sed#define fs__ 47
197192830Sed#define i1__ 48
198192830Sed#define i2__ 49
199192830Sed#define i3__ 50
200192830Sed#define if__ 51
201192830Sed#define ic__ 52
202192830Sed#define al__ 53
203192830Sed#define ip__ 54
204192830Sed#define kb__ 55		/* backspace key	*/
205192830Sed#define ka__ 56
206192830Sed#define kC__ 57
207192830Sed#define kt__ 58
208192830Sed#define kD__ 59
209192830Sed#define kL__ 60
210192830Sed#define kd__ 61
211192830Sed#define kM__ 62
212192830Sed#define kE__ 63
213192830Sed#define kS__ 64
214192830Sed#define k0__ 65
215192830Sed#define k1__ 66
216192830Sed#define kf10__ 67
217192830Sed#define k2__ 68
218192830Sed#define k3__ 69
219192830Sed#define k4__ 70
220192830Sed#define k5__ 71
221192830Sed#define k6__ 72
222192830Sed#define k7__ 73
223192830Sed#define k8__ 74
224192830Sed#define k9__ 75
225192830Sed#define kh__ 76
226192830Sed#define kI__ 77
227192830Sed#define kA__ 78
228192830Sed#define kl__ 79
229192830Sed#define kH__ 80
230192830Sed#define kN__ 81
231192830Sed#define kP__ 82
232192830Sed#define kr__ 83
233192830Sed#define kF__ 84
234192830Sed#define kR__ 85
235192830Sed#define kT__ 86
236192830Sed#define ku__ 87	/* key up	*/
237192830Sed#define ke__ 88
238192830Sed#define ks__ 89
239192830Sed#define l0__ 90
240192830Sed#define l1__ 91
241192830Sed#define la__ 92
242192830Sed#define l2__ 93
243192830Sed#define l3__ 94
244192830Sed#define l4__ 95
245192830Sed#define l5__ 96
246192830Sed#define l6__ 97
247192830Sed#define l7__ 98
248192830Sed#define l8__ 99
249192830Sed#define l9__ 100
250192830Sed#define mo__ 101
251192830Sed#define mm__ 102
252192830Sed#define nw__ 103
253192830Sed#define pc__ 104
254192830Sed#define DC__ 105
255192830Sed#define DL__ 106
256192830Sed#define DO__ 107
257192830Sed#define IC__ 118
258192830Sed#define SF__ 109
259192830Sed#define AL__ 110
260192830Sed#define LE__ 111
261192830Sed#define RI__ 112
262192830Sed#define SR__ 113
263192830Sed#define UP__ 114
264192830Sed#define pk__ 115
265192830Sed#define pl__ 116
266192830Sed#define px__ 117
267192830Sed#define ps__ 118
268192830Sed#define pf__ 119
269192830Sed#define po__ 120
270192830Sed#define rp__ 121
271192830Sed#define r1__ 122
272192830Sed#define r2__ 123
273192830Sed#define r3__ 124
274192830Sed#define rf__ 125
275192830Sed#define rc__ 126
276192830Sed#define cv__ 127
277192830Sed#define sc__ 128
278192830Sed#define sf__ 129
279192830Sed#define sr__ 130
280192830Sed#define sa__ 131	/* sgr	*/
281192830Sed#define st__ 132
282192830Sed#define wi__ 133
283192830Sed#define ta__ 134
284192830Sed#define ts__ 135
285192830Sed#define uc__ 136
286192830Sed#define hu__ 137
287192830Sed#define iP__ 138
288192830Sed#define K1__ 139
289192830Sed#define K2__ 140
290192830Sed#define K3__ 141
291192830Sed#define K4__ 142
292192830Sed#define K5__ 143
293192830Sed#define pO__ 144
294192830Sed#define ml__ 145
295192830Sed#define mu__ 146
296192830Sed#define rmp__ 145
297192830Sed#define acsc__ 146
298192830Sed#define pln__ 147
299192830Sed#define kcbt__ 148
300192830Sed#define smxon__ 149
301192830Sed#define rmxon__ 150
302192830Sed#define smam__ 151
303192830Sed#define rmam__ 152
304192830Sed#define xonc__ 153
305192830Sed#define xoffc__ 154
306192830Sed#define enacs__ 155
307192830Sed#define smln__ 156
308192830Sed#define rmln__ 157
309192830Sed#define kbeg__ 158
310192830Sed#define kcan__ 159
311192830Sed#define kclo__ 160
312192830Sed#define kcmd__ 161
313192830Sed#define kcpy__ 162
314192830Sed#define kcrt__ 163
315192830Sed#define kend__ 164
316192830Sed#define kent__ 165
317192830Sed#define kext__ 166
318192830Sed#define kfnd__ 167
319192830Sed#define khlp__ 168
320192830Sed#define kmrk__ 169
321192830Sed#define kmsg__ 170
322192830Sed#define kmov__ 171
323192830Sed#define knxt__ 172
324192830Sed#define kopn__ 173
325192830Sed#define kopt__ 174
326192830Sed#define kprv__ 175
327192830Sed#define kprt__ 176
328192830Sed#define krdo__ 177
329192830Sed#define kref__ 178
330192830Sed#define krfr__ 179
331192830Sed#define krpl__ 180
332192830Sed#define krst__ 181
333192830Sed#define kres__ 182
334192830Sed#define ksav__ 183
335192830Sed#define kspd__ 184
336192830Sed#define kund__ 185
337192830Sed#define kBEG__ 186
338192830Sed#define kCAN__ 187
339192830Sed#define kCMD__ 188
340192830Sed#define kCPY__ 189
341192830Sed#define kCRT__ 190
342192830Sed#define kDC__ 191
343192830Sed#define kDL__ 192
344192830Sed#define kslt__ 193
345192830Sed#define kEND__ 194
346192830Sed#define kEOL__ 195
347192830Sed#define kEXT__ 196
348192830Sed#define kFND__ 197
349192830Sed#define kHLP__ 198
350192830Sed#define kHOM__ 199
351192830Sed#define kIC__ 200
352192830Sed#define kLFT__ 201
353192830Sed#define kMSG__ 202
354192830Sed#define kMOV__ 203
355192830Sed#define kNXT__ 204
356192830Sed#define kOPT__ 205
357192830Sed#define kPRV__ 206
358192830Sed#define kPRT__ 207
359192830Sed#define kRDO__ 208
360192830Sed#define kRPL__ 209
361192830Sed#define kRIT__ 210
362192830Sed#define kRES__ 211
363192830Sed#define kSAV__ 212
364192830Sed#define kSPD__ 213
365192830Sed#define kUND__ 214
366192830Sed#define rfi__ 215
367192830Sed#define kf11__ 216
368192830Sed#define kf12__ 217
369192830Sed#define kf13__ 218
370192830Sed#define kf14__ 219
371192830Sed#define kf15__ 220
372192830Sed#define kf16__ 221
373192830Sed#define kf17__ 222
374192830Sed#define kf18__ 223
375192830Sed#define kf19__ 224
376192830Sed#define kf20__ 225
377192830Sed#define kf21__ 226
378192830Sed#define kf22__ 227
379192830Sed#define kf23__ 228
380192830Sed#define kf24__ 229
381192830Sed#define kf25__ 230
382192830Sed#define kf26__ 231
383192830Sed#define kf27__ 232
384192830Sed#define kf28__ 233
385192830Sed#define kf29__ 234
386192830Sed#define kf30__ 235
387192830Sed#define kf31__ 236
388192830Sed#define kf32__ 237
389192830Sed#define kf33__ 238
390192830Sed#define kf34__ 239
391192830Sed#define kf35__ 240
392192830Sed#define kf36__ 241
393192830Sed#define kf37__ 242
394192830Sed#define kf38__ 243
395192830Sed#define kf39__ 244
396192830Sed#define kf40__ 245
397192830Sed#define kf41__ 246
398192830Sed#define kf42__ 247
399192830Sed#define kf43__ 248
400192830Sed#define kf44__ 249
401192830Sed#define kf45__ 250
402192830Sed#define kf46__ 251
403192830Sed#define kf47__ 252
404192830Sed#define kf48__ 253
405192830Sed#define kf49__ 254
406192830Sed#define kf50__ 255
407192830Sed#define kf51__ 256
408192830Sed#define kf52__ 257
409192830Sed#define kf53__ 258
410192830Sed#define kf54__ 259
411192830Sed#define kf55__ 260
412192830Sed#define kf56__ 261
413192830Sed#define kf57__ 262
414192830Sed#define kf58__ 263
415192830Sed#define kf59__ 264
416192830Sed#define kf60__ 265
417192830Sed#define kf61__ 266
418192830Sed#define kf62__ 267
419192830Sed#define kf63__ 268
420192830Sed#define el1__ 269
421192830Sed#define mgc__ 270
422192830Sed#define smgl__ 271
423192830Sed#define smgr__ 272
424192830Sed
425192830Sed#ifdef CAP
426192830Sedchar *Boolean_names[] = {
427192830Sed"bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
428192830Sed"mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
429192830Sed};
430192830Sed
431192830Sedchar *Number_names[] = {
432192830Sed"co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
433192830Sed};
434192830Sed
435192830Sedchar *String_names[] = {
436192830Sed"bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
437192830Sed"do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
438192830Sed"dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
439192830Sed"mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
440192830Sed"ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
441192830Sed"kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
442192830Sed"k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
443192830Sed"kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
444192830Sed"ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
445192830Sed"l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
446192830Sed"AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
447192830Sed"rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
448192830Sed"st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
449192830Sed"K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
450192830Sed"XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
451192830Sed"@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
452192830Sed"%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
453192830Sed"&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
454192830Sed"#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
455192830Sed"%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
456192830Sed"F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
457192830Sed"FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
458192830Sed"FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
459192830Sed"Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
460192830Sed"Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
461192830Sed};
462192830Sed#endif
463192830Sed
464192830Sedchar *new_curse = "October 1987";
465192830Sed
466192830Sedchar in_buff[100];	/* buffer for ungetch			*/
467192830Sedint bufp;		/* next free position in in_buff	*/
468192830Sed
469192830Sedchar *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment	*/
470192830Sedint CFOUND = FALSE;
471192830Sedint Data_Line_len = 0;
472192830Sedint Max_Key_len;	/* max length of a sequence sent by a key	*/
473192830Sedchar *Data_Line = NULL;
474192830Sedchar *TERM_PATH = NULL;
475192830Sedchar *TERM_data_ptr = NULL;
476192830Sedchar *Term_File_name = NULL;	/* name of file containing terminal description	*/
477192830SedFILE *TFP;		/* file pointer to file with terminal des.	*/
478192830Sedint Fildes;		/* file descriptor for terminfo file		*/
479192830Sedint STAND = FALSE;	/* is standout mode activated?			*/
480192830Sedint TERM_INFO = FALSE;	/* is terminfo being used (TRUE), or termcap (FALSE) */
481192830Sedint Time_Out;	/* set when time elapsed while trying to read function key */
482192830Sedint Curr_x;		/* current x position on screen			*/
483192830Sedint Curr_y;		/* current y position on the screen		*/
484192830Sedint LINES;
485192830Sedint COLS;
486192830Sedint Move_It;		/* flag to move cursor if magic cookie glitch	*/
487192830Sedint initialized = FALSE;	/* tells whether new_curse is initialized	*/
488192830Sedfloat speed;
489192830Sedfloat chars_per_millisecond;
490192830Sedint Repaint_screen;	/* if an operation to change screen impossible, repaint screen	*/
491192830Sedint Intr;		/* storeage for interrupt character		*/
492192830Sedint Parity;		/* 0 = no parity, 1 = odd parity, 2 = even parity */
493192830Sedint Noblock;		/* for BSD systems				*/
494192830Sedint Num_bits;	/* number of bits per character	*/
495192830Sedint Flip_Bytes;	/* some systems have byte order reversed	*/
496192830Sedint interrupt_flag = FALSE;	/* set true if SIGWINCH received	*/
497192830Sed
498192830Sed#ifndef CAP
499192830Sedchar *Strings;
500192830Sed#endif
501192830Sed
502192914Sed#if !defined(TERMCAP)
503192914Sed#define TERMCAP "/etc/termcap"
504192914Sed#endif
505192914Sed
506192830Sedstruct KEYS {
507192830Sed	int length;	/* length of string sent by key			*/
508192830Sed	char *string;	/* string sent by key				*/
509192830Sed	int value;	/* CURSES value of key (9-bit)			*/
510192830Sed	};
511192830Sed
512192830Sedstruct KEY_STACK {
513192830Sed	struct KEYS *element;
514192830Sed	struct KEY_STACK *next;
515192830Sed	};
516192830Sed
517192830Sedstruct KEY_STACK *KEY_TOS = NULL;
518192830Sedstruct KEY_STACK *KEY_POINT;
519192830Sed
520192830Sed/*
521192830Sed |
522192830Sed |	Not all systems have good terminal information, so we will define
523192830Sed |	keyboard information here for the most widely used terminal type,
524192830Sed |	the VT100.
525192830Sed |
526192830Sed */
527192830Sed
528192830Sedstruct KEYS vt100[] =
529192830Sed	{
530192830Sed		{ 3, "\033[A", 0403 },	/* key up 	*/
531192830Sed		{ 3, "\033[C", 0405 },	/* key right	*/
532192830Sed		{ 3, "\033[D", 0404 },	/* key left	*/
533192830Sed
534192830Sed		{ 4, "\033[6~", 0522 },	/* key next page	*/
535192830Sed		{ 4, "\033[5~", 0523 },	/* key prev page	*/
536192830Sed		{ 3, "\033[[", 0550 },	/* key end	*/
537192830Sed		{ 3, "\033[@", 0406 },	/* key home	*/
538192830Sed		{ 4, "\033[2~", 0513 },	/* key insert char	*/
539192830Sed
540192830Sed		{ 3, "\033[y", 0410 },	/* key F0	*/
541192830Sed		{ 3, "\033[P", 0411 },	/* key F1	*/
542192830Sed		{ 3, "\033[Q", 0412 },	/* key F2	*/
543192830Sed		{ 3, "\033[R", 0413 },	/* key F3	*/
544192830Sed		{ 3, "\033[S", 0414 },	/* key F4	*/
545192830Sed		{ 3, "\033[t", 0415 },	/* key F5	*/
546192830Sed		{ 3, "\033[u", 0416 },	/* key F6	*/
547192830Sed		{ 3, "\033[v", 0417 },	/* key F7	*/
548192830Sed		{ 3, "\033[l", 0420 },	/* key F8	*/
549192830Sed		{ 3, "\033[w", 0421 },	/* key F9	*/
550192830Sed		{ 3, "\033[x", 0422 },	/* key F10	*/
551192830Sed
552192830Sed		{ 5, "\033[10~", 0410 },	/* key F0	*/
553192830Sed		{ 5, "\033[11~", 0411 },	/* key F1	*/
554192830Sed		{ 5, "\033[12~", 0412 },	/* key F2	*/
555192830Sed		{ 5, "\033[13~", 0413 },	/* key F3	*/
556192830Sed		{ 5, "\033[14~", 0414 },	/* key F4	*/
557192830Sed		{ 5, "\033[15~", 0415 },	/* key F5	*/
558192830Sed		{ 5, "\033[17~", 0416 },	/* key F6	*/
559192830Sed		{ 5, "\033[18~", 0417 },	/* key F7	*/
560192830Sed		{ 5, "\033[19~", 0420 },	/* key F8	*/
561192830Sed		{ 5, "\033[20~", 0421 },	/* key F9	*/
562192830Sed		{ 5, "\033[21~", 0422 },	/* key F10	*/
563192830Sed		{ 5, "\033[23~", 0423 },	/* key F11	*/
564192830Sed		{ 5, "\033[24~", 0424 },	/* key F12	*/
565192830Sed		{ 3, "\033[q", 0534 },	/* ka1 upper-left of keypad	*/
566192830Sed		{ 3, "\033[s", 0535 },	/* ka3 upper-right of keypad	*/
567192830Sed		{ 3, "\033[r", 0536 },	/* kb2 center of keypad	*/
568192830Sed 		{ 3, "\033[p", 0537 },	/* kc1 lower-left of keypad	*/
569192830Sed		{ 3, "\033[n", 0540 },	/* kc3 lower-right of keypad	*/
570192830Sed
571192830Sed		/*
572192830Sed		 |	The following are the same keys as above, but with
573192830Sed		 |	a different character following the escape char.
574192830Sed		 */
575192830Sed
576192830Sed		{ 3, "\033OA", 0403 },	/* key up 	*/
577192830Sed		{ 3, "\033OC", 0405 },	/* key right	*/
578192830Sed		{ 3, "\033OD", 0404 },	/* key left	*/
579192830Sed		{ 3, "\033OB", 0402 },	/* key down	*/
580192830Sed		{ 4, "\033O6~", 0522 },	/* key next page	*/
581192830Sed		{ 4, "\033O5~", 0523 },	/* key prev page	*/
582192830Sed		{ 3, "\033O[", 0550 },	/* key end	*/
583192830Sed		{ 3, "\033O@", 0406 },	/* key home	*/
584192830Sed		{ 4, "\033O2~", 0513 },	/* key insert char	*/
585192830Sed
586192830Sed		{ 3, "\033Oy", 0410 },	/* key F0	*/
587192830Sed		{ 3, "\033OP", 0411 },	/* key F1	*/
588192830Sed		{ 3, "\033OQ", 0412 },	/* key F2	*/
589192830Sed		{ 3, "\033OR", 0413 },	/* key F3	*/
590192830Sed		{ 3, "\033OS", 0414 },	/* key F4	*/
591192830Sed		{ 3, "\033Ot", 0415 },	/* key F5	*/
592192830Sed		{ 3, "\033Ou", 0416 },	/* key F6	*/
593192830Sed		{ 3, "\033Ov", 0417 },	/* key F7	*/
594192830Sed		{ 3, "\033Ol", 0420 },	/* key F8	*/
595192830Sed		{ 3, "\033Ow", 0421 },	/* key F9	*/
596192830Sed		{ 3, "\033Ox", 0422 },	/* key F10	*/
597192830Sed
598192830Sed		{ 5, "\033O10~", 0410 },	/* key F0	*/
599192830Sed		{ 5, "\033O11~", 0411 },	/* key F1	*/
600192830Sed		{ 5, "\033O12~", 0412 },	/* key F2	*/
601192830Sed		{ 5, "\033O13~", 0413 },	/* key F3	*/
602192830Sed		{ 5, "\033O14~", 0414 },	/* key F4	*/
603192830Sed		{ 5, "\033O15~", 0415 },	/* key F5	*/
604192830Sed		{ 5, "\033O17~", 0416 },	/* key F6	*/
605192830Sed		{ 5, "\033O18~", 0417 },	/* key F7	*/
606192830Sed		{ 5, "\033O19~", 0420 },	/* key F8	*/
607192830Sed		{ 5, "\033O20~", 0421 },	/* key F9	*/
608192830Sed		{ 5, "\033O21~", 0422 },	/* key F10	*/
609192830Sed		{ 5, "\033O23~", 0423 },	/* key F11	*/
610192830Sed		{ 5, "\033O24~", 0424 },	/* key F12	*/
611192830Sed		{ 3, "\033Oq", 0534 },	/* ka1 upper-left of keypad	*/
612192830Sed		{ 3, "\033Os", 0535 },	/* ka3 upper-right of keypad	*/
613192830Sed		{ 3, "\033Or", 0536 },	/* kb2 center of keypad	*/
614192830Sed 		{ 3, "\033Op", 0537 },	/* kc1 lower-left of keypad	*/
615192830Sed		{ 3, "\033On", 0540 },	/* kc3 lower-right of keypad	*/
616192830Sed
617192830Sed		{ 0, "", 0 }	/* end	*/
618192830Sed	};
619192830Sed
620192830Sedstruct Parameters {
621192830Sed	int value;
622192830Sed	struct Parameters *next;
623192830Sed	};
624192830Sed
625192830Sedint Key_vals[] = {
626192830Sed	0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
627192830Sed	0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
628192830Sed	0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
629192830Sed	0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
630192830Sed	0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
631192830Sed	0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
632192830Sed	0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
633192830Sed	0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
634192830Sed	0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
635192830Sed	0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
636192830Sed	0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
637192830Sed	0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
638192830Sed	0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
639192830Sed};
640192830Sed
641192830Sedint attributes_set[9];
642192830Sed
643192830Sedstatic int nc_attributes = 0;	/* global attributes for new_curse to observe */
644192830Sed
645192830Sed#ifdef SYS5
646192830Sedstruct termio Terminal;
647192830Sedstruct termio Saved_tty;
648192830Sed#else
649192830Sedstruct sgttyb Terminal;
650192830Sedstruct sgttyb Saved_tty;
651192830Sed#endif
652192830Sed
653192830Sedchar *tc_;
654192830Sed
655192830Sedint Booleans[128];
656192830Sedint Numbers[128];
657192830Sedchar *String_table[1024];
658192830Sed
659192830Sedint *virtual_lines;
660192830Sed
661192830Sedstatic char nc_scrolling_ability = FALSE;
662192830Sed
663192914Sedchar *terminfo_path[] = {
664192914Sed        "/usr/lib/terminfo",
665192914Sed        "/usr/share/lib/terminfo",
666192914Sed        "/usr/share/terminfo",
667192914Sed        NULL
668192914Sed        };
669192914Sed
670192830Sed#ifdef CAP
671192830Sed
672192830Sed#if defined(__STDC__) || defined(__cplusplus)
673192830Sed#define P_(s) s
674192830Sed#else
675192830Sed#define P_(s) ()
676192830Sed#endif /* __STDC__ */
677192830Sed
678192830Sedint tc_Get_int P_((int));
679192830Sedvoid CAP_PARSE P_((void));
680192830Sedvoid Find_term P_((void));
681192830Sed
682192830Sed#undef P_
683192830Sed
684192830Sed#endif /* CAP */
685192830Sed
686192830Sed
687192830Sed#ifndef __STDC__
688192830Sed#ifndef HAS_STDLIB
689192830Sedextern char *fgets();
690192830Sedextern char *malloc();
691192830Sedextern char *getenv();
692192830SedFILE *fopen();			/* declaration for open function	*/
693192830Sed#endif /* HAS_STDLIB */
694192830Sed#endif /* __STDC__ */
695192830Sed
696192830Sed#ifdef SIGWINCH
697192830Sed
698192830Sed/*
699192830Sed |	Copy the contents of one window to another.
700192830Sed */
701192830Sed
702192830Sedvoid
703192830Sedcopy_window(origin, destination)
704192830SedWINDOW *origin, *destination;
705192830Sed{
706192830Sed	int row, column;
707192830Sed	struct _line *orig, *dest;
708192830Sed
709192830Sed	orig = origin->first_line;
710192830Sed	dest = destination->first_line;
711192830Sed
712192830Sed	for (row = 0;
713192830Sed		row < (min(origin->Num_lines, destination->Num_lines));
714192830Sed			row++)
715192830Sed	{
716192830Sed		for (column = 0;
717192830Sed		    column < (min(origin->Num_cols, destination->Num_cols));
718192830Sed			column++)
719192830Sed		{
720192830Sed			dest->row[column] = orig->row[column];
721192830Sed			dest->attributes[column] = orig->attributes[column];
722192830Sed		}
723192830Sed		dest->changed = orig->changed;
724192830Sed		dest->scroll = orig->scroll;
725192830Sed		dest->last_char = min(orig->last_char, destination->Num_cols);
726192830Sed		orig = orig->next_screen;
727192830Sed		dest = dest->next_screen;
728192830Sed	}
729192830Sed	destination->LX = min((destination->Num_cols - 1), origin->LX);
730192830Sed	destination->LY = min((destination->Num_lines - 1), origin->LY);
731192830Sed	destination->Attrib = origin->Attrib;
732192830Sed	destination->scroll_up = origin->scroll_up;
733192830Sed	destination->scroll_down = origin->scroll_down;
734192830Sed	destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
735192830Sed}
736192830Sed
737192830Sedvoid
738192830Sedreinitscr(foo)
739192830Sedint foo;
740192830Sed{
741192830Sed	WINDOW *local_virt;
742192830Sed	WINDOW *local_std;
743192830Sed	WINDOW *local_cur;
744192830Sed
745192830Sed	signal(SIGWINCH, reinitscr);
746192830Sed#ifdef TIOCGWINSZ
747192830Sed	if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
748192830Sed	{
749192830Sed		if (ws.ws_row == LINES && ws.ws_col == COLS)
750192830Sed			return;
751192830Sed		if (ws.ws_row > 0)
752192830Sed			LINES = ws.ws_row;
753192830Sed		if (ws.ws_col > 0)
754192830Sed			COLS = ws.ws_col;
755192830Sed	}
756192830Sed#endif /* TIOCGWINSZ */
757192830Sed	local_virt = newwin(LINES, COLS, 0, 0);
758192830Sed	local_std = newwin(LINES, COLS, 0, 0);
759192830Sed	local_cur = newwin(LINES, COLS, 0, 0);
760192830Sed	copy_window(virtual_scr, local_virt);
761192830Sed	copy_window(stdscr, local_std);
762192830Sed	copy_window(curscr, local_cur);
763192830Sed	delwin(virtual_scr);
764192830Sed	delwin(stdscr);
765192830Sed	delwin(curscr);
766192830Sed	virtual_scr = local_virt;
767192830Sed	stdscr = local_std;
768192830Sed	curscr = local_cur;
769192830Sed	free(virtual_lines);
770192830Sed	virtual_lines = (int *) malloc(LINES * (sizeof(int)));
771192830Sed	interrupt_flag = TRUE;
772192830Sed}
773192830Sed#endif /* SIGWINCH */
774192830Sed
775192830Sedvoid
776192830Sedinitscr()		/* initialize terminal for operations	*/
777192830Sed{
778192830Sed	int value;
779192914Sed	int counter;
780192830Sed	char *lines_string;
781192830Sed	char *columns_string;
782192830Sed#ifdef CAP
783192830Sed	char *pointer;
784192830Sed#endif /* CAP */
785192830Sed
786192830Sed#ifdef DIAG
787192830Sedprintf("starting initscr \n");fflush(stdout);
788192830Sed#endif
789192830Sed	if (initialized)
790192830Sed		return;
791192830Sed#ifdef BSD_SELECT
792192830Sed	setbuf(stdin, NULL);
793192830Sed#endif /* BSD_SELECT */
794192830Sed	Flip_Bytes = FALSE;
795192830Sed	Parity = 0;
796192830Sed	Time_Out = FALSE;
797192830Sed	bufp = 0;
798192830Sed	Move_It = FALSE;
799192830Sed	Noblock = FALSE;
800192830Sed#ifdef SYS5
801192830Sed	value = ioctl(0, TCGETA, &Terminal);
802192830Sed	if (Terminal.c_cflag & PARENB)
803192830Sed	{
804192830Sed		if (Terminal.c_cflag & PARENB)
805192830Sed			Parity = 1;
806192830Sed		else
807192830Sed			Parity = 2;
808192830Sed	}
809192830Sed	if ((Terminal.c_cflag & CS8) == CS8)
810192830Sed	{
811192830Sed		Num_bits = 8;
812192830Sed	}
813192830Sed	else if ((Terminal.c_cflag & CS7) == CS7)
814192830Sed		Num_bits = 7;
815192830Sed	else if ((Terminal.c_cflag & CS6) == CS6)
816192830Sed		Num_bits = 6;
817192830Sed	else
818192830Sed		Num_bits = 5;
819192830Sed	value = Terminal.c_cflag & 037;
820192830Sed	switch (value) {
821192830Sed	case 01:	speed = 50.0;
822192830Sed		break;
823192830Sed	case 02:	speed = 75.0;
824192830Sed		break;
825192830Sed	case 03:	speed = 110.0;
826192830Sed		break;
827192830Sed	case 04:	speed = 134.5;
828192830Sed		break;
829192830Sed	case 05:	speed = 150.0;
830192830Sed		break;
831192830Sed	case 06:	speed = 200.0;
832192830Sed		break;
833192830Sed	case 07:	speed = 300.0;
834192830Sed		break;
835192830Sed	case 010:	speed = 600.0;
836192830Sed		break;
837192830Sed	case 011:	speed = 900.0;
838192830Sed		break;
839192830Sed	case 012:	speed = 1200.0;
840192830Sed		break;
841192830Sed	case 013:	speed = 1800.0;
842192830Sed		break;
843192830Sed	case 014:	speed = 2400.0;
844192830Sed		break;
845192830Sed	case 015:	speed = 3600.0;
846192830Sed		break;
847192830Sed	case 016:	speed = 4800.0;
848192830Sed		break;
849192830Sed	case 017:	speed = 7200.0;
850192830Sed		break;
851192830Sed	case 020:	speed = 9600.0;
852192830Sed		break;
853192830Sed	case 021:	speed = 19200.0;
854192830Sed		break;
855192830Sed	case 022:	speed = 38400.0;
856192830Sed		break;
857192830Sed	default:	speed = 0.0;
858192830Sed	}
859192830Sed#else
860192830Sed	value = ioctl(0, TIOCGETP, &Terminal);
861192830Sed	if (Terminal.sg_flags & EVENP)
862192830Sed		Parity = 2;
863192830Sed	else if (Terminal.sg_flags & ODDP)
864192830Sed		Parity = 1;
865192830Sed	value = Terminal.sg_ospeed;
866192830Sed	switch (value) {
867192830Sed	case 01:	speed = 50.0;
868192830Sed		break;
869192830Sed	case 02:	speed = 75.0;
870192830Sed		break;
871192830Sed	case 03:	speed = 110.0;
872192830Sed		break;
873192830Sed	case 04:	speed = 134.5;
874192830Sed		break;
875192830Sed	case 05:	speed = 150.0;
876192830Sed		break;
877192830Sed	case 06:	speed = 200.0;
878192830Sed		break;
879192830Sed	case 07:	speed = 300.0;
880192830Sed		break;
881192830Sed	case 010:	speed = 600.0;
882192830Sed		break;
883192830Sed	case 011:	speed = 1200.0;
884192830Sed		break;
885192830Sed	case 012:	speed = 1800.0;
886192830Sed		break;
887192830Sed	case 013:	speed = 2400.0;
888192830Sed		break;
889192830Sed	case 014:	speed = 4800.0;
890192830Sed		break;
891192830Sed	case 015:	speed = 9600.0;
892192830Sed		break;
893192830Sed	default:	speed = 0.0;
894192830Sed	}
895192830Sed#endif
896192830Sed	chars_per_millisecond = (0.001 * speed) / 8.0;
897192830Sed	TERMINAL_TYPE = getenv("TERM");
898192830Sed	if (TERMINAL_TYPE == NULL)
899192830Sed	{
900192830Sed		printf("unknown terminal type\n");
901192830Sed		exit(0);
902192830Sed	}
903192830Sed#ifndef CAP
904192830Sed	Fildes = -1;
905192830Sed	TERM_PATH = getenv("TERMINFO");
906192830Sed	if (TERM_PATH != NULL)
907192830Sed	{
908192830Sed		Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
909192830Sed		Term_File_name = malloc(Data_Line_len);
910192830Sed		sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
911192830Sed		Fildes = open(Term_File_name, O_RDONLY);
912192914Sed		if (Fildes == -1)
913192914Sed		{
914192914Sed        		sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
915192914Sed        		Fildes = open(Term_File_name, O_RDONLY);
916192914Sed		}
917192830Sed	}
918192914Sed	counter = 0;
919192914Sed	while ((Fildes == -1) && (terminfo_path[counter] != NULL))
920192830Sed	{
921192914Sed		TERM_PATH = terminfo_path[counter];
922192830Sed		Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
923192830Sed		Term_File_name = malloc(Data_Line_len);
924192830Sed		sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
925192830Sed		Fildes = open(Term_File_name, O_RDONLY);
926192914Sed		if (Fildes == -1)
927192914Sed		{
928192914Sed        		sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
929192914Sed        		Fildes = open(Term_File_name, O_RDONLY);
930192914Sed		}
931192914Sed		counter++;
932192830Sed	}
933192830Sed	if (Fildes == -1)
934192830Sed	{
935192830Sed		free(Term_File_name);
936192830Sed		Term_File_name = NULL;
937192830Sed	}
938192830Sed	else
939192830Sed		TERM_INFO = INFO_PARSE();
940192830Sed#else
941192830Sed	/*
942192830Sed	 |	termcap information can be in the TERMCAP env variable, if so
943192830Sed	 |	use that, otherwise check the /etc/termcap file
944192830Sed	 */
945192830Sed	if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
946192830Sed	{
947192830Sed		if (*Term_File_name != '/')
948192914Sed			Term_File_name = TERMCAP;
949192830Sed	}
950192830Sed	else
951192830Sed	{
952192914Sed		Term_File_name = TERMCAP;
953192830Sed	}
954192830Sed	if ((TFP = fopen(Term_File_name, "r")) == NULL)
955192830Sed	{
956192914Sed		printf("unable to open %s file \n", TERMCAP);
957192830Sed		exit(0);
958192830Sed	}
959192830Sed 	for (value = 0; value < 1024; value++)
960192830Sed		String_table[value] = NULL;
961192830Sed	for (value = 0; value < 128; value++)
962192830Sed		Booleans[value] = 0;
963192830Sed	for (value = 0; value < 128; value++)
964192830Sed		Numbers[value] = 0;
965192830Sed	Data_Line = malloc(512);
966192830Sed	if (pointer && *pointer != '/')
967192830Sed	{
968192830Sed		TERM_data_ptr = pointer;
969192830Sed		CAP_PARSE();
970192830Sed	}
971192830Sed	else
972192830Sed	{
973192830Sed		Find_term();
974192830Sed		CAP_PARSE();
975192830Sed	}
976192830Sed#endif
977192830Sed	if (String_table[pc__] == NULL)
978192830Sed		String_table[pc__] = "\0";
979192830Sed	if ((String_table[cm__] == NULL) || (Booleans[hc__]))
980192830Sed	{
981192830Sed		fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
982192830Sed		exit(0);
983192830Sed	}
984192830Sed	Key_Get();
985192830Sed	keys_vt100();
986192830Sed	LINES = Numbers[li__];
987192830Sed	COLS = Numbers[co__];
988192830Sed	if ((lines_string = getenv("LINES")) != NULL)
989192830Sed	{
990192830Sed		value = atoi(lines_string);
991192830Sed		if (value > 0)
992192830Sed			LINES = value;
993192830Sed	}
994192830Sed	if ((columns_string = getenv("COLUMNS")) != NULL)
995192830Sed	{
996192830Sed		value = atoi(columns_string);
997192830Sed		if (value > 0)
998192830Sed			COLS = value;
999192830Sed	}
1000192830Sed#ifdef TIOCGWINSZ
1001192830Sed	/*
1002192830Sed	 |	get the window size
1003192830Sed	 */
1004192830Sed	if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
1005192830Sed	{
1006192830Sed		if (ws.ws_row > 0)
1007192830Sed			LINES = ws.ws_row;
1008192830Sed		if (ws.ws_col > 0)
1009192830Sed			COLS = ws.ws_col;
1010192830Sed	}
1011192830Sed#endif
1012192830Sed	virtual_scr = newwin(LINES, COLS, 0, 0);
1013192830Sed	stdscr = newwin(LINES, COLS, 0, 0);
1014192830Sed	curscr = newwin(LINES, COLS, 0, 0);
1015192830Sed	wmove(stdscr, 0, 0);
1016192830Sed	werase(stdscr);
1017192830Sed	Repaint_screen = TRUE;
1018192830Sed	initialized = TRUE;
1019192830Sed	virtual_lines = (int *) malloc(LINES * (sizeof(int)));
1020192830Sed
1021192830Sed#ifdef SIGWINCH
1022192830Sed	/*
1023192830Sed	 |	reset size of windows and LINES and COLS if term window
1024192830Sed	 |	changes size
1025192830Sed	 */
1026192830Sed	signal(SIGWINCH, reinitscr);
1027192830Sed#endif /* SIGWINCH */
1028192830Sed
1029192830Sed	/*
1030192830Sed	 |	check if scrolling is available
1031192830Sed	 */
1032192830Sed
1033192830Sed	nc_scrolling_ability = ((String_table[al__] != NULL) &&
1034192830Sed				(String_table[dl__])) || ((String_table[cs__])
1035192830Sed				&& (String_table[sr__]));
1036192830Sed
1037192830Sed}
1038192830Sed
1039192830Sed#ifndef CAP
1040192830Sedint
1041192830SedGet_int()		/* get a two-byte integer from the terminfo file */
1042192830Sed{
1043192830Sed	int High_byte;
1044192830Sed	int Low_byte;
1045192830Sed	int temp;
1046192830Sed
1047192830Sed	Low_byte = *((unsigned char *) TERM_data_ptr++);
1048192830Sed	High_byte = *((unsigned char *) TERM_data_ptr++);
1049192830Sed	if (Flip_Bytes)
1050192830Sed	{
1051192830Sed		temp = Low_byte;
1052192830Sed		Low_byte = High_byte;
1053192830Sed		High_byte = temp;
1054192830Sed	}
1055192830Sed	if ((High_byte == 255) && (Low_byte == 255))
1056192830Sed		return (-1);
1057192830Sed	else
1058192830Sed		return(Low_byte + (High_byte * 256));
1059192830Sed}
1060192830Sed
1061192830Sedint
1062192830SedINFO_PARSE()		/* parse off the data in the terminfo data file	*/
1063192830Sed{
1064192830Sed	int offset;
1065192830Sed	int magic_number = 0;
1066192830Sed	int counter = 0;
1067192830Sed	int Num_names = 0;
1068192830Sed	int Num_bools = 0;
1069192830Sed	int Num_ints = 0;
1070192830Sed	int Num_strings = 0;
1071192830Sed	int string_table_len = 0;
1072192830Sed	char *temp_ptr;
1073192830Sed
1074192830Sed	TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
1075192830Sed	Data_Line_len = read(Fildes, Data_Line, 10240);
1076192830Sed	if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
1077192830Sed		return(0);
1078192830Sed	/*
1079192830Sed	 |	get magic number
1080192830Sed	 */
1081192830Sed	magic_number = Get_int();
1082192830Sed	/*
1083192830Sed	 |	if magic number not right, reverse byte order and check again
1084192830Sed	 */
1085192830Sed	if (magic_number != 282)
1086192830Sed	{
1087192830Sed		Flip_Bytes = TRUE;
1088192830Sed		TERM_data_ptr--;
1089192830Sed		TERM_data_ptr--;
1090192830Sed		magic_number = Get_int();
1091192830Sed		if (magic_number != 282)
1092192830Sed			return(0);
1093192830Sed	}
1094192830Sed	/*
1095192830Sed	 |	get the number of each type in the terminfo data file
1096192830Sed	 */
1097192830Sed	Num_names = Get_int();
1098192830Sed	Num_bools = Get_int();
1099192830Sed	Num_ints = Get_int();
1100192830Sed	Num_strings = Get_int();
1101192830Sed	string_table_len = Get_int();
1102192830Sed	Strings = malloc(string_table_len);
1103192830Sed	while (Num_names > 0)
1104192830Sed	{
1105192830Sed		TERM_data_ptr++;
1106192830Sed		Num_names--;
1107192830Sed	}
1108192830Sed	counter = 0;
1109192830Sed	while (Num_bools)
1110192830Sed	{
1111192830Sed		Num_bools--;
1112192830Sed		Booleans[counter++] = *TERM_data_ptr++;
1113192830Sed	}
1114192914Sed	if ((unsigned long)TERM_data_ptr & 1)	/* force alignment	*/
1115192830Sed		TERM_data_ptr++;
1116192830Sed	counter = 0;
1117192830Sed	while (Num_ints)
1118192830Sed	{
1119192830Sed		Num_ints--;
1120192830Sed		Numbers[counter] = Get_int();
1121192830Sed		counter++;
1122192830Sed	}
1123192830Sed	temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
1124192830Sed	memcpy(Strings, temp_ptr, string_table_len);
1125192830Sed	counter = bt__;
1126192830Sed	while (Num_strings)
1127192830Sed	{
1128192830Sed		Num_strings--;
1129192830Sed		if ((offset=Get_int()) != -1)
1130192830Sed		{
1131192830Sed			if (String_table[counter] == NULL)
1132192830Sed				String_table[counter] = Strings + offset;
1133192830Sed		}
1134192830Sed		else
1135192830Sed			String_table[counter] = NULL;
1136192830Sed		counter++;
1137192830Sed	}
1138192830Sed	close(Fildes);
1139192830Sed	free(Data_Line);
1140192830Sed	return(TRUE);
1141192830Sed}
1142192830Sed#endif		/* ifndef CAP	*/
1143192830Sed
1144192830Sedint
1145192830SedAtoI()		/* convert ascii text to integers	*/
1146192830Sed{
1147192830Sed	int Temp;
1148192830Sed
1149192830Sed	Temp = 0;
1150192830Sed	while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1151192830Sed	{
1152192830Sed		Temp = (Temp * 10) + (*TERM_data_ptr - '0');
1153192830Sed		TERM_data_ptr++;
1154192830Sed	}
1155192830Sed	return(Temp);
1156192830Sed}
1157192830Sed
1158192830Sedvoid
1159192830SedKey_Get()		/* create linked list with all key sequences obtained from terminal database	*/
1160192830Sed{
1161192830Sed	int Counter;
1162192830Sed	int Klen;
1163192830Sed	int key_def;
1164192830Sed	struct KEY_STACK *Spoint;
1165192830Sed
1166192830Sed	Max_Key_len = 0;
1167192830Sed	Counter = 0;
1168192830Sed	key_def = kb__;
1169192830Sed	while (key_def <= kf63__)
1170192830Sed	{
1171192830Sed		if (key_def == ke__)
1172192830Sed			key_def = K1__;
1173192830Sed		else if (key_def == (K5__ + 1))
1174192830Sed			key_def = kcbt__;
1175192830Sed		else if (key_def == (kcbt__ + 1))
1176192830Sed			key_def = kbeg__;
1177192830Sed		else if (key_def == (kUND__ + 1))
1178192830Sed			key_def = kf11__;
1179192830Sed		if (String_table[key_def] != NULL)
1180192830Sed		{
1181192830Sed			if (KEY_TOS == NULL)
1182192830Sed				Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1183192830Sed			else
1184192830Sed			{
1185192830Sed				Spoint = KEY_TOS;
1186192830Sed				while (Spoint->next != NULL)
1187192830Sed					Spoint = Spoint->next;
1188192830Sed				Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1189192830Sed				Spoint = Spoint->next;
1190192830Sed			}
1191192830Sed			Spoint->next = NULL;
1192192830Sed			Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1193192830Sed			Spoint->element->string = String_table[key_def];
1194192830Sed			Spoint->element->length = strlen(String_table[key_def]);
1195192830Sed			Spoint->element->value = Key_vals[Counter];
1196192830Sed			Klen = strlen(Spoint->element->string);
1197192830Sed			if (Klen > Max_Key_len)
1198192830Sed				Max_Key_len = Klen;
1199192830Sed			/*
1200192830Sed			 |  Some terminal types accept keystrokes of the form
1201192830Sed			 |  \E[A and \EOA, substituting '[' for 'O'.  Make a
1202192830Sed			 |  duplicate of such key strings (since the
1203192830Sed			 |  database will only have one version) so new_curse
1204192830Sed			 |  can understand both.
1205192830Sed			 */
1206192830Sed			if ((Spoint->element->length > 1) &&
1207192830Sed			    ((String_table[key_def][1] == '[') ||
1208192830Sed			     (String_table[key_def][1] == 'O')))
1209192830Sed			{
1210192830Sed				Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1211192830Sed				Spoint = Spoint->next;
1212192830Sed				Spoint->next = NULL;
1213192830Sed				Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
1214192830Sed				Spoint->element->length = strlen(String_table[key_def]);
1215192830Sed				Spoint->element->string = malloc(Spoint->element->length + 1);
1216192830Sed				strcpy(Spoint->element->string, String_table[key_def]);
1217192830Sed				Spoint->element->value = Key_vals[Counter];
1218192830Sed				Klen = strlen(Spoint->element->string);
1219192830Sed				if (Klen > Max_Key_len)
1220192830Sed					Max_Key_len = Klen;
1221192830Sed
1222192830Sed				if (String_table[key_def][1] == '[')
1223192830Sed					Spoint->element->string[1] = 'O';
1224192830Sed				else
1225192830Sed					Spoint->element->string[1] = '[';
1226192830Sed			}
1227192830Sed		}
1228192830Sed		key_def++;
1229192830Sed		Counter++;
1230192830Sed	}
1231192830Sed}
1232192830Sed
1233192830Sed/*
1234192830Sed |	insert information about keys for a vt100 terminal
1235192830Sed */
1236192830Sed
1237192830Sedvoid
1238192830Sedkeys_vt100()
1239192830Sed{
1240192830Sed	int counter;
1241192830Sed	int Klen;
1242192830Sed	struct KEY_STACK *Spoint;
1243192830Sed
1244192830Sed	Spoint = KEY_TOS;
1245192830Sed	while (Spoint->next != NULL)
1246192830Sed		Spoint = Spoint->next;
1247192830Sed	for (counter = 0; vt100[counter].length != 0; counter++)
1248192830Sed	{
1249192830Sed		Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
1250192830Sed		Spoint = Spoint->next;
1251192830Sed		Spoint->next = NULL;
1252192830Sed		Spoint->element = &vt100[counter];
1253192830Sed		Klen = strlen(Spoint->element->string);
1254192830Sed		if (Klen > Max_Key_len)
1255192830Sed			Max_Key_len = Klen;
1256192830Sed	}
1257192830Sed}
1258192830Sed
1259192830Sed#ifdef CAP
1260192830Sedchar *
1261192830SedString_Get(param)		/* read the string */
1262192830Sedchar *param;
1263192830Sed{
1264192830Sed	char *String;
1265192830Sed	char *Temp;
1266192830Sed	int Counter;
1267192830Sed
1268192830Sed	if (param == NULL)
1269192830Sed	{
1270192830Sed		while (*TERM_data_ptr != '=')
1271192830Sed			TERM_data_ptr++;
1272192830Sed		Temp = ++TERM_data_ptr;
1273192830Sed		Counter = 1;
1274192830Sed		while ((*Temp != ':') && (*Temp != (char)NULL))
1275192830Sed		{
1276192830Sed			Counter++;
1277192830Sed			Temp++;
1278192830Sed		}
1279192830Sed		if (Counter == 1)	/* no data */
1280192830Sed			return(NULL);
1281192830Sed		String = Temp = malloc(Counter);
1282192830Sed		while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1283192830Sed		{
1284192830Sed			if (*TERM_data_ptr == '\\')
1285192830Sed			{
1286192830Sed				TERM_data_ptr++;
1287192830Sed				if (*TERM_data_ptr == 'n')
1288192830Sed					*Temp = '\n';
1289192830Sed				else if (*TERM_data_ptr == 't')
1290192830Sed					*Temp = '\t';
1291192830Sed				else if (*TERM_data_ptr == 'b')
1292192830Sed					*Temp = '\b';
1293192830Sed				else if (*TERM_data_ptr == 'r')
1294192830Sed					*Temp = '\r';
1295192830Sed				else if (*TERM_data_ptr == 'f')
1296192830Sed					*Temp = '\f';
1297192830Sed				else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
1298192830Sed					*Temp = '\033';		/* escape */
1299192830Sed				else if (*TERM_data_ptr == '\\')
1300192830Sed					*Temp = '\\';
1301192830Sed				else if (*TERM_data_ptr == '\'')
1302192830Sed					*Temp = '\'';
1303192830Sed				else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1304192830Sed				{
1305192830Sed					Counter = 0;
1306192830Sed					while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
1307192830Sed					{
1308192830Sed						Counter = (8 * Counter) + (*TERM_data_ptr - '0');
1309192830Sed						TERM_data_ptr++;  /* ? */
1310192830Sed					}
1311192830Sed					*Temp = Counter;
1312192830Sed					TERM_data_ptr--;
1313192830Sed				}
1314192830Sed				TERM_data_ptr++;
1315192830Sed				Temp++;
1316192830Sed			}
1317192830Sed			else if (*TERM_data_ptr == '^')
1318192830Sed			{
1319192830Sed				TERM_data_ptr++;
1320192830Sed				if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
1321192830Sed					*Temp = *TERM_data_ptr - '@';
1322192830Sed				else if (*TERM_data_ptr == '?')
1323192830Sed					*Temp = 127;
1324192830Sed				TERM_data_ptr++;
1325192830Sed				Temp++;
1326192830Sed			}
1327192830Sed			else
1328192830Sed				*Temp++ = *TERM_data_ptr++;
1329192830Sed		}
1330192830Sed		*Temp = (char)NULL;
1331192830Sed		param = String;
1332192830Sed	}
1333192830Sed	else
1334192830Sed	{
1335192830Sed		while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
1336192830Sed			TERM_data_ptr++;
1337192830Sed	}
1338192830Sed	return(param);
1339192830Sed}
1340192830Sed
1341192830Sedint
1342192830Sedtc_Get_int(param)		/* read the integer			*/
1343192830Sedint param;
1344192830Sed{
1345192830Sed	int Itemp;
1346192830Sed
1347192830Sed	if (param == 0)
1348192830Sed	{
1349192830Sed		while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
1350192830Sed			TERM_data_ptr++;
1351192830Sed		TERM_data_ptr++;
1352192830Sed		Itemp = AtoI();
1353192830Sed		param = Itemp;
1354192830Sed	}
1355192830Sed	else
1356192830Sed	{
1357192830Sed		while (*TERM_data_ptr != ':')
1358192830Sed			TERM_data_ptr++;
1359192830Sed	}
1360192830Sed	return(param);
1361192830Sed}
1362192830Sed
1363192830Sedvoid
1364192830SedFind_term()		/* find terminal description in termcap file	*/
1365192830Sed{
1366192830Sed	char *Name;
1367192830Sed	char *Ftemp;
1368192830Sed
1369192914Sed	Ftemp = Name = malloc(strlen(TERMINAL_TYPE) + 2);
1370192830Sed	strcpy(Name, TERMINAL_TYPE);
1371192830Sed	while (*Ftemp != (char)NULL)
1372192830Sed		Ftemp++;
1373192830Sed	*Ftemp++ = '|';
1374192830Sed	*Ftemp = (char)NULL;
1375192830Sed	CFOUND = FALSE;
1376192830Sed	Data_Line_len = strlen(TERMINAL_TYPE) + 1;
1377192830Sed	while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
1378192830Sed	{
1379192830Sed		if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
1380192830Sed		{
1381192830Sed			while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
1382192830Sed			{
1383192830Sed				CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
1384192830Sed				while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
1385192830Sed					TERM_data_ptr++;
1386192830Sed				if (*TERM_data_ptr == '|')
1387192830Sed					TERM_data_ptr++;
1388192830Sed				else if (!CFOUND)
1389192830Sed					*TERM_data_ptr = (char)NULL;
1390192830Sed			}
1391192830Sed		}
1392192830Sed	}
1393192830Sed	if (!CFOUND)
1394192830Sed	{
1395192830Sed		printf("terminal type %s not found\n", TERMINAL_TYPE);
1396192830Sed		exit(0);
1397192830Sed	}
1398192830Sed}
1399192830Sed
1400192830Sedvoid
1401192830SedCAP_PARSE()		/* parse off the data in the termcap data file	*/
1402192830Sed{
1403192830Sed	int offset;
1404192830Sed	int found;
1405192830Sed
1406192830Sed	do
1407192830Sed	{
1408192830Sed		while (*TERM_data_ptr != (char)NULL)
1409192830Sed		{
1410192830Sed			for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
1411192830Sed			{
1412192830Sed				if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
1413192830Sed				{
1414192830Sed					found = TRUE;
1415192830Sed					Booleans[offset] = TRUE;
1416192830Sed				}
1417192830Sed			}
1418192830Sed			if (!found)
1419192830Sed			{
1420192830Sed				for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
1421192830Sed				{
1422192830Sed					if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
1423192830Sed					{
1424192830Sed						found = TRUE;
1425192830Sed						Numbers[offset] = tc_Get_int(Numbers[offset]);
1426192830Sed					}
1427192830Sed				}
1428192830Sed			}
1429192830Sed			if (!found)
1430192830Sed			{
1431192830Sed				for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
1432192830Sed				{
1433192830Sed					if (!strncmp(TERM_data_ptr, String_names[offset], 3))
1434192830Sed					{
1435192830Sed						found = TRUE;
1436192830Sed						String_table[offset] = String_Get(String_table[offset]);
1437192830Sed					}
1438192830Sed				}
1439192830Sed			}
1440192830Sed
1441192830Sed			if (!strncmp(TERM_data_ptr, "tc=", 3))
1442192830Sed				tc_ = String_Get(NULL);
1443192830Sed			while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
1444192830Sed				TERM_data_ptr++;
1445192830Sed			if (*TERM_data_ptr == ':')
1446192830Sed				TERM_data_ptr++;
1447192830Sed		}
1448192830Sed	} while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
1449192830Sed	if (tc_ != NULL)
1450192830Sed	{
1451192830Sed		TERMINAL_TYPE = tc_;
1452192830Sed		rewind(TFP);
1453192830Sed		Find_term();
1454192830Sed		tc_ = NULL;
1455192830Sed		CAP_PARSE();
1456192830Sed	}
1457192830Sed	else
1458192830Sed		fclose(TFP);
1459192830Sed}
1460192830Sed#endif		/* ifdef CAP	*/
1461192830Sed
1462192830Sedstruct _line *
1463192830SedScreenalloc(columns)
1464192830Sedint columns;
1465192830Sed{
1466192830Sed	int i;
1467192830Sed	struct _line *tmp;
1468192830Sed
1469192830Sed	tmp = (struct _line *) malloc(sizeof (struct _line));
1470192830Sed	tmp->row = malloc(columns + 1);
1471192830Sed	tmp->attributes = malloc(columns + 1);
1472192830Sed	tmp->prev_screen = NULL;
1473192830Sed	tmp->next_screen = NULL;
1474192830Sed	for (i = 0; i < columns; i++)
1475192830Sed	{
1476192830Sed		tmp->row[i] = ' ';
1477192914Sed		tmp->attributes[i] = '\0';
1478192830Sed	}
1479192830Sed	tmp->scroll = tmp->changed = FALSE;
1480192914Sed	tmp->row[0] = '\0';
1481192914Sed	tmp->attributes[0] = '\0';
1482192914Sed	tmp->row[columns] = '\0';
1483192914Sed	tmp->attributes[columns] = '\0';
1484192830Sed	tmp->last_char = 0;
1485192830Sed	return(tmp);
1486192830Sed}
1487192830Sed
1488192830SedWINDOW *newwin(lines, cols, start_l, start_c)
1489192830Sedint lines, cols;	/* number of lines and columns to be in window	*/
1490192830Sedint start_l, start_c;	/* starting line and column to be inwindow	*/
1491192830Sed{
1492192830Sed	WINDOW *Ntemp;
1493192830Sed	struct _line *temp_screen;
1494192830Sed	int i;
1495192830Sed
1496192830Sed	Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
1497192830Sed	Ntemp->SR = start_l;
1498192830Sed	Ntemp->SC = start_c;
1499192830Sed	Ntemp->Num_lines = lines;
1500192830Sed	Ntemp->Num_cols = cols;
1501192830Sed	Ntemp->LX = 0;
1502192830Sed	Ntemp->LY = 0;
1503192830Sed	Ntemp->scroll_down = Ntemp->scroll_up = 0;
1504192830Sed	Ntemp->SCROLL_CLEAR = FALSE;
1505192830Sed	Ntemp->Attrib = FALSE;
1506192830Sed	Ntemp->first_line = temp_screen = Screenalloc(cols);
1507192830Sed	Ntemp->first_line->number = 0;
1508192830Sed	Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
1509192830Sed
1510192830Sed	Ntemp->line_array[0] = Ntemp->first_line;
1511192830Sed
1512192830Sed	for (i = 1; i < lines; i++)
1513192830Sed	{
1514192830Sed		temp_screen->next_screen = Screenalloc(cols);
1515192830Sed		temp_screen->next_screen->number = i;
1516192830Sed		temp_screen->next_screen->prev_screen = temp_screen;
1517192830Sed		temp_screen = temp_screen->next_screen;
1518192830Sed		Ntemp->line_array[i] = temp_screen;
1519192830Sed	}
1520192830Sed	Ntemp->first_line->prev_screen = NULL;
1521192830Sed	temp_screen->next_screen = NULL;
1522192830Sed	return(Ntemp);
1523192830Sed}
1524192830Sed
1525192830Sed#ifdef CAP
1526192830Sedvoid
1527192830SedCap_Out(string, p_list, place)	/* interpret the output string if necessary */
1528192830Sedchar *string;
1529192830Sedint p_list[];			/* stack of values	*/
1530192830Sedint place;			/* place keeper of top of stack	*/
1531192830Sed{
1532192830Sed	char *Otemp;		/* temporary string pointer to parse output */
1533192830Sed	int delay;
1534192830Sed	int p1, p2, temp;
1535192830Sed	float chars;
1536192830Sed
1537192830Sed	if (string == NULL)
1538192830Sed		return;
1539192830Sed
1540192830Sed	if (p_list != NULL)
1541192830Sed	{
1542192830Sed		p1 = p_list[--place];
1543192830Sed		p2 = p_list[--place];
1544192830Sed	}
1545192830Sed	delay = 0;
1546192830Sed	Otemp = string;
1547192830Sed	if ((*Otemp >= '0') && (*Otemp <= '9'))
1548192830Sed	{
1549192830Sed		delay = atoi(Otemp);
1550192830Sed		while ((*Otemp >= '0') && (*Otemp <= '9'))
1551192830Sed			Otemp++;
1552192830Sed		if (*Otemp == '*')
1553192830Sed			Otemp++;
1554192830Sed	}
1555192830Sed	while (*Otemp != (char)NULL)
1556192830Sed	{
1557192830Sed		if (*Otemp == '%')
1558192830Sed		{
1559192830Sed			Otemp++;
1560192830Sed			if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
1561192830Sed			{
1562192830Sed				if (*Otemp == 'd')
1563192830Sed				 	printf("%d", p1);
1564192830Sed				else if (*Otemp == '2')
1565192830Sed					printf("%02d", p1);
1566192830Sed				else if (*Otemp == '3')
1567192830Sed					printf("%03d", p1);
1568192830Sed				else if (*Otemp == '+')
1569192830Sed				{
1570192830Sed					Otemp++;
1571192830Sed					p1 += *Otemp;
1572192830Sed					putchar(p1);
1573192830Sed				}
1574192830Sed				else if (*Otemp == '.')
1575192830Sed					putchar(p1);
1576192830Sed				p1 = p2;
1577192830Sed				p2 = 0;
1578192830Sed			}
1579192830Sed			else if (*Otemp == '>')
1580192830Sed			{
1581192830Sed				Otemp++;
1582192830Sed				if (p1 > *Otemp)
1583192830Sed				{
1584192830Sed					Otemp++;
1585192830Sed					p1 += *Otemp;
1586192830Sed				}
1587192830Sed				else
1588192830Sed					Otemp++;
1589192830Sed			}
1590192830Sed			else if (*Otemp == 'r')
1591192830Sed			{
1592192830Sed				temp = p1;
1593192830Sed				p1 = p2;
1594192830Sed				p2 = temp;
1595192830Sed			}
1596192830Sed			else if (*Otemp == 'i')
1597192830Sed			{
1598192830Sed				p1++;
1599192830Sed				p2++;
1600192830Sed			}
1601192830Sed			else if (*Otemp == '%')
1602192830Sed				putchar(*Otemp);
1603192830Sed			else if (*Otemp == 'n')
1604192830Sed			{
1605192830Sed				p1 ^= 0140;
1606192830Sed				p2 ^= 0140;
1607192830Sed			}
1608192830Sed			else if (*Otemp == 'B')
1609192830Sed			{
1610192830Sed				p1 = (16 * (p1/10)) + (p1 % 10);
1611192830Sed				p2 = (16 * (p2/10)) + (p2 % 10);
1612192830Sed			}
1613192830Sed			else if (*Otemp == 'D')
1614192830Sed			{
1615192830Sed				p1 = (p1 - 2 * (p1 % 16));
1616192830Sed				p2 = (p2 - 2 * (p2 % 16));
1617192830Sed			}
1618192830Sed		}
1619192830Sed		else
1620192830Sed			putchar (*Otemp);
1621192830Sed		Otemp++;
1622192830Sed	}
1623192830Sed	if (delay != 0)
1624192830Sed	{
1625192830Sed		chars = delay * chars_per_millisecond;
1626192830Sed		delay = chars;
1627192830Sed		if ((chars - delay) > 0.0)
1628192830Sed			delay++;
1629192830Sed		for (; delay > 0; delay--)
1630192830Sed			putchar(*String_table[pc__]);
1631192830Sed	}
1632192830Sed	fflush(stdout);
1633192830Sed}
1634192830Sed
1635192830Sed#else
1636192830Sed
1637192830Sed	char *Otemp;		/* temporary string pointer to parse output */
1638192830Sed	float chars;
1639192830Sed	int p[10];
1640192830Sed	int variable[27];
1641192830Sed
1642192830Sedint
1643192830SedOperation(Temp_Stack, place)	/* handle conditional operations	*/
1644192830Sedint Temp_Stack[];
1645192830Sedint place;
1646192830Sed{
1647192830Sed	int temp;
1648192830Sed
1649192830Sed	if (*Otemp == 'd')
1650192830Sed	{
1651192830Sed		Otemp++;
1652192830Sed		temp = Temp_Stack[--place];
1653192830Sed	 	printf("%d", temp);
1654192830Sed	}
1655192830Sed	else if (!strncmp(Otemp, "2d", 2))
1656192830Sed	{
1657192830Sed		temp = Temp_Stack[--place];
1658192830Sed		printf("%2d", temp);
1659192830Sed		Otemp++;
1660192830Sed		Otemp++;
1661192830Sed	}
1662192830Sed	else if (!strncmp(Otemp, "3d", 2))
1663192830Sed	{
1664192830Sed		temp = Temp_Stack[--place];
1665192830Sed		printf("%0d", temp);
1666192830Sed		Otemp++;
1667192830Sed		Otemp++;
1668192830Sed	}
1669192830Sed	else if (!strncmp(Otemp, "02d", 3))
1670192830Sed	{
1671192830Sed		temp = Temp_Stack[--place];
1672192830Sed		printf("%02d", temp);
1673192830Sed		Otemp++;
1674192830Sed		Otemp++;
1675192830Sed		Otemp++;
1676192830Sed	}
1677192830Sed	else if (!strncmp(Otemp, "03d", 3))
1678192830Sed	{
1679192830Sed		temp = Temp_Stack[--place];
1680192830Sed		printf("%03d", temp);
1681192830Sed		Otemp++;
1682192830Sed		Otemp++;
1683192830Sed		Otemp++;
1684192830Sed	}
1685192830Sed	else if (*Otemp == '+')
1686192830Sed	{
1687192830Sed		Otemp++;
1688192830Sed		temp = Temp_Stack[--place];
1689192830Sed		temp += Temp_Stack[--place];
1690192830Sed		Temp_Stack[place++] = temp;
1691192830Sed	}
1692192830Sed	else if (*Otemp == '-')
1693192830Sed	{
1694192830Sed		Otemp++;
1695192830Sed		temp = Temp_Stack[--place];
1696192830Sed		temp -= Temp_Stack[--place];
1697192830Sed		Temp_Stack[place++] = temp;
1698192830Sed	}
1699192830Sed	else if (*Otemp == '*')
1700192830Sed	{
1701192830Sed		Otemp++;
1702192830Sed		temp = Temp_Stack[--place];
1703192830Sed		temp *= Temp_Stack[--place];
1704192830Sed		Temp_Stack[place++] = temp;
1705192830Sed	}
1706192830Sed	else if (*Otemp == '/')
1707192830Sed	{
1708192830Sed		Otemp++;
1709192830Sed		temp = Temp_Stack[--place];
1710192830Sed		temp /= Temp_Stack[--place];
1711192830Sed		Temp_Stack[place++] = temp;
1712192830Sed	}
1713192830Sed	else if (*Otemp == 'm')
1714192830Sed	{
1715192830Sed		Otemp++;
1716192830Sed		temp = Temp_Stack[--place];
1717192830Sed		temp %= Temp_Stack[--place];
1718192830Sed		Temp_Stack[place++] = temp;
1719192830Sed	}
1720192830Sed	else if (*Otemp == '&')
1721192830Sed	{
1722192830Sed		Otemp++;
1723192830Sed		temp = Temp_Stack[--place];
1724192830Sed		temp &= Temp_Stack[--place];
1725192830Sed		Temp_Stack[place++] = temp;
1726192830Sed	}
1727192830Sed	else if (*Otemp == '|')
1728192830Sed	{
1729192830Sed		Otemp++;
1730192830Sed		temp = Temp_Stack[--place];
1731192830Sed		temp |= Temp_Stack[--place];
1732192830Sed		Temp_Stack[place++] = temp;
1733192830Sed	}
1734192830Sed	else if (*Otemp == '^')
1735192830Sed	{
1736192830Sed		Otemp++;
1737192830Sed		temp = Temp_Stack[--place];
1738192830Sed		temp ^= Temp_Stack[--place];
1739192830Sed		Temp_Stack[place++] = temp;
1740192830Sed	}
1741192830Sed	else if (*Otemp == '=')
1742192830Sed	{
1743192830Sed		Otemp++;
1744192830Sed		temp = Temp_Stack[--place];
1745192830Sed		temp = (temp == Temp_Stack[--place]);
1746192830Sed		Temp_Stack[place++] = temp;
1747192830Sed	}
1748192830Sed	else if (*Otemp == '>')
1749192830Sed	{
1750192830Sed		Otemp++;
1751192830Sed		temp = Temp_Stack[--place];
1752192830Sed		temp = temp > Temp_Stack[--place];
1753192830Sed		Temp_Stack[place++] = temp;
1754192830Sed	}
1755192830Sed	else if (*Otemp == '<')
1756192830Sed	{
1757192830Sed		Otemp++;
1758192830Sed		temp = Temp_Stack[--place];
1759192830Sed		temp = temp < Temp_Stack[--place];
1760192830Sed		Temp_Stack[place++] = temp;
1761192830Sed	}
1762192830Sed	else if (*Otemp == 'c')
1763192830Sed	{
1764192830Sed		Otemp++;
1765192830Sed		putchar(Temp_Stack[--place]);
1766192830Sed	}
1767192830Sed	else if (*Otemp == 'i')
1768192830Sed	{
1769192830Sed		Otemp++;
1770192830Sed		p[1]++;
1771192830Sed		p[2]++;
1772192830Sed	}
1773192830Sed	else if (*Otemp == '%')
1774192830Sed	{
1775192830Sed		putchar(*Otemp);
1776192830Sed		Otemp++;
1777192830Sed	}
1778192830Sed	else if (*Otemp == '!')
1779192830Sed	{
1780192830Sed		temp = ! Temp_Stack[--place];
1781192830Sed		Temp_Stack[place++] = temp;
1782192830Sed		Otemp++;
1783192830Sed	}
1784192830Sed	else if (*Otemp == '~')
1785192830Sed	{
1786192830Sed		temp = ~Temp_Stack[--place];
1787192830Sed		Temp_Stack[place++] = temp;
1788192830Sed		Otemp++;
1789192830Sed	}
1790192830Sed	else if (*Otemp == 'p')
1791192830Sed	{
1792192830Sed		Otemp++;
1793192830Sed		Temp_Stack[place++] = p[*Otemp - '0'];
1794192830Sed		Otemp++;
1795192830Sed	}
1796192830Sed	else if (*Otemp == 'P')
1797192830Sed	{
1798192830Sed		Otemp++;
1799192830Sed		Temp_Stack[place++] = variable[*Otemp - 'a'];
1800192830Sed		Otemp++;
1801192830Sed	}
1802192830Sed	else if (*Otemp == 'g')
1803192830Sed	{
1804192830Sed		Otemp++;
1805192830Sed		variable[*Otemp - 'a'] = Temp_Stack[--place];
1806192830Sed		Otemp++;
1807192830Sed	}
1808192830Sed	else if (*Otemp == '\'')
1809192830Sed	{
1810192830Sed		Otemp++;
1811192830Sed		Temp_Stack[place++] = *Otemp;
1812192830Sed		Otemp++;
1813192830Sed		Otemp++;
1814192830Sed	}
1815192830Sed	else if (*Otemp == '{')
1816192830Sed	{
1817192830Sed		Otemp++;
1818192830Sed		temp = atoi(Otemp);
1819192830Sed		Temp_Stack[place++] = temp;
1820192830Sed		while (*Otemp != '}')
1821192830Sed			Otemp++;
1822192830Sed		Otemp++;
1823192830Sed	}
1824192830Sed	return(place);
1825192830Sed}
1826192830Sed
1827192830Sedvoid
1828192830SedInfo_Out(string, p_list, place)	/* interpret the output string if necessary */
1829192830Sedchar *string;
1830192830Sedint p_list[];
1831192830Sedint place;
1832192830Sed{
1833192830Sed	char *tchar;
1834192830Sed	int delay;
1835192830Sed	int temp;
1836192830Sed	int Cond_FLAG;
1837192830Sed	int EVAL;
1838192830Sed	int Cond_Stack[128];
1839192830Sed	int Cond_place;
1840192830Sed	int Stack[128];
1841192830Sed	int Top_of_stack;
1842192830Sed
1843192830Sed	if (string == NULL)
1844192830Sed		return;
1845192830Sed
1846192830Sed	Cond_FLAG = FALSE;
1847192830Sed	Cond_place = 0;
1848192830Sed	Top_of_stack = 0;
1849192830Sed	p[0] = 0;
1850192830Sed	p[1] = 0;
1851192830Sed	p[2] = 0;
1852192830Sed	p[3] = 0;
1853192830Sed	p[4] = 0;
1854192830Sed	p[5] = 0;
1855192830Sed	p[6] = 0;
1856192830Sed	p[7] = 0;
1857192830Sed	p[8] = 0;
1858192830Sed	p[9] = 0;
1859192830Sed	if (p_list != NULL)
1860192830Sed	{
1861192830Sed		for (temp = 1; (place != 0); temp++)
1862192830Sed		{
1863192830Sed			p[temp] = p_list[--place];
1864192830Sed		}
1865192830Sed	}
1866192830Sed	delay = 0;
1867192830Sed	Otemp = string;
1868192914Sed	while (*Otemp != '\0')
1869192830Sed	{
1870192830Sed		if (*Otemp == '%')
1871192830Sed		{
1872192830Sed			Otemp++;
1873192830Sed			if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
1874192830Sed			{
1875192830Sed				if (*Otemp == '?')
1876192830Sed				{
1877192830Sed					Otemp++;
1878192830Sed					Cond_FLAG = TRUE;
1879192830Sed					EVAL = TRUE;
1880192830Sed					while (EVAL)
1881192830Sed					{
1882192830Sed						/*
1883192830Sed						 |  find the end of the
1884192830Sed						 |  conditional statement
1885192830Sed						 */
1886192914Sed						while ((strncmp(Otemp, "%t", 2)) && (*Otemp != '\0'))
1887192830Sed						{
1888192830Sed							/*
1889192830Sed							 |  move past '%'
1890192830Sed							 */
1891192830Sed							Otemp++;
1892192830Sed							Cond_place = Operation(Cond_Stack, Cond_place);
1893192830Sed						}
1894192830Sed
1895192830Sed						/*
1896192830Sed						 |  if condition is true
1897192830Sed						 */
1898192830Sed						if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
1899192830Sed						{
1900192830Sed							/*
1901192830Sed							 |  end conditional
1902192830Sed							 |  parsing
1903192830Sed							 */
1904192830Sed							EVAL = FALSE;
1905192830Sed							Otemp++;
1906192830Sed							Otemp++;
1907192830Sed						}
1908192830Sed						else	/* condition is false */
1909192830Sed						{
1910192830Sed							/*
1911192830Sed							 |  find 'else' or end
1912192830Sed							 |  of if statement
1913192830Sed							 */
1914192914Sed							while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != '\0'))
1915192830Sed								Otemp++;
1916192830Sed							/*
1917192830Sed							 |  if an 'else' found
1918192830Sed							 */
1919192914Sed							if ((*Otemp != '\0') && (!strncmp(Otemp, "%e", 2)))
1920192830Sed							{
1921192830Sed								Otemp++;
1922192830Sed								Otemp++;
1923192830Sed								tchar = Otemp;
1924192830Sed								/*
1925192830Sed								 |  check for 'then' part
1926192830Sed								 */
1927192914Sed								while ((*tchar != '\0') && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
1928192830Sed									tchar++;
1929192830Sed								/*
1930192830Sed								 |  if end of string
1931192830Sed								 */
1932192914Sed								if (*tchar == '\0')
1933192830Sed								{
1934192830Sed									EVAL = FALSE;
1935192830Sed									Cond_FLAG = FALSE;
1936192830Sed									Otemp = tchar;
1937192830Sed								}
1938192830Sed								/*
1939192830Sed								 |  if end of if found,
1940192830Sed								 |  set up to parse
1941192830Sed								 |  info
1942192830Sed								 */
1943192830Sed								else if (!strncmp(tchar, "%;", 2))
1944192830Sed									EVAL = FALSE;
1945192830Sed								/*
1946192830Sed								 |  otherwise, check
1947192830Sed								 |  conditional in
1948192830Sed								 |  'else'
1949192830Sed								 */
1950192830Sed							}
1951192830Sed							/*
1952192830Sed							 |  if end of if found,
1953192830Sed							 |  get out of if
1954192830Sed							 |  statement
1955192830Sed							 */
1956192914Sed							else if ((*Otemp != '\0') && (!strncmp(Otemp, "%;", 2)))
1957192830Sed							{
1958192830Sed								EVAL = FALSE;
1959192830Sed								Otemp++;
1960192830Sed								Otemp++;
1961192830Sed							}
1962192830Sed							else /* Otemp == NULL */
1963192830Sed							{
1964192830Sed								EVAL = FALSE;
1965192830Sed								Cond_FLAG = FALSE;
1966192830Sed							}
1967192830Sed						}
1968192830Sed					}
1969192830Sed				}
1970192830Sed				else
1971192830Sed				{
1972192830Sed					Otemp++;
1973192830Sed					Cond_FLAG = FALSE;
1974192830Sed					if (*Otemp != ';')
1975192830Sed					{
1976192914Sed						while ((*Otemp != '\0') && (strncmp(Otemp, "%;", 2)))
1977192830Sed							Otemp++;
1978192914Sed						if (*Otemp != '\0')
1979192830Sed						{
1980192830Sed							Otemp++;
1981192830Sed							Otemp++;
1982192830Sed						}
1983192830Sed					}
1984192830Sed					else
1985192830Sed						Otemp++;
1986192830Sed				}
1987192830Sed			}
1988192830Sed			else
1989192830Sed			{
1990192830Sed				Top_of_stack = Operation(Stack, Top_of_stack);
1991192830Sed			}
1992192830Sed		}
1993192830Sed		else if (!strncmp(Otemp, "$<", 2))
1994192830Sed		{
1995192830Sed			Otemp++;
1996192830Sed			Otemp++;
1997192830Sed			delay = atoi(Otemp);
1998192830Sed			while (*Otemp != '>')
1999192830Sed				Otemp++;
2000192830Sed			Otemp++;
2001192830Sed			chars = delay * chars_per_millisecond;
2002192830Sed			delay = chars;
2003192830Sed			if ((chars - delay) > 0.0)
2004192830Sed				delay++;
2005192830Sed			if (String_table[pc__] == NULL)
2006192830Sed				temp = 0;
2007192830Sed			else
2008192830Sed				temp = *String_table[pc__];
2009192830Sed			for (; delay > 0; delay--)
2010192830Sed				putc(temp, stdout);
2011192830Sed		}
2012192830Sed		else
2013192830Sed		{
2014192830Sed			putchar(*Otemp);
2015192830Sed			Otemp++;
2016192830Sed		}
2017192830Sed	}
2018192830Sed	fflush(stdout);
2019192830Sed}
2020192830Sed#endif
2021192830Sed
2022192830Sedvoid
2023192830Sedwmove(window, row, column)	/* move cursor to indicated position in window */
2024192830SedWINDOW *window;
2025192830Sedint row, column;
2026192830Sed{
2027192830Sed	if ((row < window->Num_lines) && (column < window->Num_cols))
2028192830Sed	{
2029192830Sed		window->LX = column;
2030192830Sed		window->LY = row;
2031192830Sed	}
2032192830Sed}
2033192830Sed
2034192830Sedvoid
2035192830Sedclear_line(line, column, cols)
2036192830Sedstruct _line *line;
2037192830Sedint column;
2038192830Sedint cols;
2039192830Sed{
2040192830Sed	int j;
2041192830Sed
2042192830Sed	if (column > line->last_char)
2043192830Sed	{
2044192830Sed		for (j = line->last_char; j < column; j++)
2045192830Sed		{
2046192830Sed			line->row[j] = ' ';
2047192914Sed			line->attributes[j] = '\0';
2048192830Sed		}
2049192830Sed	}
2050192830Sed	line->last_char = column;
2051192914Sed	line->row[column] = '\0';
2052192914Sed	line->attributes[column] = '\0';
2053192830Sed	line->changed = TRUE;
2054192830Sed}
2055192830Sed
2056192830Sedvoid
2057192830Sedwerase(window)			/* clear the specified window		*/
2058192830SedWINDOW *window;
2059192830Sed{
2060192830Sed	int i;
2061192830Sed	struct _line *tmp;
2062192830Sed
2063192830Sed	window->SCROLL_CLEAR = CLEAR;
2064192830Sed	window->scroll_up = window->scroll_down = 0;
2065192830Sed	for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
2066192830Sed		clear_line(tmp, 0, window->Num_cols);
2067192830Sed}
2068192830Sed
2069192830Sedvoid
2070192830Sedwclrtoeol(window)	/* erase from current cursor position to end of line */
2071192830SedWINDOW *window;
2072192830Sed{
2073192830Sed	int column, row;
2074192830Sed	struct _line *tmp;
2075192830Sed
2076192830Sed	window->SCROLL_CLEAR = CHANGE;
2077192830Sed	column = window->LX;
2078192830Sed	row = window->LY;
2079192830Sed	for (row = 0, tmp = window->first_line; row < window->LY; row++)
2080192830Sed		tmp = tmp->next_screen;
2081192830Sed	clear_line(tmp, column, window->Num_cols);
2082192830Sed}
2083192830Sed
2084192830Sedvoid
2085192830Sedwrefresh(window)		/* flush all previous output		*/
2086192830SedWINDOW *window;
2087192830Sed{
2088192830Sed	wnoutrefresh(window);
2089192830Sed#ifdef DIAG
2090192830Sed{
2091192830Sed	struct _line *temp;
2092192830Sed	int value;
2093192830Sed	fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
2094192830Sed	for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
2095192830Sed	{
2096192830Sed		if (temp->number == -1)
2097192830Sed			fprintf(stderr, "line moved ");
2098192830Sed		if (temp->scroll)
2099192830Sed			fprintf(stderr, "scroll_x is set:  ");
2100192830Sed		fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2101192830Sed	}
2102192830Sed	fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
2103192830Sed	fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
2104192830Sed	for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
2105192830Sed	{
2106192830Sed		if (temp->number == -1)
2107192830Sed			fprintf(stderr, "line moved ");
2108192830Sed		if (temp->scroll)
2109192830Sed			fprintf(stderr, "scroll_x is set:  ");
2110192830Sed		fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
2111192830Sed	}
2112192830Sed	fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
2113192830Sed	for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
2114192830Sed		fprintf(stderr, "line=%s|\n", temp->row);
2115192830Sed}
2116192830Sed#endif
2117192830Sed	doupdate();
2118192830Sed	virtual_scr->SCROLL_CLEAR = FALSE;
2119192830Sed	virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
2120192830Sed	fflush(stdout);
2121192830Sed}
2122192830Sed
2123192830Sedvoid
2124192830Sedtouchwin(window)
2125192830SedWINDOW *window;
2126192830Sed{
2127192830Sed	struct _line *user_line;
2128192830Sed	int line_counter = 0;
2129192830Sed
2130192830Sed	for (line_counter = 0, user_line = window->first_line;
2131192830Sed		line_counter < window->Num_lines; line_counter++)
2132192830Sed	{
2133192830Sed		user_line->changed = TRUE;
2134192830Sed	}
2135192830Sed	window->SCROLL_CLEAR = TRUE;
2136192830Sed}
2137192830Sed
2138192830Sedvoid
2139192830Sedwnoutrefresh(window)
2140192830SedWINDOW *window;
2141192830Sed{
2142192830Sed	struct _line *user_line;
2143192830Sed	struct _line *virtual_line;
2144192830Sed	int line_counter = 0;
2145192830Sed	int user_col = 0;
2146192830Sed	int virt_col = 0;
2147192830Sed
2148192830Sed	if (window->SR >= virtual_scr->Num_lines)
2149192830Sed		return;
2150192830Sed	user_line = window->first_line;
2151192830Sed	virtual_line = virtual_scr->first_line;
2152192830Sed	virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
2153192830Sed	virtual_scr->LX = window->LX + window->SC;
2154192830Sed	virtual_scr->LY = window->LY + window->SR;
2155192830Sed	virtual_scr->scroll_up = window->scroll_up;
2156192830Sed	virtual_scr->scroll_down = window->scroll_down;
2157192830Sed	if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
2158192830Sed		return;
2159192830Sed	for (line_counter = 0; line_counter < window->SR; line_counter++)
2160192830Sed	{
2161192830Sed		virtual_line = virtual_line->next_screen;
2162192830Sed	}
2163192830Sed	for (line_counter = 0; (line_counter < window->Num_lines)
2164192830Sed		&& ((line_counter + window->SR) < virtual_scr->Num_lines);
2165192830Sed			line_counter++)
2166192830Sed	{
2167192830Sed		if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
2168192830Sed		{
2169192830Sed			for (user_col = 0, virt_col = window->SC;
2170192830Sed				(virt_col < virtual_scr->Num_cols)
2171192830Sed				  && (user_col < user_line->last_char);
2172192830Sed				  	virt_col++, user_col++)
2173192830Sed			{
2174192830Sed				virtual_line->row[virt_col] = user_line->row[user_col];
2175192830Sed				virtual_line->attributes[virt_col] = user_line->attributes[user_col];
2176192830Sed			}
2177192830Sed			for (user_col = user_line->last_char,
2178192830Sed			     virt_col = window->SC + user_line->last_char;
2179192830Sed				(virt_col < virtual_scr->Num_cols)
2180192830Sed				  && (user_col < window->Num_cols);
2181192830Sed				  	virt_col++, user_col++)
2182192830Sed			{
2183192830Sed				virtual_line->row[virt_col] = ' ';
2184192914Sed				virtual_line->attributes[virt_col] = '\0';
2185192830Sed			}
2186192830Sed		}
2187192830Sed		if (virtual_scr->Num_cols != window->Num_cols)
2188192830Sed		{
2189192830Sed			if (virtual_line->last_char < (user_line->last_char + window->SC))
2190192830Sed			{
2191192914Sed				if (virtual_line->row[virtual_line->last_char] == '\0')
2192192830Sed					virtual_line->row[virtual_line->last_char] = ' ';
2193192830Sed				virtual_line->last_char =
2194192830Sed					min(virtual_scr->Num_cols,
2195192830Sed					  (user_line->last_char + window->SC));
2196192830Sed			}
2197192830Sed		}
2198192830Sed		else
2199192830Sed			virtual_line->last_char = user_line->last_char;
2200192914Sed		virtual_line->row[virtual_line->last_char] = '\0';
2201192830Sed		virtual_line->changed = user_line->changed;
2202192830Sed		virtual_line = virtual_line->next_screen;
2203192830Sed		user_line = user_line->next_screen;
2204192830Sed	}
2205192830Sed	window->SCROLL_CLEAR = FALSE;
2206192830Sed	window->scroll_up = window->scroll_down = 0;
2207192830Sed	last_window_refreshed = window;
2208192830Sed}
2209192830Sed
2210192830Sedvoid
2211192830Sedflushinp()			/* flush input				*/
2212192830Sed{
2213192830Sed}
2214192830Sed
2215192830Sedvoid
2216192830Sedungetch(c)			/* push a character back on input	*/
2217192830Sedint c;
2218192830Sed{
2219192830Sed	if (bufp < 100)
2220192830Sed		in_buff[bufp++] = c;
2221192830Sed}
2222192830Sed
2223192830Sed#ifdef BSD_SELECT
2224192830Sedint
2225192830Sedtimed_getchar()
2226192830Sed{
2227192830Sed	struct timeval tv;
2228192830Sed	fd_set fds;
2229192830Sed	int ret_val;
2230192830Sed	int nfds = 1;
2231192830Sed	char temp;
2232192830Sed
2233192830Sed	FD_ZERO(&fds);
2234192830Sed	tv.tv_sec = 0;
2235192830Sed	tv.tv_usec = 500000;  /* half a second */
2236192830Sed	FD_SET(0, &fds);
2237192830Sed	Time_Out = FALSE; /* just in case */
2238192830Sed
2239192830Sed	ret_val = select(nfds, &fds, 0, 0, &tv);
2240192830Sed
2241192830Sed	/*
2242192830Sed	 |	if ret_val is less than zero, there was no input
2243192830Sed	 |	otherwise, get a character and return it
2244192830Sed	 */
2245192830Sed
2246192830Sed	if (ret_val <= 0)
2247192830Sed	{
2248192830Sed		Time_Out = TRUE;
2249192830Sed		return(-1);
2250192830Sed	}
2251192830Sed
2252192830Sed	return(read(0, &temp, 1)? temp : -1);
2253192830Sed}
2254192830Sed#endif
2255192830Sed
2256192830Sedint
2257192830Sedwgetch(window)			/* get character from specified window	*/
2258192830SedWINDOW *window;
2259192830Sed{
2260192830Sed	int in_value;
2261192830Sed	char temp;
2262192830Sed#ifndef SYS5
2263192830Sed	int old_arg;
2264192830Sed#endif /* SYS5 */
2265192830Sed
2266192830Sed#ifdef BSD_SELECT
2267192830Sed	if (Noblock)
2268192830Sed		in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
2269192830Sed	else
2270192830Sed		in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2271192830Sed#else /* BSD_SELECT */
2272192830Sed#ifdef SYS5
2273192830Sed	in_value = ((bufp > 0) ? in_buff[--bufp] :
2274192830Sed					(read(0, &temp, 1)> 0) ? temp : -1);
2275192830Sed#else /* SYS5 */
2276192830Sed	if (Noblock)
2277192830Sed	{
2278192830Sed		Time_Out = FALSE;
2279192830Sed		old_arg = fcntl(0, F_GETFL, 0);
2280192830Sed		in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
2281192830Sed	}
2282192830Sed	in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
2283192830Sed	if (Noblock)
2284192830Sed	{
2285192830Sed		fcntl(0, F_SETFL, old_arg);
2286192830Sed		if (Time_Out)
2287192830Sed			in_value = -1;
2288192830Sed	}
2289192830Sed#endif /* SYS5 */
2290192830Sed#endif /* BSD_SELECT */
2291192830Sed
2292192830Sed	if (in_value != -1)
2293192830Sed	{
2294192830Sed		in_value &= 0xff;
2295192830Sed		if ((Parity) && (Num_bits < 8))
2296192830Sed				/* strip eighth bit if parity in use */
2297192830Sed		in_value &= 0177;
2298192830Sed	}
2299192830Sed	else if (interrupt_flag)
2300192830Sed	{
2301192830Sed		interrupt_flag = FALSE;
2302192830Sed		in_value = wgetch(window);
2303192830Sed	}
2304192830Sed
2305192830Sed	if ((in_value == '\033') || (in_value == '\037'))/* escape character */
2306192830Sed		in_value = Get_key(in_value);
2307192830Sed	return(in_value);
2308192830Sed}
2309192830Sed
2310192830Sed#ifndef BSD_SELECT
2311192830Sedvoid
2312192830SedClear(arg)		/* notify that time out has occurred	*/
2313192830Sedint arg;
2314192830Sed{
2315192830Sed	Time_Out = TRUE;
2316192830Sed#ifdef DEBUG
2317192830Sedfprintf(stderr, "inside Clear()\n");
2318192830Sedfflush(stderr);
2319192830Sed#endif /* DEBUG */
2320192830Sed}
2321192830Sed#endif /* BSD_SELECT */
2322192830Sed
2323192830Sedint
2324192830SedGet_key(first_char)			/* try to decode key sequence	*/
2325192830Sedint first_char;				/* first character of sequence	*/
2326192830Sed{
2327192830Sed	int in_char;
2328192830Sed	int Count;
2329192830Sed	char string[128];
2330192830Sed	char *Gtemp;
2331192830Sed	int Found;
2332192830Sed#ifdef SYS5
2333192830Sed	struct termio Gterminal;
2334192830Sed#else
2335192830Sed	struct sgttyb Gterminal;
2336192830Sed#endif
2337192830Sed	struct KEY_STACK *St_point;
2338192830Sed#if (!defined( BSD_SELECT)) || (!defined(SYS5))
2339192830Sed	int value;
2340192830Sed#endif /* BSD_SELECT */
2341192830Sed
2342192830Sed	Count = 0;
2343192830Sed	Gtemp = string;
2344192830Sed	string[Count++] = first_char;
2345192914Sed	string[Count] = '\0';
2346192830Sed	Time_Out = FALSE;
2347192830Sed#ifndef BSD_SELECT
2348192830Sed	signal(SIGALRM, Clear);
2349192830Sed	value = alarm(1);
2350192830Sed#endif /* BSD_SELECT */
2351192830Sed	Noblock = TRUE;
2352192830Sed#ifdef SYS5
2353192830Sed	Gterminal.c_cc[VTIME] = 0;		/* timeout value	*/
2354192830Sed	Gterminal.c_lflag &= ~ICANON;	/* disable canonical operation	*/
2355192830Sed	Gterminal.c_lflag &= ~ECHO;		/* disable echo		*/
2356192830Sed#endif
2357192830Sed	Count = 1;
2358192830Sed	Found = FALSE;
2359192830Sed	while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
2360192830Sed	{
2361192830Sed		in_char = wgetch(stdscr);
2362192830Sed#ifdef DEBUG
2363192830Sedfprintf(stderr, "back in GetKey()\n");
2364192830Sedfflush(stderr);
2365192830Sed#endif /* DEBUG */
2366192830Sed		if (in_char != -1)
2367192830Sed		{
2368192830Sed			string[Count++] = in_char;
2369192914Sed			string[Count] = '\0';
2370192830Sed			St_point = KEY_TOS;
2371192830Sed			while ((St_point != NULL) && (!Found))
2372192830Sed			{
2373192830Sed				if (!strcmp(string, St_point->element->string))
2374192830Sed					Found = TRUE;
2375192830Sed				else
2376192830Sed					St_point = St_point->next;
2377192830Sed			}
2378192830Sed		}
2379192830Sed	}
2380192830Sed#ifndef BSD_SELECT
2381192830Sed	if (!Time_Out)
2382192830Sed		value = alarm(0);
2383192830Sed#endif /* BSD_SELECT */
2384192830Sed#ifdef SYS5
2385192830Sed/*	value = ioctl(0, TCSETA, &Terminal);*/
2386192830Sed#else
2387192830Sed	value = ioctl(0, TIOCSETP, &Terminal);
2388192830Sed/*	value = fcntl(0, F_SETFL, old_arg);*/
2389192830Sed#endif
2390192830Sed	Noblock = FALSE;
2391192830Sed	if (Found)
2392192830Sed	{
2393192830Sed		return(St_point->element->value);
2394192830Sed	}
2395192830Sed	else
2396192830Sed	{
2397192830Sed		while (Count > 1)
2398192830Sed		{
2399192830Sed			if ((string[--Count] != -1) &&
2400192830Sed					((unsigned char) (string[Count]) != 255))
2401192830Sed			{
2402192830Sed#ifdef DIAG
2403192830Sedfprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
2404192830Sed#endif
2405192830Sed				ungetch(string[Count]);
2406192830Sed			}
2407192830Sed		}
2408192830Sed		return(first_char);
2409192830Sed	}
2410192830Sed}
2411192830Sed
2412192830Sedvoid
2413192830Sedwaddch(window, c)	/* output the character in the specified window	*/
2414192830SedWINDOW *window;
2415192830Sedint c;
2416192830Sed{
2417192830Sed	int column, j;
2418192830Sed	int shift;	/* number of spaces to shift if a tab		*/
2419192830Sed	struct _line *tmpline;
2420192830Sed
2421192830Sed#ifdef DIAG
2422192830Sed/*printf("starting waddch \n");fflush(stdout);*/
2423192830Sed#endif
2424192830Sed	column = window->LX;
2425192830Sed	if (c == '\t')
2426192830Sed	{
2427192830Sed		shift = (column + 1) % 8;
2428192830Sed		if (shift == 0)
2429192830Sed			shift++;
2430192830Sed		else
2431192830Sed			shift = 9 - shift;
2432192830Sed		while (shift > 0)
2433192830Sed		{
2434192830Sed			shift--;
2435192830Sed			waddch(window, ' ');
2436192830Sed		}
2437192830Sed	}
2438192830Sed	else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
2439192830Sed	{
2440192830Sed		if ((c == '~') && (Booleans[hz__]))
2441192830Sed			c = '@';
2442192830Sed
2443192830Sed		if (( c != '\b') && (c != '\n') && (c != '\r'))
2444192830Sed		{
2445192830Sed			tmpline = window->line_array[window->LY];
2446192830Sed			tmpline->row[column] = c;
2447192830Sed			tmpline->attributes[column] = window->Attrib;
2448192830Sed			tmpline->changed = TRUE;
2449192830Sed			if (column >= tmpline->last_char)
2450192830Sed			{
2451192830Sed				if (column > tmpline->last_char)
2452192830Sed					for (j = tmpline->last_char; j < column; j++)
2453192830Sed					{
2454192830Sed						tmpline->row[j] = ' ';
2455192914Sed						tmpline->attributes[j] = '\0';
2456192830Sed					}
2457192914Sed				tmpline->row[column + 1] = '\0';
2458192914Sed				tmpline->attributes[column + 1] = '\0';
2459192830Sed				tmpline->last_char = column + 1;
2460192830Sed			}
2461192830Sed		}
2462192830Sed		if (c == '\n')
2463192830Sed		{
2464192830Sed			wclrtoeol(window);
2465192830Sed			window->LX = window->Num_cols;
2466192830Sed		}
2467192830Sed		else if (c == '\r')
2468192830Sed			window->LX = 0;
2469192830Sed		else if (c == '\b')
2470192830Sed			window->LX--;
2471192830Sed		else
2472192830Sed			window->LX++;
2473192830Sed	}
2474192830Sed	if (window->LX >= window->Num_cols)
2475192830Sed	{
2476192830Sed		window->LX = 0;
2477192830Sed		window->LY++;
2478192830Sed		if (window->LY >= window->Num_lines)
2479192830Sed		{
2480192830Sed			window->LY = window->Num_lines - 1;
2481192830Sed/*			window->LY = row;
2482192830Sed			wmove(window, 0, 0);
2483192830Sed			wdeleteln(window);
2484192830Sed			wmove(window, row, 0);*/
2485192830Sed		}
2486192830Sed	}
2487192830Sed	window->SCROLL_CLEAR = CHANGE;
2488192830Sed}
2489192830Sed
2490192830Sedvoid
2491192830Sedwinsertln(window)	/* insert a blank line into the specified window */
2492192830SedWINDOW *window;
2493192830Sed{
2494192830Sed	int row, column;
2495192830Sed	struct _line *tmp;
2496192830Sed	struct _line *tmp1;
2497192830Sed
2498192830Sed	window->scroll_down += 1;
2499192830Sed	window->SCROLL_CLEAR = SCROLL;
2500192830Sed	column = window->LX;
2501192830Sed	row = window->LY;
2502192830Sed	for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
2503192830Sed		tmp = tmp->next_screen;
2504192830Sed	if (tmp->prev_screen != NULL)
2505192830Sed		tmp->prev_screen->next_screen = NULL;
2506192830Sed	tmp1 = tmp;
2507192830Sed	clear_line(tmp1, 0, window->Num_cols);
2508192830Sed	tmp1->number = -1;
2509192830Sed	for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
2510192830Sed		tmp = tmp->next_screen;
2511192830Sed	if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
2512192830Sed	{
2513192830Sed		tmp1->next_screen = tmp->next_screen;
2514192830Sed		tmp->next_screen = tmp1;
2515192830Sed		tmp->changed = TRUE;
2516192830Sed		tmp->next_screen->prev_screen = tmp;
2517192830Sed	}
2518192830Sed	else if (window->Num_lines > 1)
2519192830Sed	{
2520192830Sed		if (tmp->prev_screen != NULL)
2521192830Sed			tmp->prev_screen->next_screen = tmp1;
2522192830Sed		tmp1->prev_screen = tmp->prev_screen;
2523192830Sed		tmp->prev_screen = tmp1;
2524192830Sed		tmp1->next_screen = tmp;
2525192830Sed		tmp->changed = TRUE;
2526192830Sed		tmp->scroll = DOWN;
2527192830Sed	}
2528192830Sed	if (window->LY == 0)
2529192830Sed		window->first_line = tmp1;
2530192830Sed
2531192830Sed	for (row = 0, tmp1 = window->first_line;
2532192830Sed		row < window->Num_lines; row++)
2533192830Sed	{
2534192830Sed		window->line_array[row] = tmp1;
2535192830Sed		tmp1 = tmp1->next_screen;
2536192830Sed	}
2537192830Sed}
2538192830Sed
2539192830Sedvoid
2540192830Sedwdeleteln(window)	/* delete a line in the specified window */
2541192830SedWINDOW *window;
2542192830Sed{
2543192830Sed	int row, column;
2544192830Sed	struct _line *tmp;
2545192830Sed	struct _line  *tmpline;
2546192830Sed
2547192830Sed	if (window->Num_lines > 1)
2548192830Sed	{
2549192830Sed		window->scroll_up += 1;
2550192830Sed		window->SCROLL_CLEAR = SCROLL;
2551192830Sed		column = window->LX;
2552192830Sed		row = window->LY;
2553192830Sed		for (row = 0, tmp = window->first_line; row < window->LY; row++)
2554192830Sed			tmp = tmp->next_screen;
2555192830Sed		if (window->LY == 0)
2556192830Sed			window->first_line = tmp->next_screen;
2557192830Sed		if (tmp->prev_screen != NULL)
2558192830Sed			tmp->prev_screen->next_screen = tmp->next_screen;
2559192830Sed		if (tmp->next_screen != NULL)
2560192830Sed		{
2561192830Sed			tmp->next_screen->changed = TRUE;
2562192830Sed			tmp->next_screen->scroll = UP;
2563192830Sed			tmp->next_screen->prev_screen = tmp->prev_screen;
2564192830Sed		}
2565192830Sed		tmpline = tmp;
2566192830Sed		clear_line(tmpline, 0, window->Num_cols);
2567192830Sed		tmpline->number = -1;
2568192830Sed		for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
2569192830Sed			tmp = tmp->next_screen;
2570192830Sed		if (tmp != NULL)
2571192830Sed		{
2572192830Sed			tmp->next_screen = tmpline;
2573192830Sed			tmp->next_screen->prev_screen = tmp;
2574192830Sed			tmp->changed = TRUE;
2575192830Sed			tmp = tmp->next_screen;
2576192830Sed		}
2577192830Sed		else
2578192830Sed			tmp = tmpline;
2579192830Sed		tmp->next_screen = NULL;
2580192830Sed
2581192830Sed		for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
2582192830Sed		{
2583192830Sed			window->line_array[row] = tmp;
2584192830Sed			tmp = tmp->next_screen;
2585192830Sed		}
2586192830Sed	}
2587192830Sed	else
2588192830Sed	{
2589192830Sed		clear_line(window->first_line, 0, window->Num_cols);
2590192830Sed	}
2591192830Sed}
2592192830Sed
2593192830Sedvoid
2594192830Sedwclrtobot(window)	/* delete from current position to end of the window */
2595192830SedWINDOW *window;
2596192830Sed{
2597192830Sed	int row, column;
2598192830Sed	struct _line *tmp;
2599192830Sed
2600192830Sed	window->SCROLL_CLEAR |= CLEAR;
2601192830Sed	column = window->LX;
2602192830Sed	row = window->LY;
2603192830Sed	for (row = 0, tmp = window->first_line; row < window->LY; row++)
2604192830Sed		tmp = tmp->next_screen;
2605192830Sed	clear_line(tmp, column, window->Num_cols);
2606192830Sed	for (row = (window->LY + 1); row < window->Num_lines; row++)
2607192830Sed	{
2608192830Sed		tmp = tmp->next_screen;
2609192830Sed		clear_line(tmp, 0, window->Num_cols);
2610192830Sed	}
2611192830Sed	wmove(window, row, column);
2612192830Sed}
2613192830Sed
2614192830Sedvoid
2615192830Sedwstandout(window)	/* begin standout mode in window	*/
2616192830SedWINDOW *window;
2617192830Sed{
2618192830Sed	if (Numbers[sg__] < 1)	/* if not magic cookie glitch	*/
2619192830Sed		window->Attrib |= A_STANDOUT;
2620192830Sed}
2621192830Sed
2622192830Sedvoid
2623192830Sedwstandend(window)	/* end standout mode in window	*/
2624192830SedWINDOW *window;
2625192830Sed{
2626192830Sed	window->Attrib &= ~A_STANDOUT;
2627192830Sed}
2628192830Sed
2629192830Sedvoid
2630192830Sedwaddstr(window, string)	/* write 'string' in window	*/
2631192830SedWINDOW *window;
2632192830Sedchar *string;
2633192830Sed{
2634192830Sed	char *wstring;
2635192830Sed
2636192914Sed	for (wstring = string; *wstring != '\0'; wstring++)
2637192830Sed		waddch(window, *wstring);
2638192830Sed}
2639192830Sed
2640192830Sedvoid
2641192830Sedclearok(window, flag)	/* erase screen and redraw at next refresh	*/
2642192830SedWINDOW *window;
2643192830Sedint flag;
2644192830Sed{
2645192830Sed	Repaint_screen = TRUE;
2646192830Sed}
2647192830Sed
2648192830Sed
2649192830Sedvoid
2650192830Sedecho()			/* turn on echoing				*/
2651192830Sed{
2652192830Sed	int value;
2653192830Sed
2654192830Sed#ifdef SYS5
2655192830Sed	Terminal.c_lflag |= ECHO;		/* enable echo		*/
2656192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2657192830Sed#else
2658192830Sed	Terminal.sg_flags |= ECHO;		/* enable echo		*/
2659192830Sed	value = ioctl(0, TIOCSETP, &Terminal);	/* set characteristics	*/
2660192830Sed#endif
2661192830Sed}
2662192830Sed
2663192830Sedvoid
2664192830Sednoecho()		/* turn off echoing				*/
2665192830Sed{
2666192830Sed	int value;
2667192830Sed
2668192830Sed#ifdef SYS5
2669192830Sed	Terminal.c_lflag &= ~ECHO;		/* disable echo		*/
2670192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2671192830Sed#else
2672192830Sed	Terminal.sg_flags &= ~ECHO;		/* disable echo		*/
2673192830Sed	value = ioctl(0, TIOCSETP, &Terminal);	/* set characteristics	*/
2674192830Sed#endif
2675192830Sed}
2676192830Sed
2677192830Sedvoid
2678192830Sedraw()			/* set to read characters immediately		*/
2679192830Sed{
2680192830Sed	int value;
2681192830Sed
2682192830Sed#ifdef SYS5
2683192830Sed	Intr = Terminal.c_cc[VINTR];	/* get the interrupt character	*/
2684192830Sed	Terminal.c_lflag &= ~ICANON;	/* disable canonical operation	*/
2685192830Sed	Terminal.c_lflag &= ~ISIG;	/* disable signal checking	*/
2686192830Sed#ifdef FLUSHO
2687192830Sed	Terminal.c_lflag &= ~FLUSHO;
2688192830Sed#endif
2689192830Sed#ifdef PENDIN
2690192830Sed	Terminal.c_lflag &= ~PENDIN;
2691192830Sed#endif
2692192830Sed#ifdef IEXTEN
2693192830Sed	Terminal.c_lflag &= ~IEXTEN;
2694192830Sed#endif
2695192830Sed	Terminal.c_cc[VMIN] = 1;		/* minimum of one character */
2696192830Sed	Terminal.c_cc[VTIME] = 0;		/* timeout value	*/
2697192830Sed	Terminal.c_cc[VINTR] = 0;		/* eliminate interrupt	*/
2698192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2699192830Sed#else
2700192830Sed	Terminal.sg_flags |= RAW;	/* enable raw mode		*/
2701192830Sed	value = ioctl(0, TIOCSETP, &Terminal);	/* set characteristics	*/
2702192830Sed#endif
2703192830Sed}
2704192830Sed
2705192830Sedvoid
2706192830Sednoraw()			/* set to normal character read mode		*/
2707192830Sed{
2708192830Sed	int value;
2709192830Sed
2710192830Sed#ifdef SYS5
2711192830Sed	Terminal.c_lflag |= ICANON;	/* enable canonical operation	*/
2712192830Sed	Terminal.c_lflag |= ISIG;	/* enable signal checking	*/
2713192830Sed	Terminal.c_cc[VEOF] = 4;		/* EOF character = 4	*/
2714192914Sed	Terminal.c_cc[VEOL] = '\0';	/* EOL = 0		*/
2715192830Sed	Terminal.c_cc[VINTR] = Intr;		/* reset interrupt char	*/
2716192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2717192830Sed#else
2718192830Sed	Terminal.sg_flags &= ~RAW;	/* disable raw mode		*/
2719192830Sed	value = ioctl(0, TIOCSETP, &Terminal);	/* set characteristics	*/
2720192830Sed/*	old_arg = fcntl(0, F_GETFL, 0);
2721192830Sed	value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2722192830Sed#endif
2723192830Sed}
2724192830Sed
2725192830Sedvoid
2726192830Sednl()
2727192830Sed{
2728192830Sed	int value;
2729192830Sed
2730192830Sed#ifdef SYS5
2731192830Sed	Terminal.c_iflag |= ICRNL;	/* enable carriage-return to line-feed mapping	*/
2732192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2733192830Sed#endif
2734192830Sed}
2735192830Sed
2736192830Sedvoid
2737192830Sednonl()
2738192830Sed{
2739192830Sed	int value;
2740192830Sed
2741192830Sed#ifdef SYS5
2742192830Sed	Terminal.c_iflag &= ~ICRNL;	/* disable carriage-return to line-feed mapping	*/
2743192830Sed	Terminal.c_iflag &= ~IGNCR;	/* do not ignore carriage-return	*/
2744192830Sed	value = ioctl(0, TCSETA, &Terminal);	/* set characteristics	*/
2745192830Sed#endif
2746192830Sed}
2747192830Sed
2748192830Sedvoid
2749192830Sedsaveterm()
2750192830Sed{
2751192830Sed}
2752192830Sed
2753192830Sedvoid
2754192830Sedfixterm()
2755192830Sed{
2756192830Sed}
2757192830Sed
2758192830Sedvoid
2759192830Sedresetterm()
2760192830Sed{
2761192830Sed}
2762192830Sed
2763192830Sedvoid
2764192830Sednodelay(window, flag)
2765192830SedWINDOW *window;
2766192830Sedint flag;
2767192830Sed{
2768192830Sed}
2769192830Sed
2770192830Sedvoid
2771192830Sedidlok(window, flag)
2772192830SedWINDOW *window;
2773192830Sedint flag;
2774192830Sed{
2775192830Sed}
2776192830Sed
2777192830Sedvoid
2778192830Sedkeypad(window, flag)
2779192830SedWINDOW *window;
2780192830Sedint flag;
2781192830Sed{
2782192830Sed	if (flag)
2783192830Sed		String_Out(String_table[ks__], NULL, 0);
2784192830Sed	else
2785192830Sed		String_Out(String_table[ke__], NULL, 0);
2786192830Sed}
2787192830Sed
2788192830Sedvoid
2789192830Sedsavetty()		/* save current tty stats			*/
2790192830Sed{
2791192830Sed	int value;
2792192830Sed
2793192830Sed#ifdef SYS5
2794192830Sed	value = ioctl(0, TCGETA, &Saved_tty);	/* set characteristics	*/
2795192830Sed#else
2796192830Sed	value = ioctl(0, TIOCGETP, &Saved_tty);	/* set characteristics	*/
2797192830Sed#endif
2798192830Sed}
2799192830Sed
2800192830Sedvoid
2801192830Sedresetty()		/* restore previous tty stats			*/
2802192830Sed{
2803192830Sed	int value;
2804192830Sed
2805192830Sed#ifdef SYS5
2806192830Sed	value = ioctl(0, TCSETA, &Saved_tty);	/* set characteristics	*/
2807192830Sed#else
2808192830Sed	value = ioctl(0, TIOCSETP, &Saved_tty);	/* set characteristics	*/
2809192830Sed#endif
2810192830Sed}
2811192830Sed
2812192830Sedvoid
2813192830Sedendwin()		/* end windows					*/
2814192830Sed{
2815192830Sed	keypad(stdscr, FALSE);
2816192830Sed	initialized = FALSE;
2817192830Sed	delwin(curscr);
2818192830Sed	delwin(virtual_scr);
2819192830Sed	delwin(stdscr);
2820192830Sed#ifndef SYS5
2821192830Sed{
2822192830Sed	int old_arg, value;
2823192830Sed/*	old_arg = fcntl(0, F_GETFL, 0);
2824192830Sed	value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
2825192830Sed}
2826192830Sed#endif
2827192830Sed}
2828192830Sed
2829192830Sedvoid
2830192830Seddelwin(window)		/* delete the window structure			*/
2831192830SedWINDOW *window;
2832192830Sed{
2833192830Sed	int i;
2834192830Sed
2835192830Sed	for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
2836192830Sed	{
2837192830Sed		window->first_line = window->first_line->next_screen;
2838192830Sed		free(window->first_line->prev_screen->row);
2839192830Sed		free(window->first_line->prev_screen->attributes);
2840192830Sed		free(window->first_line->prev_screen);
2841192830Sed	}
2842192830Sed	if (window == last_window_refreshed)
2843192830Sed		last_window_refreshed = 0;
2844192830Sed	if (window->first_line != NULL)
2845192830Sed	{
2846192830Sed		free(window->first_line->row);
2847192830Sed		free(window->first_line->attributes);
2848192830Sed		free(window->first_line);
2849192830Sed		free(window);
2850192830Sed	}
2851192830Sed}
2852192830Sed
2853192830Sed#ifndef __STDC__
2854192830Sedvoid
2855192830Sedwprintw(va_alist)
2856192830Sedva_dcl
2857192830Sed#else /* __STDC__ */
2858192830Sedvoid
2859192830Sedwprintw(WINDOW *window, const char *format, ...)
2860192830Sed#endif /* __STDC__ */
2861192830Sed{
2862192830Sed#ifndef __STDC__
2863192830Sed	WINDOW *window;
2864192830Sed	char *format;
2865192830Sed	va_list ap;
2866192830Sed#else
2867192830Sed	va_list ap;
2868192830Sed#endif
2869192830Sed	int value;
2870192830Sed	char *fpoint;
2871192830Sed	char *wtemp;
2872192830Sed
2873192830Sed#ifndef __STDC__
2874192830Sed	va_start(ap);
2875192830Sed	window = va_arg(ap, WINDOW *);
2876192830Sed	format = va_arg(ap, char *);
2877192830Sed#else /* __STDC__ */
2878192830Sed	va_start(ap, format);
2879192830Sed#endif /* __STDC__ */
2880192830Sed
2881192830Sed	fpoint = (char *) format;
2882192914Sed	while (*fpoint != '\0')
2883192830Sed	{
2884192830Sed		if (*fpoint == '%')
2885192830Sed		{
2886192830Sed			fpoint++;
2887192830Sed			if (*fpoint == 'd')
2888192830Sed			{
2889192830Sed				value = va_arg(ap, int);
2890192830Sed				iout(window, value);
2891192830Sed			}
2892192830Sed			else if (*fpoint == 'c')
2893192830Sed			{
2894192830Sed				value = va_arg(ap, int);
2895192830Sed				waddch(window, value);
2896192830Sed			}
2897192830Sed			else if (*fpoint == 's')
2898192830Sed			{
2899192830Sed				wtemp = va_arg(ap, char *);
2900192830Sed					waddstr(window, wtemp);
2901192830Sed			}
2902192830Sed			fpoint++;
2903192830Sed		}
2904192830Sed		else if (*fpoint == '\\')
2905192830Sed		{
2906192830Sed			fpoint++;
2907192830Sed			if (*fpoint == 'n')
2908192830Sed				waddch(window, '\n');
2909192830Sed			else if ((*fpoint >= '0') && (*fpoint <= '9'))
2910192830Sed			{
2911192830Sed				value = 0;
2912192830Sed				while ((*fpoint >= '0') && (*fpoint <= '9'))
2913192830Sed				{
2914192830Sed					value = (value * 8) + (*fpoint - '0');
2915192830Sed					fpoint++;
2916192830Sed				}
2917192830Sed				waddch(window, value);
2918192830Sed			}
2919192830Sed			fpoint++;
2920192830Sed		}
2921192830Sed		else
2922192830Sed			waddch(window, *fpoint++);
2923192830Sed	}
2924192830Sed#ifdef __STDC__
2925192830Sed	va_end(ap);
2926192830Sed#endif /* __STDC__ */
2927192830Sed}
2928192830Sed
2929192830Sedvoid
2930192830Sediout(window, value)	/* output characters		*/
2931192830SedWINDOW *window;
2932192830Sedint value;
2933192830Sed{
2934192830Sed	int i;
2935192830Sed
2936192830Sed	if ((i = value / 10) != 0)
2937192830Sed		iout(window, i);
2938192830Sed	waddch(window, ((value % 10) + '0'));
2939192830Sed}
2940192830Sed
2941192830Sedint
2942192830SedComp_line(line1, line2)		/* compare lines	*/
2943192830Sedstruct _line *line1;
2944192830Sedstruct _line *line2;
2945192830Sed{
2946192830Sed	int count1;
2947192830Sed	int i;
2948192830Sed	char *att1, *att2;
2949192830Sed	char *c1, *c2;
2950192830Sed
2951192830Sed	if (line1->last_char != line2->last_char)
2952192830Sed		return(2);
2953192830Sed
2954192830Sed	c1 = line1->row;
2955192830Sed	c2 = line2->row;
2956192830Sed	att1 = line1->attributes;
2957192830Sed	att2 = line2->attributes;
2958192830Sed	i = 0;
2959192914Sed	while ((c1[i] != '\0') && (c2[i] != '\0') && (c1[i] == c2[i]) && (att1[i] == att2[i]))
2960192830Sed		i++;
2961192830Sed	count1 = i + 1;
2962192914Sed	if ((count1 == 1) && (c1[i] == '\0') && (c2[i] == '\0'))
2963192830Sed		count1 = 0;			/* both lines blank	*/
2964192914Sed	else if ((c1[i] == '\0') && (c2[i] == '\0'))
2965192830Sed		count1 = -1;			/* equal		*/
2966192830Sed	else
2967192830Sed		count1 = 1;			/* lines unequal	*/
2968192830Sed	return(count1);
2969192830Sed}
2970192830Sed
2971192830Sedstruct _line *
2972192830SedInsert_line(row, end_row, window)	/* insert line into screen */
2973192830Sedint row;
2974192830Sedint end_row;
2975192830SedWINDOW *window;
2976192830Sed{
2977192830Sed	int i;
2978192830Sed	struct _line *tmp;
2979192830Sed	struct _line *tmp1;
2980192830Sed
2981192830Sed	for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
2982192830Sed		tmp = tmp->next_screen;
2983192830Sed	if ((end_row + window->SR) == 0)
2984192830Sed		curscr->first_line = curscr->first_line->next_screen;
2985192830Sed	top_of_win = tmp;
2986192830Sed	/*
2987192830Sed	 |	find bottom line to delete
2988192830Sed	 */
2989192830Sed	for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
2990192830Sed		tmp = tmp->next_screen;
2991192830Sed	if (tmp->prev_screen != NULL)
2992192830Sed		tmp->prev_screen->next_screen = tmp->next_screen;
2993192830Sed	if (tmp->next_screen != NULL)
2994192830Sed		tmp->next_screen->prev_screen = tmp->prev_screen;
2995192830Sed	tmp1 = tmp;
2996192830Sed	/*
2997192830Sed	 |	clear deleted line
2998192830Sed	 */
2999192830Sed	clear_line(tmp, 0, window->Num_cols);
3000192830Sed	tmp1->number = -1;
3001192830Sed	for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3002192830Sed		tmp = tmp->next_screen;
3003192830Sed	top_of_win = tmp;
3004192830Sed	for (i = 0, tmp = top_of_win; i < row; i++)
3005192830Sed		tmp = tmp->next_screen;
3006192830Sed	if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
3007192830Sed		tmp->prev_screen->next_screen = tmp1;
3008192830Sed	tmp1->prev_screen = tmp->prev_screen;
3009192830Sed	tmp->prev_screen = tmp1;
3010192830Sed	tmp1->next_screen = tmp;
3011192830Sed	if ((row + window->SR) == 0)
3012192830Sed		curscr->first_line = tmp1;
3013192830Sed	if (tmp1->next_screen != NULL)
3014192830Sed		tmp1 = tmp1->next_screen;
3015192830Sed
3016192830Sed	if ((!String_table[cs__]) && (end_row < window->Num_lines))
3017192830Sed	{
3018192830Sed		Position(window, (window->SR + end_row), 0);
3019192830Sed		String_Out(String_table[dl__], NULL, 0);
3020192830Sed	}
3021192830Sed	Position(window, (window->SR + row), 0);
3022192830Sed	if (String_table[al__] != NULL)
3023192830Sed		String_Out(String_table[al__], NULL, 0);
3024192830Sed	else
3025192830Sed		String_Out(String_table[sr__], NULL, 0);
3026192830Sed
3027192830Sed	for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
3028192830Sed		top_of_win = top_of_win->next_screen;
3029192830Sed	return(tmp1);
3030192830Sed}
3031192830Sed
3032192830Sed
3033192830Sedstruct _line *
3034192830SedDelete_line(row, end_row, window)	/* delete a line on screen */
3035192830Sedint row;
3036192830Sedint end_row;
3037192830SedWINDOW *window;
3038192830Sed{
3039192830Sed	int i;
3040192830Sed	struct _line *tmp;
3041192830Sed	struct _line *tmp1;
3042192830Sed	struct _line *tmp2;
3043192830Sed
3044192830Sed	i = 0;
3045192830Sed	tmp = curscr->first_line;
3046192830Sed	while (i < window->SR)
3047192830Sed	{
3048192830Sed		i++;
3049192830Sed		tmp = tmp->next_screen;
3050192830Sed	}
3051192830Sed	/*
3052192830Sed	 |	find line to delete
3053192830Sed	 */
3054192830Sed	top_of_win = tmp;
3055192830Sed	if ((row + window->SR) == 0)
3056192830Sed		curscr->first_line = top_of_win->next_screen;
3057192830Sed	for (i = 0, tmp = top_of_win; i < row; i++)
3058192830Sed		tmp = tmp->next_screen;
3059192830Sed	if (tmp->prev_screen != NULL)
3060192830Sed		tmp->prev_screen->next_screen = tmp->next_screen;
3061192830Sed	if (tmp->next_screen != NULL)
3062192830Sed		tmp->next_screen->prev_screen = tmp->prev_screen;
3063192830Sed	tmp2 = tmp->next_screen;
3064192830Sed	tmp1 = tmp;
3065192830Sed	/*
3066192830Sed	 |	clear deleted line
3067192830Sed	 */
3068192830Sed	clear_line(tmp1, 0, window->Num_cols);
3069192830Sed	tmp1->number = -1;
3070192830Sed	/*
3071192830Sed	 |	find location to insert deleted line
3072192830Sed	 */
3073192830Sed	for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
3074192830Sed		tmp = tmp->next_screen;
3075192830Sed	top_of_win = tmp;
3076192830Sed	for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
3077192830Sed		tmp = tmp->next_screen;
3078192830Sed	tmp1->next_screen = tmp;
3079192830Sed	tmp1->prev_screen = tmp->prev_screen;
3080192830Sed	if (tmp1->prev_screen != NULL)
3081192830Sed		tmp1->prev_screen->next_screen = tmp1;
3082192830Sed	tmp->prev_screen = tmp1;
3083192830Sed
3084192830Sed	Position(window, (window->SR + row), 0);
3085192830Sed	String_Out(String_table[dl__], NULL, 0);
3086192830Sed	if ((!String_table[cs__]) && (end_row < window->Num_lines))
3087192830Sed	{
3088192830Sed		Position(window, (window->SR + end_row), 0);
3089192830Sed		String_Out(String_table[al__], NULL, 0);
3090192830Sed	}
3091192830Sed	else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
3092192830Sed	{
3093192830Sed		Position(window, (window->SR + end_row), 0);
3094192830Sed		putchar('\n');
3095192830Sed	}
3096192830Sed
3097192830Sed	if (row == (window->Num_lines-1))
3098192830Sed		tmp2 = tmp1;
3099192830Sed	if ((row + window->SR) == 0)
3100192830Sed		curscr->first_line = top_of_win = tmp2;
3101192830Sed	return(tmp2);
3102192830Sed}
3103192830Sed
3104192830Sedvoid
3105192830SedCLEAR_TO_EOL(window, row, column)
3106192830SedWINDOW *window;
3107192830Sedint row, column;
3108192830Sed{
3109192830Sed	int x, y;
3110192830Sed	struct _line *tmp1;
3111192830Sed
3112192830Sed	for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
3113192830Sed		tmp1 = tmp1->next_screen;
3114192830Sed	for (x = column; x<window->Num_cols; x++)
3115192830Sed	{
3116192830Sed		tmp1->row[x] = ' ';
3117192914Sed		tmp1->attributes[x] = '\0';
3118192830Sed	}
3119192914Sed	tmp1->row[column] = '\0';
3120192830Sed	tmp1->last_char = column;
3121192830Sed	if (column < COLS)
3122192830Sed	{
3123192830Sed		if (STAND)
3124192830Sed		{
3125192830Sed			STAND = FALSE;
3126192830Sed			Position(window, row, column);
3127192830Sed			attribute_off();
3128192830Sed		}
3129192830Sed		if (String_table[ce__] != NULL)
3130192830Sed			String_Out(String_table[ce__], NULL, 0);
3131192830Sed		else
3132192830Sed		{
3133192830Sed			for (x = column; x < window->Num_cols; x++)
3134192830Sed				putchar(' ');
3135192830Sed			Curr_x = x;
3136192830Sed		}
3137192830Sed	}
3138192830Sed}
3139192830Sed
3140192830Sedint
3141192830Sedcheck_delete(window, line, offset, pointer_new, pointer_old)
3142192830SedWINDOW *window;
3143192830Sedint line, offset;
3144192830Sedstruct _line *pointer_new, *pointer_old;
3145192830Sed{
3146192830Sed	int end_old;
3147192830Sed	int end_new;
3148192830Sed	int k;
3149192830Sed	int changed;
3150192830Sed	char *old_lin;
3151192830Sed	char *new_lin;
3152192830Sed	char *old_att;
3153192830Sed	char *new_att;
3154192830Sed
3155192830Sed	changed = FALSE;
3156192830Sed	new_lin = pointer_new->row;
3157192830Sed	new_att = pointer_new->attributes;
3158192830Sed	old_lin = pointer_old->row;
3159192830Sed	old_att = pointer_old->attributes;
3160192830Sed	end_old = end_new = offset;
3161192914Sed	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'))
3162192830Sed		end_old++;
3163192914Sed	if (old_lin[end_old] != '\0')
3164192830Sed	{
3165192830Sed		k = 0;
3166192914Sed		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))
3167192830Sed			k++;
3168192914Sed		if ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0)))
3169192830Sed		{
3170192914Sed			if (new_lin[end_new+k] == '\0')
3171192830Sed			{
3172192830Sed				Position(window, line, (end_new+k));
3173192830Sed				CLEAR_TO_EOL(window, line, (end_new+k));
3174192830Sed			}
3175192830Sed			Position(window, line, offset);
3176192830Sed			for (k = offset; k < end_old; k++)
3177192830Sed				Char_del(old_lin, old_att, offset, window->Num_cols);
3178192914Sed			while ((old_lin[offset] != '\0') && (offset < COLS))
3179192830Sed				offset++;
3180192830Sed			pointer_old->last_char = offset;
3181192830Sed			changed = TRUE;
3182192830Sed		}
3183192830Sed	}
3184192830Sed	return(changed);
3185192830Sed}
3186192830Sed
3187192830Sed/*
3188192830Sed |	Check if characters were inserted in the middle of a line, and if
3189192830Sed |	so, insert them.
3190192830Sed */
3191192830Sed
3192192830Sedint
3193192830Sedcheck_insert(window, line, offset, pointer_new, pointer_old)
3194192830SedWINDOW *window;
3195192830Sedint line, offset;
3196192830Sedstruct _line *pointer_new, *pointer_old;
3197192830Sed{
3198192830Sed	int changed;
3199192830Sed	int end_old, end_new;
3200192830Sed	int k;
3201192830Sed	int same = FALSE;
3202192830Sed	int old_off;
3203192830Sed	int insert;
3204192830Sed	char *old_lin;
3205192830Sed	char *new_lin;
3206192830Sed	char *old_att;
3207192830Sed	char *new_att;
3208192830Sed
3209192830Sed	changed = FALSE;
3210192830Sed	new_lin = pointer_new->row;
3211192830Sed	new_att = pointer_new->attributes;
3212192830Sed	old_lin = pointer_old->row;
3213192830Sed	old_att = pointer_old->attributes;
3214192830Sed	end_old = end_new = offset;
3215192914Sed	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'))
3216192830Sed		end_new++;
3217192914Sed	if (new_lin[end_new] != '\0')
3218192830Sed	{
3219192830Sed		k = 0;
3220192914Sed		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))
3221192830Sed			k++;
3222192830Sed		/*
3223192830Sed		 |  check for commonality between rest of lines (are the old
3224192830Sed		 |  and new lines the same, except for a chunk in the middle?)
3225192830Sed		 |  if the rest of the lines are common, do not insert text
3226192830Sed		 */
3227192830Sed		old_off = end_new;
3228192914Sed		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]))
3229192830Sed			old_off++;
3230192830Sed		if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
3231192830Sed			same = TRUE;
3232192914Sed		if ((!same) && ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0))))
3233192830Sed		{
3234192830Sed			Position(window, line, offset);
3235192830Sed			insert = FALSE;
3236192830Sed			if (String_table[ic__] == NULL)
3237192830Sed			{
3238192830Sed				String_Out(String_table[im__], NULL, 0);
3239192830Sed				insert = TRUE;
3240192830Sed			}
3241192830Sed			for (k = offset; k < end_new; k++)
3242192830Sed			{
3243192830Sed				if (!insert)
3244192830Sed					String_Out(String_table[ic__], NULL, 0);
3245192830Sed				Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
3246192830Sed			}
3247192830Sed			if (insert)
3248192830Sed				String_Out(String_table[ei__], NULL, 0);
3249192914Sed			while ((old_lin[offset] != '\0') && (offset < COLS))
3250192830Sed				offset++;
3251192830Sed			pointer_old->last_char = offset;
3252192830Sed			changed = TRUE;
3253192830Sed		}
3254192830Sed	}
3255192830Sed	return(changed);
3256192830Sed}
3257192830Sed
3258192830Sedvoid
3259192830Seddoupdate()
3260192830Sed{
3261192830Sed	WINDOW *window;
3262192830Sed	int similar;
3263192830Sed	int diff;
3264192830Sed	int begin_old, begin_new;
3265192830Sed	int end_old, end_new;
3266192830Sed	int count1, j;
3267192830Sed	int from_top, tmp_ft, offset;
3268192830Sed	int changed;
3269192830Sed	int first_time;
3270192830Sed	int first_same;
3271192830Sed	int last_same;
3272192830Sed	int list[10];
3273192830Sed	int bottom;
3274192830Sed
3275192830Sed	struct _line *curr;
3276192830Sed	struct _line *virt;
3277192830Sed	struct _line *old;
3278192830Sed
3279192830Sed	struct _line *new;
3280192830Sed
3281192830Sed	struct _line *old1, *new1;
3282192830Sed
3283192830Sed	char *cur_lin;
3284192830Sed	char *vrt_lin;
3285192830Sed	char *cur_att;
3286192830Sed	char *vrt_att;
3287192830Sed	char *att1, *att2;
3288192830Sed	char *c1, *c2;
3289192830Sed
3290192830Sed	char NC_chinese = FALSE;	/* flag to indicate handling Chinese */
3291192830Sed
3292192830Sed	window = virtual_scr;
3293192830Sed
3294192830Sed	if ((nc_attributes & A_NC_BIG5) != 0)
3295192830Sed		NC_chinese = TRUE;
3296192830Sed
3297192830Sed	if (Repaint_screen)
3298192830Sed	{
3299192830Sed		if (String_table[cl__])
3300192830Sed			String_Out(String_table[cl__], NULL, 0);
3301192830Sed		else
3302192830Sed		{
3303192830Sed			from_top = 0;
3304192830Sed			while (from_top < LINES)
3305192830Sed			{
3306192830Sed				Position(curscr, from_top, 0);
3307192830Sed				if (String_table[ce__] != NULL)
3308192830Sed					String_Out(String_table[ce__], NULL, 0);
3309192830Sed				else
3310192830Sed				{
3311192830Sed					for (j = 0; j < window->Num_cols; j++)
3312192830Sed						putchar(' ');
3313192830Sed				}
3314192830Sed				from_top++;
3315192830Sed			}
3316192830Sed		}
3317192830Sed		for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
3318192830Sed		{
3319192830Sed			Position(curscr, from_top, 0);
3320192914Sed			for (j = 0; (curr->row[j] != '\0') && (j < curscr->Num_cols); j++)
3321192830Sed			{
3322192830Sed				Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
3323192830Sed			}
3324192830Sed			if (STAND)
3325192830Sed			{
3326192830Sed				STAND = FALSE;
3327192830Sed				Position(curscr, from_top, j);
3328192830Sed				attribute_off();
3329192830Sed			}
3330192830Sed		}
3331192830Sed		Repaint_screen = FALSE;
3332192830Sed	}
3333192830Sed
3334192830Sed	similar = 0;
3335192830Sed	diff = FALSE;
3336192830Sed	top_of_win = curscr->first_line;
3337192830Sed
3338192830Sed	for (from_top = 0, curr = top_of_win, virt = window->first_line;
3339192830Sed			from_top < window->Num_lines; from_top++)
3340192830Sed	{
3341192830Sed		virtual_lines[from_top] = TRUE;
3342192830Sed		if ((similar = Comp_line(curr, virt)) > 0)
3343192830Sed		{
3344192830Sed			virtual_lines[from_top] = FALSE;
3345192830Sed			diff = TRUE;
3346192830Sed		}
3347192830Sed		curr = curr->next_screen;
3348192830Sed		virt = virt->next_screen;
3349192830Sed	}
3350192830Sed
3351192830Sed	from_top = 0;
3352192830Sed	virt = window->first_line;
3353192830Sed	curr = top_of_win;
3354192830Sed	similar = 0;
3355192830Sed	/*
3356192830Sed	 |  if the window has lines that are different, check for scrolling
3357192830Sed	 */
3358192830Sed	if (diff)
3359192830Sed	{
3360192830Sed		last_same = -1;
3361192830Sed		changed = FALSE;
3362192830Sed		for (first_same = window->Num_lines;
3363192830Sed		    (first_same > from_top) && (virtual_lines[first_same - 1]);
3364192830Sed		     first_same--)
3365192830Sed			;
3366192830Sed		for (last_same = 0;
3367192830Sed		    (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
3368192830Sed		     last_same++)
3369192830Sed			;
3370192830Sed		while ((from_top < first_same) && nc_scrolling_ability)
3371192830Sed					/* check entire lines for diffs	*/
3372192830Sed		{
3373192830Sed
3374192830Sed			if (from_top >= last_same)
3375192830Sed			{
3376192830Sed				for (last_same = from_top;
3377192830Sed				     (last_same < window->Num_lines) &&
3378192830Sed				     (virtual_lines[last_same] == FALSE);
3379192830Sed				      last_same++)
3380192830Sed					;
3381192830Sed			}
3382192830Sed			if (!virtual_lines[from_top])
3383192830Sed			{
3384192830Sed				diff = TRUE;
3385192830Sed				/*
3386192830Sed				 |	check for lines deleted (scroll up)
3387192830Sed				 */
3388192830Sed				for (tmp_ft = from_top+1, old = curr->next_screen;
3389192830Sed					((window->scroll_up) && (diff) &&
3390192830Sed					(tmp_ft < last_same) &&
3391192830Sed					(!virtual_lines[tmp_ft]));
3392192830Sed						tmp_ft++)
3393192830Sed				{
3394192830Sed					if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
3395192830Sed					{
3396192830Sed						/*
3397192830Sed						 |	Find the bottom of the
3398192830Sed						 |	area that should be
3399192830Sed						 |	scrolled.
3400192830Sed						 */
3401192830Sed						for (bottom = tmp_ft, old1 = old,
3402192830Sed						     new1 = virt, count1 = 0;
3403192830Sed							(bottom < window->Num_lines) &&
3404192830Sed								(Comp_line(old1, new1) <= 0);
3405192830Sed								bottom++, old1 = old1->next_screen,
3406192830Sed								new1 = new1->next_screen,
3407192830Sed								count1++)
3408192830Sed							;
3409192830Sed						if (count1 > 3)
3410192830Sed						{
3411192830Sed							if (String_table[cs__]) /* scrolling region */
3412192830Sed							{
3413192830Sed								list[1] = from_top;
3414192830Sed								list[0] = min((bottom - 1), (window->Num_lines - 1));
3415192830Sed								String_Out(String_table[cs__], list, 2);
3416192830Sed								Curr_y = Curr_x = -1;
3417192830Sed							}
3418192830Sed
3419192830Sed							for (offset = (tmp_ft - from_top); (offset > 0); offset--)
3420192830Sed							{
3421192830Sed								old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
3422192830Sed								diff = FALSE;
3423192830Sed							}
3424192830Sed
3425192830Sed							if (String_table[cs__]) /* scrolling region */
3426192830Sed							{
3427192830Sed								list[1] = 0;
3428192830Sed								list[0] = LINES - 1;
3429192830Sed								String_Out(String_table[cs__], list, 2);
3430192830Sed								Curr_y = Curr_x = -1;
3431192830Sed							}
3432192830Sed
3433192830Sed							top_of_win = curscr->first_line;
3434192830Sed							curr = top_of_win;
3435192830Sed							for (offset = 0; offset < from_top; offset++)
3436192830Sed								curr = curr->next_screen;
3437192830Sed							for (offset = from_top, old=curr, new=virt;
3438192830Sed							   offset < window->Num_lines;
3439192830Sed							   old=old->next_screen, new=new->next_screen,
3440192830Sed							   offset++)
3441192830Sed							{
3442192830Sed								similar = Comp_line(old, new);
3443192830Sed								virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3444192830Sed							}
3445192830Sed						}
3446192830Sed					}
3447192830Sed					else
3448192830Sed						old = old->next_screen;
3449192830Sed				}
3450192830Sed				/*
3451192830Sed				 |	check for lines inserted (scroll down)
3452192830Sed				 */
3453192830Sed				for (tmp_ft = from_top-1, old = curr->prev_screen;
3454192830Sed					((window->scroll_down) && (tmp_ft >= 0) &&
3455192830Sed					(diff) &&
3456192830Sed					(!virtual_lines[tmp_ft]));
3457192830Sed					  tmp_ft--)
3458192830Sed				{
3459192830Sed					if (Comp_line(old, virt) == -1)
3460192830Sed					{
3461192830Sed						/*
3462192830Sed						 |	Find the bottom of the
3463192830Sed						 |	area that should be
3464192830Sed						 |	scrolled.
3465192830Sed						 */
3466192830Sed						for (bottom = from_top, old1 = old,
3467192830Sed						     new1 = virt, count1 = 0;
3468192830Sed							(bottom < window->Num_lines) &&
3469192830Sed								(Comp_line(old1, new1) <= 0);
3470192830Sed								bottom++, old1 = old1->next_screen,
3471192830Sed								new1 = new1->next_screen,
3472192830Sed								count1++)
3473192830Sed							;
3474192830Sed						if (count1 > 3)
3475192830Sed						{
3476192830Sed							if (String_table[cs__]) /* scrolling region */
3477192830Sed							{
3478192830Sed								list[1] = tmp_ft;
3479192830Sed								list[0] = min((bottom - 1), (window->Num_lines - 1));
3480192830Sed								String_Out(String_table[cs__], list, 2);
3481192830Sed								Curr_y = Curr_x = -1;
3482192830Sed							}
3483192830Sed
3484192830Sed							for (offset = (from_top - tmp_ft); (offset > 0); offset--)
3485192830Sed							{
3486192830Sed								old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
3487192830Sed								diff = FALSE;
3488192830Sed							}
3489192830Sed
3490192830Sed							if (String_table[cs__]) /* scrolling region */
3491192830Sed							{
3492192830Sed								list[1] = 0;
3493192830Sed								list[0] = LINES - 1;
3494192830Sed								String_Out(String_table[cs__], list, 2);
3495192830Sed								Curr_y = Curr_x = -1;
3496192830Sed							}
3497192830Sed
3498192830Sed							top_of_win = curscr->first_line;
3499192830Sed							curr = top_of_win;
3500192830Sed							for (offset = 0; offset < from_top; offset++)
3501192830Sed								curr = curr->next_screen;
3502192830Sed							for (offset = from_top, old=curr, new=virt;
3503192830Sed							   offset < window->Num_lines;
3504192830Sed							   old=old->next_screen, new=new->next_screen,
3505192830Sed							   offset++)
3506192830Sed							{
3507192830Sed								similar = Comp_line(old, new);
3508192830Sed								virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
3509192830Sed							}
3510192830Sed						}
3511192830Sed					}
3512192830Sed					else
3513192830Sed						old = old->prev_screen;
3514192830Sed				}
3515192830Sed			}
3516192830Sed			from_top++;
3517192830Sed			curr = curr->next_screen;
3518192830Sed			virt = virt->next_screen;
3519192830Sed		}
3520192830Sed	}
3521192830Sed
3522192830Sed
3523192830Sed	/*
3524192830Sed	 |	Scrolling done, now need to insert, delete, or modify text
3525192830Sed	 |	within lines.
3526192830Sed	 */
3527192830Sed
3528192830Sed	for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
3529192830Sed		curr = curr->next_screen;
3530192830Sed	top_of_win = curr;
3531192830Sed	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)
3532192830Sed	{
3533192830Sed
3534192830Sed		/*
3535192830Sed		 |	If either 'insert mode' or 'insert char' are
3536192830Sed		 |	available, enter the following 'if' statement,
3537192830Sed		 |	else, need to simply rewrite the contents of the line
3538192830Sed		 |	at the point where the contents of the line change.
3539192830Sed		 */
3540192830Sed
3541192830Sed		if (((String_table[ic__]) || (String_table[im__])) &&
3542192914Sed		    (String_table[dc__]) && (curr->row[0] != '\0') &&
3543192830Sed		    (!NC_chinese))
3544192830Sed		{
3545192830Sed			j = 0;
3546192830Sed			first_time = TRUE;
3547192830Sed			vrt_lin = virt->row;
3548192830Sed			vrt_att = virt->attributes;
3549192830Sed			cur_lin = curr->row;
3550192830Sed			cur_att = curr->attributes;
3551192914Sed			while ((vrt_lin[j] != '\0') && (j < window->Num_cols))
3552192830Sed			{
3553192830Sed				if ((STAND) && (Booleans[xs__]))
3554192830Sed				{
3555192914Sed					while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0') && (vrt_att[j]))
3556192830Sed						j++;
3557192830Sed					if ((STAND) && (!vrt_att[j]))
3558192830Sed					{
3559192830Sed						STAND = FALSE;
3560192830Sed						Position(window, from_top, j);
3561192830Sed						attribute_off();
3562192830Sed						attribute_off();
3563192830Sed					}
3564192830Sed				}
3565192830Sed				else
3566192830Sed				{
3567192914Sed					while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0'))
3568192830Sed						j++;
3569192830Sed				}
3570192830Sed				if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
3571192830Sed				{
3572192830Sed					Position(window, from_top, j);
3573192830Sed/*					CLEAR_TO_EOL(window, from_top, j);*/
3574192830Sed					attribute_off();
3575192830Sed					attribute_off();
3576192830Sed				}
3577192914Sed				if (vrt_lin[j] != '\0')
3578192830Sed				{
3579192830Sed					begin_new = j;
3580192830Sed					begin_old = j;
3581192830Sed					end_old = j;
3582192830Sed					end_new = j;
3583192830Sed					if ((first_time) && (virt->changed))
3584192830Sed					{
3585192830Sed						if (curr->last_char <= virt->last_char)
3586192830Sed							changed = check_insert(window, from_top, j, virt, curr);
3587192830Sed					}
3588192830Sed					changed = check_delete(window, from_top, j, virt, curr);
3589192830Sed					first_time = FALSE;
3590192830Sed					virt->changed = FALSE;
3591192830Sed					if (!changed)
3592192830Sed						changed = check_insert(window, from_top, j, virt, curr);
3593192830Sed					if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
3594192830Sed					{
3595192914Sed						if ((vrt_lin[j] == ' ') && (cur_lin[j] == '\0') && (vrt_att[j] == cur_att[j]))
3596192830Sed							cur_lin[j] = ' ';
3597192830Sed						else
3598192830Sed						{
3599192830Sed							Position(window, from_top, j);
3600192830Sed							Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
3601192830Sed						}
3602192830Sed					}
3603192914Sed					if ((vrt_lin[j] != '\0'))
3604192830Sed						j++;
3605192830Sed				}
3606192830Sed				if ((STAND) && (!vrt_att[j]))
3607192830Sed				{
3608192830Sed					STAND = FALSE;
3609192830Sed					Position(window, from_top, j);
3610192830Sed					attribute_off();
3611192830Sed				}
3612192830Sed			}
3613192914Sed			if ((vrt_lin[j] == '\0') && (cur_lin[j] != '\0'))
3614192830Sed			{
3615192830Sed				Position(window, from_top, j);
3616192830Sed				CLEAR_TO_EOL(window, from_top, j);
3617192830Sed			}
3618192830Sed		}
3619192830Sed		else /*if ((similar != -1) && (similar != 0))*/
3620192830Sed		{
3621192830Sed			j = 0;
3622192830Sed			c1 = curr->row;
3623192830Sed			att1 = curr->attributes;
3624192830Sed			c2 = virt->row;
3625192830Sed			att2 = virt->attributes;
3626192914Sed			while ((j < window->Num_cols) && (c2[j] != '\0'))
3627192830Sed			{
3628192914Sed				while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != '\0'))
3629192830Sed					j++;
3630192830Sed
3631192830Sed				/*
3632192830Sed				 |	if previous character is an eight bit
3633192830Sed				 |	char, start redraw from that character
3634192830Sed				 */
3635192830Sed
3636192830Sed				if ((NC_chinese) && (highbitset(c1[j - 1])))
3637192830Sed					j--;
3638192830Sed				begin_old = j;
3639192830Sed				begin_new = j;
3640192914Sed				if ((j < window->Num_cols) && (c2[j] != '\0'))
3641192830Sed				{
3642192830Sed					Position(window, from_top, begin_old);
3643192830Sed					CLEAR_TO_EOL(window, from_top, j);
3644192830Sed					Position(window, from_top, begin_old);
3645192914Sed					for (j = begin_old; (c2[j] != '\0') && (j < window->Num_cols); j++)
3646192830Sed						Char_out(c2[j], att2[j], c1, att1, j);
3647192830Sed				}
3648192830Sed			}
3649192914Sed			if ((c2[j] == '\0') && (c1[j] != '\0'))
3650192830Sed			{
3651192830Sed				Position(window, from_top, j);
3652192830Sed				CLEAR_TO_EOL(window, from_top, j);
3653192830Sed			}
3654192830Sed		}
3655192830Sed		if (STAND)
3656192830Sed		{
3657192830Sed			STAND = FALSE;
3658192830Sed			Position(window, from_top, j);
3659192830Sed			attribute_off();
3660192830Sed		}
3661192830Sed		virt->number = from_top;
3662192830Sed	}
3663192830Sed	Position(window, window->LY, window->LX);
3664192830Sed}
3665192830Sed
3666192830Sedvoid
3667192830SedPosition(window, row, col)	/* position the cursor for output on the screen	*/
3668192830SedWINDOW *window;
3669192830Sedint row;
3670192830Sedint col;
3671192830Sed{
3672192830Sed	int list[10];
3673192830Sed	int place;
3674192830Sed
3675192830Sed	int pos_row;
3676192830Sed	int pos_column;
3677192830Sed
3678192830Sed	pos_row = row + window->SR;
3679192830Sed	pos_column = col + window->SC;
3680192830Sed	if ((pos_row != Curr_y) || (pos_column != Curr_x))
3681192830Sed	{
3682192830Sed		if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
3683192830Sed		{
3684192830Sed			place = 0;
3685192830Sed			list[place++] = pos_column;
3686192830Sed			list[place++] = pos_row;
3687192830Sed			String_Out(String_table[cm__], list, place);
3688192830Sed			if ((STAND) && (!Booleans[ms__]))
3689192830Sed				attribute_on();
3690192830Sed		}
3691192830Sed		Curr_x = pos_column;
3692192830Sed		Curr_y = pos_row;
3693192830Sed	}
3694192830Sed}
3695192830Sed
3696192830Sedvoid
3697192830SedChar_del(line, attrib, offset, maxlen)	/* delete chars from line	*/
3698192830Sedchar *line;
3699192830Sedchar *attrib;
3700192830Sedint offset;
3701192830Sedint maxlen;
3702192830Sed{
3703192830Sed	int one, two;
3704192830Sed
3705192914Sed	for (one = offset, two = offset+1; (line[one] != '\0') && (one < maxlen); one++, two++)
3706192830Sed	{
3707192830Sed		line[one] = line[two];
3708192830Sed		attrib[one] = attrib[two];
3709192830Sed	}
3710192830Sed	String_Out(String_table[dc__], NULL, 0);
3711192830Sed}
3712192830Sed
3713192830Sedvoid
3714192830SedChar_ins(line, attrib, newc, newatt, offset, maxlen)	/* insert chars in line	*/
3715192830Sedchar *line;
3716192830Sedchar *attrib;
3717192830Sedchar newc;
3718192830Sedchar newatt;
3719192830Sedint offset;
3720192830Sedint maxlen;
3721192830Sed{
3722192830Sed	int one, two;
3723192830Sed
3724192830Sed	one = 0;
3725192914Sed	while ((line[one] != '\0') && (one < (maxlen - 2)))
3726192830Sed		one++;
3727192830Sed	for (two = one + 1; (two > offset); one--, two--)
3728192830Sed	{
3729192830Sed		line[two] = line[one];
3730192830Sed		attrib[two] = attrib[one];
3731192830Sed	}
3732192830Sed	line[offset] = newc;
3733192830Sed	attrib[offset] = newatt;
3734192830Sed	Char_out(newc, newatt, line, attrib, offset);
3735192830Sed}
3736192830Sed
3737192830Sedvoid
3738192830Sedattribute_on()
3739192830Sed{
3740192830Sed	if (String_table[sa__])
3741192830Sed	{
3742192830Sed		attributes_set[0] = 1;
3743192830Sed		String_Out(String_table[sa__], attributes_set, 1);
3744192830Sed	}
3745192830Sed	else if (String_table[so__])
3746192830Sed		String_Out(String_table[so__], NULL, 0);
3747192830Sed}
3748192830Sed
3749192830Sedvoid
3750192830Sedattribute_off()
3751192830Sed{
3752192830Sed	if (String_table[me__])
3753192830Sed		String_Out(String_table[me__], NULL, 0);
3754192830Sed	else if (String_table[sa__])
3755192830Sed	{
3756192830Sed		attributes_set[0] = 0;
3757192830Sed		String_Out(String_table[sa__], attributes_set, 1);
3758192830Sed	}
3759192830Sed	else if (String_table[se__])
3760192830Sed		String_Out(String_table[se__], NULL, 0);
3761192830Sed}
3762192830Sed
3763192830Sedvoid
3764192830SedChar_out(newc, newatt, line, attrib, offset)	/* output character with proper attribute	*/
3765192830Sedchar newc;
3766192830Sedchar newatt;
3767192830Sedchar *line;
3768192830Sedchar *attrib;
3769192830Sedint offset;
3770192830Sed{
3771192830Sed
3772192830Sed
3773192830Sed	if ((newatt) && (!STAND))
3774192830Sed	{
3775192830Sed		STAND = TRUE;
3776192830Sed		attribute_on();
3777192830Sed	}
3778192830Sed	else if ((STAND) && (!newatt))
3779192830Sed	{
3780192830Sed		STAND = FALSE;
3781192830Sed		attribute_off();
3782192830Sed	}
3783192830Sed
3784192830Sed	if ((newatt) && (STAND) && (Booleans[xs__]))
3785192830Sed	{
3786192830Sed		attribute_on();
3787192830Sed	}
3788192830Sed
3789192830Sed	if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
3790192830Sed	{
3791192830Sed		putchar(newc);
3792192830Sed		line[offset] = newc;
3793192830Sed		attrib[offset] = newatt;
3794192830Sed	}
3795192830Sed	Curr_x++;
3796192830Sed}
3797192830Sed
3798192830Sed/*
3799192830Sed |
3800192830Sed |	The two routines that follow, nc_setattrib(), nc_clearattrib(), are
3801192830Sed |	hacks that notify new_curse to handle characters that have the high
3802192830Sed |	bit set as the first of two bytes of a multi-byte string.
3803192830Sed |
3804192830Sed */
3805192830Sed
3806192830Sedvoid
3807192830Sednc_setattrib(flag)
3808192830Sedint flag;
3809192830Sed{
3810192830Sed	nc_attributes |= flag;
3811192830Sed}
3812192830Sed
3813192830Sedvoid
3814192830Sednc_clearattrib(flag)
3815192830Sedint flag;
3816192830Sed{
3817192830Sed	nc_attributes &= ~flag;
3818192830Sed}
3819192830Sed
3820