diff options
author | ed <ed@FreeBSD.org> | 2009-05-26 20:13:17 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-05-26 20:13:17 +0000 |
commit | fbad22d013baa1ed80ce29fd090be19e99ed314c (patch) | |
tree | 802aed2d76270bc9fee21713d1e79973febde177 /contrib/ee/new_curse.c | |
parent | 6cf142b7b439d69ca0ee2ce20e9551f628a65110 (diff) | |
parent | cd2cd8f376f2d165e207cc5b80154f80bffbac4d (diff) | |
download | FreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.zip FreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.tar.gz |
Copy ee 1.4.2 into the contrib directory.
This allows me to merge our custom changes to ee(1) back on top of
original sources, with correct mergeinfo.
Diffstat (limited to 'contrib/ee/new_curse.c')
-rw-r--r-- | contrib/ee/new_curse.c | 3813 |
1 files changed, 3813 insertions, 0 deletions
diff --git a/contrib/ee/new_curse.c b/contrib/ee/new_curse.c new file mode 100644 index 0000000..9ea8269 --- /dev/null +++ b/contrib/ee/new_curse.c @@ -0,0 +1,3813 @@ +/* + | new_curse.c + | + | A subset of curses developed for use with ae. + | + | written by Hugh Mahon + | + | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE + | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS + | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE + | IMPLIED WARRANTIES OF MERCHANTABILITY AND + | FITNESS FOR A PARTICULAR PURPOSE. Neither + | Hewlett-Packard nor Hugh Mahon shall be liable + | for errors contained herein, nor for + | incidental or consequential damages in + | connection with the furnishing, performance or + | use of this material. Neither Hewlett-Packard + | nor Hugh Mahon assumes any responsibility for + | the use or reliability of this software or + | documentation. This software and + | documentation is totally UNSUPPORTED. There + | is no support contract available. Hewlett- + | Packard has done NO Quality Assurance on ANY + | of the program or documentation. You may find + | the quality of the materials inferior to + | supported materials. + | + | This software is not a product of Hewlett-Packard, Co., or any + | other company. No support is implied or offered with this software. + | You've got the source, and you're on your own. + | + | This software may be distributed under the terms of Larry Wall's + | Artistic license, a copy of which is included in this distribution. + | + | This notice must be included with this software and any derivatives. + | + | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon + | All are rights reserved. + | + | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.50 2001/01/19 02:53:40 hugh Exp hugh $ + | + */ + +char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon", + "All rights are reserved."}; + +char * new_curse_name= "@(#) new_curse.c $Revision: 1.50 $"; + +#include "new_curse.h" +#include <signal.h> +#include <fcntl.h> + +#ifdef SYS5 +#include <string.h> +#else +#include <strings.h> +#endif + +#ifdef BSD_SELECT +#include <sys/types.h> +#include <sys/time.h> + +#ifdef SLCT_HDR +#include <sys/select.h> /* on AIX */ +#endif /* SLCT_HDR */ + +#endif /* BSD_SELECT */ + +#ifdef HAS_STDLIB +#include <stdlib.h> +#endif + +#if defined(__STDC__) +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#ifdef HAS_UNISTD +#include <unistd.h> +#endif + +#ifdef HAS_SYS_IOCTL +#include <sys/ioctl.h> +#endif + + +WINDOW *curscr; +static WINDOW *virtual_scr; +WINDOW *stdscr; +WINDOW *last_window_refreshed; + +#ifdef TIOCGWINSZ + struct winsize ws; +#endif + +#define min(a, b) (a < b ? a : b) +#define highbitset(a) ((a) & 0x80) + +#ifndef CAP +#define String_Out(table, stack, place) Info_Out(table, stack, place) +#else +#define String_Out(table, stack, place) Cap_Out(table, stack, place) +#endif + +#define bw__ 0 /* booleans */ +#define am__ 1 +#define xb__ 2 +#define xs__ 3 /* hp glitch (standout not erased by overwrite) */ +#define xn__ 4 +#define eo__ 5 +#define gn__ 6 /* generic type terminal */ +#define hc__ 7 /* hardcopy terminal */ +#define km__ 8 +#define hs__ 9 +#define in__ 10 +#define da__ 11 +#define db__ 12 +#define mi__ 13 /* safe to move during insert mode */ +#define ms__ 14 /* safe to move during standout mode */ +#define os__ 15 +#define es__ 16 +#define xt__ 17 +#define hz__ 18 /* hazeltine glitch */ +#define ul__ 19 +#define xo__ 20 +#define chts__ 21 +#define nxon__ 22 +#define nrrmc__ 23 +#define npc__ 24 +#define mc5i__ 25 + +#define co__ 0 /* number of columns */ /* numbers */ +#define it__ 1 /* spaces per tab */ +#define li__ 2 /* number of lines */ +#define lm__ 3 +#define sg__ 4 /* magic cookie glitch */ +#define pb__ 5 +#define vt__ 6 +#define ws__ 7 + +#define cols__ 0 +#define lines__ 2 +#define xmc__ 4 +#define vt__ 6 +#define wsl__ 7 +#define nlab__ 8 +#define lh__ 9 +#define lw__ 10 + +#define bt__ 0 /* back tab */ /* strings */ +#define bl__ 1 /* bell */ +#define cr__ 2 /* carriage return */ +#define cs__ 3 /* change scroll region */ +#define ct__ 4 /* clear all tab stops */ +#define cl__ 5 /* clear screen and home cursor */ +#define ce__ 6 /* clear to end of line */ +#define cd__ 7 /* clear to end of display */ +#define ch__ 8 /* set cursor column */ +#define CC__ 9 /* term, settable cmd char in */ +#define cm__ 10 /* screen rel cursor motion, row, column */ +#define do__ 11 /* down one line */ +#define ho__ 12 /* home cursor */ +#define vi__ 13 /* make cursor invisible */ +#define le__ 14 /* move cursor left one space */ +#define CM__ 15 /* memory rel cursor addressing */ +#define ve__ 16 /* make cursor appear normal */ +#define nd__ 17 /* non-destructive space (cursor right) */ +#define ll__ 18 /* last line, first col */ +#define up__ 19 /* cursor up */ +#define vs__ 20 +#define dc__ 21 /* delete character */ +#define dl__ 22 /* delete line */ +#define ds__ 23 +#define hd__ 24 +#define as__ 25 +#define mb__ 26 +#define md__ 27 /* turn on bold */ +#define ti__ 28 +#define dm__ 29 /* turn on delete mode */ +#define mh__ 30 /* half bright mode */ +#define im__ 31 /* insert mode */ +#define mk__ 32 +#define mp__ 33 +#define mr__ 34 +#define so__ 35 /* enter standout mode */ +#define us__ 36 +#define ec__ 37 +#define ae__ 38 +#define me__ 39 +#define te__ 40 +#define ed__ 41 +#define ei__ 42 /* exit insert mode */ +#define se__ 43 /* exit standout mode */ +#define ue__ 44 +#define vb__ 45 +#define ff__ 46 +#define fs__ 47 +#define i1__ 48 +#define i2__ 49 +#define i3__ 50 +#define if__ 51 +#define ic__ 52 +#define al__ 53 +#define ip__ 54 +#define kb__ 55 /* backspace key */ +#define ka__ 56 +#define kC__ 57 +#define kt__ 58 +#define kD__ 59 +#define kL__ 60 +#define kd__ 61 +#define kM__ 62 +#define kE__ 63 +#define kS__ 64 +#define k0__ 65 +#define k1__ 66 +#define kf10__ 67 +#define k2__ 68 +#define k3__ 69 +#define k4__ 70 +#define k5__ 71 +#define k6__ 72 +#define k7__ 73 +#define k8__ 74 +#define k9__ 75 +#define kh__ 76 +#define kI__ 77 +#define kA__ 78 +#define kl__ 79 +#define kH__ 80 +#define kN__ 81 +#define kP__ 82 +#define kr__ 83 +#define kF__ 84 +#define kR__ 85 +#define kT__ 86 +#define ku__ 87 /* key up */ +#define ke__ 88 +#define ks__ 89 +#define l0__ 90 +#define l1__ 91 +#define la__ 92 +#define l2__ 93 +#define l3__ 94 +#define l4__ 95 +#define l5__ 96 +#define l6__ 97 +#define l7__ 98 +#define l8__ 99 +#define l9__ 100 +#define mo__ 101 +#define mm__ 102 +#define nw__ 103 +#define pc__ 104 +#define DC__ 105 +#define DL__ 106 +#define DO__ 107 +#define IC__ 118 +#define SF__ 109 +#define AL__ 110 +#define LE__ 111 +#define RI__ 112 +#define SR__ 113 +#define UP__ 114 +#define pk__ 115 +#define pl__ 116 +#define px__ 117 +#define ps__ 118 +#define pf__ 119 +#define po__ 120 +#define rp__ 121 +#define r1__ 122 +#define r2__ 123 +#define r3__ 124 +#define rf__ 125 +#define rc__ 126 +#define cv__ 127 +#define sc__ 128 +#define sf__ 129 +#define sr__ 130 +#define sa__ 131 /* sgr */ +#define st__ 132 +#define wi__ 133 +#define ta__ 134 +#define ts__ 135 +#define uc__ 136 +#define hu__ 137 +#define iP__ 138 +#define K1__ 139 +#define K2__ 140 +#define K3__ 141 +#define K4__ 142 +#define K5__ 143 +#define pO__ 144 +#define ml__ 145 +#define mu__ 146 +#define rmp__ 145 +#define acsc__ 146 +#define pln__ 147 +#define kcbt__ 148 +#define smxon__ 149 +#define rmxon__ 150 +#define smam__ 151 +#define rmam__ 152 +#define xonc__ 153 +#define xoffc__ 154 +#define enacs__ 155 +#define smln__ 156 +#define rmln__ 157 +#define kbeg__ 158 +#define kcan__ 159 +#define kclo__ 160 +#define kcmd__ 161 +#define kcpy__ 162 +#define kcrt__ 163 +#define kend__ 164 +#define kent__ 165 +#define kext__ 166 +#define kfnd__ 167 +#define khlp__ 168 +#define kmrk__ 169 +#define kmsg__ 170 +#define kmov__ 171 +#define knxt__ 172 +#define kopn__ 173 +#define kopt__ 174 +#define kprv__ 175 +#define kprt__ 176 +#define krdo__ 177 +#define kref__ 178 +#define krfr__ 179 +#define krpl__ 180 +#define krst__ 181 +#define kres__ 182 +#define ksav__ 183 +#define kspd__ 184 +#define kund__ 185 +#define kBEG__ 186 +#define kCAN__ 187 +#define kCMD__ 188 +#define kCPY__ 189 +#define kCRT__ 190 +#define kDC__ 191 +#define kDL__ 192 +#define kslt__ 193 +#define kEND__ 194 +#define kEOL__ 195 +#define kEXT__ 196 +#define kFND__ 197 +#define kHLP__ 198 +#define kHOM__ 199 +#define kIC__ 200 +#define kLFT__ 201 +#define kMSG__ 202 +#define kMOV__ 203 +#define kNXT__ 204 +#define kOPT__ 205 +#define kPRV__ 206 +#define kPRT__ 207 +#define kRDO__ 208 +#define kRPL__ 209 +#define kRIT__ 210 +#define kRES__ 211 +#define kSAV__ 212 +#define kSPD__ 213 +#define kUND__ 214 +#define rfi__ 215 +#define kf11__ 216 +#define kf12__ 217 +#define kf13__ 218 +#define kf14__ 219 +#define kf15__ 220 +#define kf16__ 221 +#define kf17__ 222 +#define kf18__ 223 +#define kf19__ 224 +#define kf20__ 225 +#define kf21__ 226 +#define kf22__ 227 +#define kf23__ 228 +#define kf24__ 229 +#define kf25__ 230 +#define kf26__ 231 +#define kf27__ 232 +#define kf28__ 233 +#define kf29__ 234 +#define kf30__ 235 +#define kf31__ 236 +#define kf32__ 237 +#define kf33__ 238 +#define kf34__ 239 +#define kf35__ 240 +#define kf36__ 241 +#define kf37__ 242 +#define kf38__ 243 +#define kf39__ 244 +#define kf40__ 245 +#define kf41__ 246 +#define kf42__ 247 +#define kf43__ 248 +#define kf44__ 249 +#define kf45__ 250 +#define kf46__ 251 +#define kf47__ 252 +#define kf48__ 253 +#define kf49__ 254 +#define kf50__ 255 +#define kf51__ 256 +#define kf52__ 257 +#define kf53__ 258 +#define kf54__ 259 +#define kf55__ 260 +#define kf56__ 261 +#define kf57__ 262 +#define kf58__ 263 +#define kf59__ 264 +#define kf60__ 265 +#define kf61__ 266 +#define kf62__ 267 +#define kf63__ 268 +#define el1__ 269 +#define mgc__ 270 +#define smgl__ 271 +#define smgr__ 272 + +#ifdef CAP +char *Boolean_names[] = { +"bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db", +"mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i" +}; + +char *Number_names[] = { +"co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#" +}; + +char *String_names[] = { +"bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=", +"do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=", +"dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=", +"mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=", +"ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=", +"kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=", +"k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=", +"kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=", +"ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=", +"l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=", +"AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=", +"rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=", +"st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=", +"K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=", +"XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=", +"@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=", +"%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=", +"&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=", +"#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=", +"%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=", +"F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=", +"FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=", +"FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=", +"Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=", +"Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR=" +}; +#endif + +char *new_curse = "October 1987"; + +char in_buff[100]; /* buffer for ungetch */ +int bufp; /* next free position in in_buff */ + +char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */ +int CFOUND = FALSE; +int Data_Line_len = 0; +int Max_Key_len; /* max length of a sequence sent by a key */ +char *Data_Line = NULL; +char *TERM_PATH = NULL; +char *TERM_data_ptr = NULL; +char *Term_File_name = NULL; /* name of file containing terminal description */ +FILE *TFP; /* file pointer to file with terminal des. */ +int Fildes; /* file descriptor for terminfo file */ +int STAND = FALSE; /* is standout mode activated? */ +int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */ +int Time_Out; /* set when time elapsed while trying to read function key */ +int Curr_x; /* current x position on screen */ +int Curr_y; /* current y position on the screen */ +int LINES; +int COLS; +int Move_It; /* flag to move cursor if magic cookie glitch */ +int initialized = FALSE; /* tells whether new_curse is initialized */ +float speed; +float chars_per_millisecond; +int Repaint_screen; /* if an operation to change screen impossible, repaint screen */ +int Intr; /* storeage for interrupt character */ +int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */ +int Noblock; /* for BSD systems */ +int Num_bits; /* number of bits per character */ +int Flip_Bytes; /* some systems have byte order reversed */ +int interrupt_flag = FALSE; /* set true if SIGWINCH received */ + +#ifndef CAP +char *Strings; +#endif + +struct KEYS { + int length; /* length of string sent by key */ + char *string; /* string sent by key */ + int value; /* CURSES value of key (9-bit) */ + }; + +struct KEY_STACK { + struct KEYS *element; + struct KEY_STACK *next; + }; + +struct KEY_STACK *KEY_TOS = NULL; +struct KEY_STACK *KEY_POINT; + +/* + | + | Not all systems have good terminal information, so we will define + | keyboard information here for the most widely used terminal type, + | the VT100. + | + */ + +struct KEYS vt100[] = + { + { 3, "\033[A", 0403 }, /* key up */ + { 3, "\033[C", 0405 }, /* key right */ + { 3, "\033[D", 0404 }, /* key left */ + + { 4, "\033[6~", 0522 }, /* key next page */ + { 4, "\033[5~", 0523 }, /* key prev page */ + { 3, "\033[[", 0550 }, /* key end */ + { 3, "\033[@", 0406 }, /* key home */ + { 4, "\033[2~", 0513 }, /* key insert char */ + + { 3, "\033[y", 0410 }, /* key F0 */ + { 3, "\033[P", 0411 }, /* key F1 */ + { 3, "\033[Q", 0412 }, /* key F2 */ + { 3, "\033[R", 0413 }, /* key F3 */ + { 3, "\033[S", 0414 }, /* key F4 */ + { 3, "\033[t", 0415 }, /* key F5 */ + { 3, "\033[u", 0416 }, /* key F6 */ + { 3, "\033[v", 0417 }, /* key F7 */ + { 3, "\033[l", 0420 }, /* key F8 */ + { 3, "\033[w", 0421 }, /* key F9 */ + { 3, "\033[x", 0422 }, /* key F10 */ + + { 5, "\033[10~", 0410 }, /* key F0 */ + { 5, "\033[11~", 0411 }, /* key F1 */ + { 5, "\033[12~", 0412 }, /* key F2 */ + { 5, "\033[13~", 0413 }, /* key F3 */ + { 5, "\033[14~", 0414 }, /* key F4 */ + { 5, "\033[15~", 0415 }, /* key F5 */ + { 5, "\033[17~", 0416 }, /* key F6 */ + { 5, "\033[18~", 0417 }, /* key F7 */ + { 5, "\033[19~", 0420 }, /* key F8 */ + { 5, "\033[20~", 0421 }, /* key F9 */ + { 5, "\033[21~", 0422 }, /* key F10 */ + { 5, "\033[23~", 0423 }, /* key F11 */ + { 5, "\033[24~", 0424 }, /* key F12 */ + { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */ + { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */ + { 3, "\033[r", 0536 }, /* kb2 center of keypad */ + { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */ + { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */ + + /* + | The following are the same keys as above, but with + | a different character following the escape char. + */ + + { 3, "\033OA", 0403 }, /* key up */ + { 3, "\033OC", 0405 }, /* key right */ + { 3, "\033OD", 0404 }, /* key left */ + { 3, "\033OB", 0402 }, /* key down */ + { 4, "\033O6~", 0522 }, /* key next page */ + { 4, "\033O5~", 0523 }, /* key prev page */ + { 3, "\033O[", 0550 }, /* key end */ + { 3, "\033O@", 0406 }, /* key home */ + { 4, "\033O2~", 0513 }, /* key insert char */ + + { 3, "\033Oy", 0410 }, /* key F0 */ + { 3, "\033OP", 0411 }, /* key F1 */ + { 3, "\033OQ", 0412 }, /* key F2 */ + { 3, "\033OR", 0413 }, /* key F3 */ + { 3, "\033OS", 0414 }, /* key F4 */ + { 3, "\033Ot", 0415 }, /* key F5 */ + { 3, "\033Ou", 0416 }, /* key F6 */ + { 3, "\033Ov", 0417 }, /* key F7 */ + { 3, "\033Ol", 0420 }, /* key F8 */ + { 3, "\033Ow", 0421 }, /* key F9 */ + { 3, "\033Ox", 0422 }, /* key F10 */ + + { 5, "\033O10~", 0410 }, /* key F0 */ + { 5, "\033O11~", 0411 }, /* key F1 */ + { 5, "\033O12~", 0412 }, /* key F2 */ + { 5, "\033O13~", 0413 }, /* key F3 */ + { 5, "\033O14~", 0414 }, /* key F4 */ + { 5, "\033O15~", 0415 }, /* key F5 */ + { 5, "\033O17~", 0416 }, /* key F6 */ + { 5, "\033O18~", 0417 }, /* key F7 */ + { 5, "\033O19~", 0420 }, /* key F8 */ + { 5, "\033O20~", 0421 }, /* key F9 */ + { 5, "\033O21~", 0422 }, /* key F10 */ + { 5, "\033O23~", 0423 }, /* key F11 */ + { 5, "\033O24~", 0424 }, /* key F12 */ + { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */ + { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */ + { 3, "\033Or", 0536 }, /* kb2 center of keypad */ + { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */ + { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */ + + { 0, "", 0 } /* end */ + }; + +struct Parameters { + int value; + struct Parameters *next; + }; + +int Key_vals[] = { + 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411, + 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511, + 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403, + 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547, + 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562, + 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573, + 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607, + 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623, + 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431, + 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445, + 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461, + 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475, + 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507 +}; + +int attributes_set[9]; + +static int nc_attributes = 0; /* global attributes for new_curse to observe */ + +#ifdef SYS5 +struct termio Terminal; +struct termio Saved_tty; +#else +struct sgttyb Terminal; +struct sgttyb Saved_tty; +#endif + +char *tc_; + +int Booleans[128]; +int Numbers[128]; +char *String_table[1024]; + +int *virtual_lines; + +static char nc_scrolling_ability = FALSE; + +#ifdef CAP + +#if defined(__STDC__) || defined(__cplusplus) +#define P_(s) s +#else +#define P_(s) () +#endif /* __STDC__ */ + +int tc_Get_int P_((int)); +void CAP_PARSE P_((void)); +void Find_term P_((void)); + +#undef P_ + +#endif /* CAP */ + + +#ifndef __STDC__ +#ifndef HAS_STDLIB +extern char *fgets(); +extern char *malloc(); +extern char *getenv(); +FILE *fopen(); /* declaration for open function */ +#endif /* HAS_STDLIB */ +#endif /* __STDC__ */ + +#ifdef SIGWINCH + +/* + | Copy the contents of one window to another. + */ + +void +copy_window(origin, destination) +WINDOW *origin, *destination; +{ + int row, column; + struct _line *orig, *dest; + + orig = origin->first_line; + dest = destination->first_line; + + for (row = 0; + row < (min(origin->Num_lines, destination->Num_lines)); + row++) + { + for (column = 0; + column < (min(origin->Num_cols, destination->Num_cols)); + column++) + { + dest->row[column] = orig->row[column]; + dest->attributes[column] = orig->attributes[column]; + } + dest->changed = orig->changed; + dest->scroll = orig->scroll; + dest->last_char = min(orig->last_char, destination->Num_cols); + orig = orig->next_screen; + dest = dest->next_screen; + } + destination->LX = min((destination->Num_cols - 1), origin->LX); + destination->LY = min((destination->Num_lines - 1), origin->LY); + destination->Attrib = origin->Attrib; + destination->scroll_up = origin->scroll_up; + destination->scroll_down = origin->scroll_down; + destination->SCROLL_CLEAR = origin->SCROLL_CLEAR; +} + +void +reinitscr(foo) +int foo; +{ + WINDOW *local_virt; + WINDOW *local_std; + WINDOW *local_cur; + + signal(SIGWINCH, reinitscr); +#ifdef TIOCGWINSZ + if (ioctl(0, TIOCGWINSZ, &ws) >= 0) + { + if (ws.ws_row == LINES && ws.ws_col == COLS) + return; + if (ws.ws_row > 0) + LINES = ws.ws_row; + if (ws.ws_col > 0) + COLS = ws.ws_col; + } +#endif /* TIOCGWINSZ */ + local_virt = newwin(LINES, COLS, 0, 0); + local_std = newwin(LINES, COLS, 0, 0); + local_cur = newwin(LINES, COLS, 0, 0); + copy_window(virtual_scr, local_virt); + copy_window(stdscr, local_std); + copy_window(curscr, local_cur); + delwin(virtual_scr); + delwin(stdscr); + delwin(curscr); + virtual_scr = local_virt; + stdscr = local_std; + curscr = local_cur; + free(virtual_lines); + virtual_lines = (int *) malloc(LINES * (sizeof(int))); + interrupt_flag = TRUE; +} +#endif /* SIGWINCH */ + +void +initscr() /* initialize terminal for operations */ +{ + int value; + char *lines_string; + char *columns_string; +#ifdef CAP + char *pointer; +#endif /* CAP */ + +#ifdef DIAG +printf("starting initscr \n");fflush(stdout); +#endif + if (initialized) + return; +#ifdef BSD_SELECT + setbuf(stdin, NULL); +#endif /* BSD_SELECT */ + Flip_Bytes = FALSE; + Parity = 0; + Time_Out = FALSE; + bufp = 0; + Move_It = FALSE; + Noblock = FALSE; +#ifdef SYS5 + value = ioctl(0, TCGETA, &Terminal); + if (Terminal.c_cflag & PARENB) + { + if (Terminal.c_cflag & PARENB) + Parity = 1; + else + Parity = 2; + } + if ((Terminal.c_cflag & CS8) == CS8) + { + Num_bits = 8; + } + else if ((Terminal.c_cflag & CS7) == CS7) + Num_bits = 7; + else if ((Terminal.c_cflag & CS6) == CS6) + Num_bits = 6; + else + Num_bits = 5; + value = Terminal.c_cflag & 037; + switch (value) { + case 01: speed = 50.0; + break; + case 02: speed = 75.0; + break; + case 03: speed = 110.0; + break; + case 04: speed = 134.5; + break; + case 05: speed = 150.0; + break; + case 06: speed = 200.0; + break; + case 07: speed = 300.0; + break; + case 010: speed = 600.0; + break; + case 011: speed = 900.0; + break; + case 012: speed = 1200.0; + break; + case 013: speed = 1800.0; + break; + case 014: speed = 2400.0; + break; + case 015: speed = 3600.0; + break; + case 016: speed = 4800.0; + break; + case 017: speed = 7200.0; + break; + case 020: speed = 9600.0; + break; + case 021: speed = 19200.0; + break; + case 022: speed = 38400.0; + break; + default: speed = 0.0; + } +#else + value = ioctl(0, TIOCGETP, &Terminal); + if (Terminal.sg_flags & EVENP) + Parity = 2; + else if (Terminal.sg_flags & ODDP) + Parity = 1; + value = Terminal.sg_ospeed; + switch (value) { + case 01: speed = 50.0; + break; + case 02: speed = 75.0; + break; + case 03: speed = 110.0; + break; + case 04: speed = 134.5; + break; + case 05: speed = 150.0; + break; + case 06: speed = 200.0; + break; + case 07: speed = 300.0; + break; + case 010: speed = 600.0; + break; + case 011: speed = 1200.0; + break; + case 012: speed = 1800.0; + break; + case 013: speed = 2400.0; + break; + case 014: speed = 4800.0; + break; + case 015: speed = 9600.0; + break; + default: speed = 0.0; + } +#endif + chars_per_millisecond = (0.001 * speed) / 8.0; + TERMINAL_TYPE = getenv("TERM"); + if (TERMINAL_TYPE == NULL) + { + printf("unknown terminal type\n"); + exit(0); + } +#ifndef CAP + Fildes = -1; + TERM_PATH = getenv("TERMINFO"); + if (TERM_PATH != NULL) + { + Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); + Term_File_name = malloc(Data_Line_len); + sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); + Fildes = open(Term_File_name, O_RDONLY); + } + if (Fildes == -1) + { + TERM_PATH = "/usr/lib/terminfo"; + Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); + Term_File_name = malloc(Data_Line_len); + sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); + Fildes = open(Term_File_name, O_RDONLY); + } + if (Fildes == -1) + { + TERM_PATH = "/usr/share/lib/terminfo"; + Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); + Term_File_name = malloc(Data_Line_len); + sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); + Fildes = open(Term_File_name, O_RDONLY); + } + if (Fildes == -1) + { + TERM_PATH = "/usr/share/terminfo"; + Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); + Term_File_name = malloc(Data_Line_len); + sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); + Fildes = open(Term_File_name, O_RDONLY); + } + if (Fildes == -1) + { + free(Term_File_name); + Term_File_name = NULL; + } + else + TERM_INFO = INFO_PARSE(); +#else + /* + | termcap information can be in the TERMCAP env variable, if so + | use that, otherwise check the /etc/termcap file + */ + if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL) + { + if (*Term_File_name != '/') + Term_File_name = "/etc/termcap"; + } + else + { + Term_File_name = "/etc/termcap"; + } + if ((TFP = fopen(Term_File_name, "r")) == NULL) + { + printf("unable to open /etc/termcap file \n"); + exit(0); + } + for (value = 0; value < 1024; value++) + String_table[value] = NULL; + for (value = 0; value < 128; value++) + Booleans[value] = 0; + for (value = 0; value < 128; value++) + Numbers[value] = 0; + Data_Line = malloc(512); + if (pointer && *pointer != '/') + { + TERM_data_ptr = pointer; + CAP_PARSE(); + } + else + { + Find_term(); + CAP_PARSE(); + } +#endif + if (String_table[pc__] == NULL) + String_table[pc__] = "\0"; + if ((String_table[cm__] == NULL) || (Booleans[hc__])) + { + fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n"); + exit(0); + } + Key_Get(); + keys_vt100(); + LINES = Numbers[li__]; + COLS = Numbers[co__]; + if ((lines_string = getenv("LINES")) != NULL) + { + value = atoi(lines_string); + if (value > 0) + LINES = value; + } + if ((columns_string = getenv("COLUMNS")) != NULL) + { + value = atoi(columns_string); + if (value > 0) + COLS = value; + } +#ifdef TIOCGWINSZ + /* + | get the window size + */ + if (ioctl(0, TIOCGWINSZ, &ws) >= 0) + { + if (ws.ws_row > 0) + LINES = ws.ws_row; + if (ws.ws_col > 0) + COLS = ws.ws_col; + } +#endif + virtual_scr = newwin(LINES, COLS, 0, 0); + stdscr = newwin(LINES, COLS, 0, 0); + curscr = newwin(LINES, COLS, 0, 0); + wmove(stdscr, 0, 0); + werase(stdscr); + Repaint_screen = TRUE; + initialized = TRUE; + virtual_lines = (int *) malloc(LINES * (sizeof(int))); + +#ifdef SIGWINCH + /* + | reset size of windows and LINES and COLS if term window + | changes size + */ + signal(SIGWINCH, reinitscr); +#endif /* SIGWINCH */ + + /* + | check if scrolling is available + */ + + nc_scrolling_ability = ((String_table[al__] != NULL) && + (String_table[dl__])) || ((String_table[cs__]) + && (String_table[sr__])); + +} + +#ifndef CAP +int +Get_int() /* get a two-byte integer from the terminfo file */ +{ + int High_byte; + int Low_byte; + int temp; + + Low_byte = *((unsigned char *) TERM_data_ptr++); + High_byte = *((unsigned char *) TERM_data_ptr++); + if (Flip_Bytes) + { + temp = Low_byte; + Low_byte = High_byte; + High_byte = temp; + } + if ((High_byte == 255) && (Low_byte == 255)) + return (-1); + else + return(Low_byte + (High_byte * 256)); +} + +int +INFO_PARSE() /* parse off the data in the terminfo data file */ +{ + int offset; + int magic_number = 0; + int counter = 0; + int Num_names = 0; + int Num_bools = 0; + int Num_ints = 0; + int Num_strings = 0; + int string_table_len = 0; + char *temp_ptr; + + TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char)))); + Data_Line_len = read(Fildes, Data_Line, 10240); + if ((Data_Line_len >= 10240) || (Data_Line_len < 0)) + return(0); + /* + | get magic number + */ + magic_number = Get_int(); + /* + | if magic number not right, reverse byte order and check again + */ + if (magic_number != 282) + { + Flip_Bytes = TRUE; + TERM_data_ptr--; + TERM_data_ptr--; + magic_number = Get_int(); + if (magic_number != 282) + return(0); + } + /* + | get the number of each type in the terminfo data file + */ + Num_names = Get_int(); + Num_bools = Get_int(); + Num_ints = Get_int(); + Num_strings = Get_int(); + string_table_len = Get_int(); + Strings = malloc(string_table_len); + while (Num_names > 0) + { + TERM_data_ptr++; + Num_names--; + } + counter = 0; + while (Num_bools) + { + Num_bools--; + Booleans[counter++] = *TERM_data_ptr++; + } + if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */ + TERM_data_ptr++; + counter = 0; + while (Num_ints) + { + Num_ints--; + Numbers[counter] = Get_int(); + counter++; + } + temp_ptr = TERM_data_ptr + Num_strings + Num_strings; + memcpy(Strings, temp_ptr, string_table_len); + counter = bt__; + while (Num_strings) + { + Num_strings--; + if ((offset=Get_int()) != -1) + { + if (String_table[counter] == NULL) + String_table[counter] = Strings + offset; + } + else + String_table[counter] = NULL; + counter++; + } + close(Fildes); + free(Data_Line); + return(TRUE); +} +#endif /* ifndef CAP */ + +int +AtoI() /* convert ascii text to integers */ +{ + int Temp; + + Temp = 0; + while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) + { + Temp = (Temp * 10) + (*TERM_data_ptr - '0'); + TERM_data_ptr++; + } + return(Temp); +} + +void +Key_Get() /* create linked list with all key sequences obtained from terminal database */ +{ + int Counter; + int Klen; + int key_def; + struct KEY_STACK *Spoint; + + Max_Key_len = 0; + Counter = 0; + key_def = kb__; + while (key_def <= kf63__) + { + if (key_def == ke__) + key_def = K1__; + else if (key_def == (K5__ + 1)) + key_def = kcbt__; + else if (key_def == (kcbt__ + 1)) + key_def = kbeg__; + else if (key_def == (kUND__ + 1)) + key_def = kf11__; + if (String_table[key_def] != NULL) + { + if (KEY_TOS == NULL) + Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); + else + { + Spoint = KEY_TOS; + while (Spoint->next != NULL) + Spoint = Spoint->next; + Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); + Spoint = Spoint->next; + } + Spoint->next = NULL; + Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS)); + Spoint->element->string = String_table[key_def]; + Spoint->element->length = strlen(String_table[key_def]); + Spoint->element->value = Key_vals[Counter]; + Klen = strlen(Spoint->element->string); + if (Klen > Max_Key_len) + Max_Key_len = Klen; + /* + | Some terminal types accept keystrokes of the form + | \E[A and \EOA, substituting '[' for 'O'. Make a + | duplicate of such key strings (since the + | database will only have one version) so new_curse + | can understand both. + */ + if ((Spoint->element->length > 1) && + ((String_table[key_def][1] == '[') || + (String_table[key_def][1] == 'O'))) + { + Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); + Spoint = Spoint->next; + Spoint->next = NULL; + Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS)); + Spoint->element->length = strlen(String_table[key_def]); + Spoint->element->string = malloc(Spoint->element->length + 1); + strcpy(Spoint->element->string, String_table[key_def]); + Spoint->element->value = Key_vals[Counter]; + Klen = strlen(Spoint->element->string); + if (Klen > Max_Key_len) + Max_Key_len = Klen; + + if (String_table[key_def][1] == '[') + Spoint->element->string[1] = 'O'; + else + Spoint->element->string[1] = '['; + } + } + key_def++; + Counter++; + } +} + +/* + | insert information about keys for a vt100 terminal + */ + +void +keys_vt100() +{ + int counter; + int Klen; + struct KEY_STACK *Spoint; + + Spoint = KEY_TOS; + while (Spoint->next != NULL) + Spoint = Spoint->next; + for (counter = 0; vt100[counter].length != 0; counter++) + { + Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); + Spoint = Spoint->next; + Spoint->next = NULL; + Spoint->element = &vt100[counter]; + Klen = strlen(Spoint->element->string); + if (Klen > Max_Key_len) + Max_Key_len = Klen; + } +} + +#ifdef CAP +char * +String_Get(param) /* read the string */ +char *param; +{ + char *String; + char *Temp; + int Counter; + + if (param == NULL) + { + while (*TERM_data_ptr != '=') + TERM_data_ptr++; + Temp = ++TERM_data_ptr; + Counter = 1; + while ((*Temp != ':') && (*Temp != (char)NULL)) + { + Counter++; + Temp++; + } + if (Counter == 1) /* no data */ + return(NULL); + String = Temp = malloc(Counter); + while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL)) + { + if (*TERM_data_ptr == '\\') + { + TERM_data_ptr++; + if (*TERM_data_ptr == 'n') + *Temp = '\n'; + else if (*TERM_data_ptr == 't') + *Temp = '\t'; + else if (*TERM_data_ptr == 'b') + *Temp = '\b'; + else if (*TERM_data_ptr == 'r') + *Temp = '\r'; + else if (*TERM_data_ptr == 'f') + *Temp = '\f'; + else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E')) + *Temp = '\033'; /* escape */ + else if (*TERM_data_ptr == '\\') + *Temp = '\\'; + else if (*TERM_data_ptr == '\'') + *Temp = '\''; + else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) + { + Counter = 0; + while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) + { + Counter = (8 * Counter) + (*TERM_data_ptr - '0'); + TERM_data_ptr++; /* ? */ + } + *Temp = Counter; + TERM_data_ptr--; + } + TERM_data_ptr++; + Temp++; + } + else if (*TERM_data_ptr == '^') + { + TERM_data_ptr++; + if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_')) + *Temp = *TERM_data_ptr - '@'; + else if (*TERM_data_ptr == '?') + *Temp = 127; + TERM_data_ptr++; + Temp++; + } + else + *Temp++ = *TERM_data_ptr++; + } + *Temp = (char)NULL; + param = String; + } + else + { + while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':')) + TERM_data_ptr++; + } + return(param); +} + +int +tc_Get_int(param) /* read the integer */ +int param; +{ + int Itemp; + + if (param == 0) + { + while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#')) + TERM_data_ptr++; + TERM_data_ptr++; + Itemp = AtoI(); + param = Itemp; + } + else + { + while (*TERM_data_ptr != ':') + TERM_data_ptr++; + } + return(param); +} + +void +Find_term() /* find terminal description in termcap file */ +{ + char *Name; + char *Ftemp; + + Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1); + strcpy(Name, TERMINAL_TYPE); + while (*Ftemp != (char)NULL) + Ftemp++; + *Ftemp++ = '|'; + *Ftemp = (char)NULL; + CFOUND = FALSE; + Data_Line_len = strlen(TERMINAL_TYPE) + 1; + while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL)) + { + if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#')) + { + while ((!CFOUND) && (*TERM_data_ptr != (char)NULL)) + { + CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len); + while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':')) + TERM_data_ptr++; + if (*TERM_data_ptr == '|') + TERM_data_ptr++; + else if (!CFOUND) + *TERM_data_ptr = (char)NULL; + } + } + } + if (!CFOUND) + { + printf("terminal type %s not found\n", TERMINAL_TYPE); + exit(0); + } +} + +void +CAP_PARSE() /* parse off the data in the termcap data file */ +{ + int offset; + int found; + + do + { + while (*TERM_data_ptr != (char)NULL) + { + for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++) + { + if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2)) + { + found = TRUE; + Booleans[offset] = TRUE; + } + } + if (!found) + { + for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++) + { + if (!strncmp(TERM_data_ptr, Number_names[offset], 3)) + { + found = TRUE; + Numbers[offset] = tc_Get_int(Numbers[offset]); + } + } + } + if (!found) + { + for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++) + { + if (!strncmp(TERM_data_ptr, String_names[offset], 3)) + { + found = TRUE; + String_table[offset] = String_Get(String_table[offset]); + } + } + } + + if (!strncmp(TERM_data_ptr, "tc=", 3)) + tc_ = String_Get(NULL); + while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL)) + TERM_data_ptr++; + if (*TERM_data_ptr == ':') + TERM_data_ptr++; + } + } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t'))); + if (tc_ != NULL) + { + TERMINAL_TYPE = tc_; + rewind(TFP); + Find_term(); + tc_ = NULL; + CAP_PARSE(); + } + else + fclose(TFP); +} +#endif /* ifdef CAP */ + +struct _line * +Screenalloc(columns) +int columns; +{ + int i; + struct _line *tmp; + + tmp = (struct _line *) malloc(sizeof (struct _line)); + tmp->row = malloc(columns + 1); + tmp->attributes = malloc(columns + 1); + tmp->prev_screen = NULL; + tmp->next_screen = NULL; + for (i = 0; i < columns; i++) + { + tmp->row[i] = ' '; + tmp->attributes[i] = (char) NULL; + } + tmp->scroll = tmp->changed = FALSE; + tmp->row[0] = (char) NULL; + tmp->attributes[0] = (char) NULL; + tmp->row[columns] = (char) NULL; + tmp->attributes[columns] = (char) NULL; + tmp->last_char = 0; + return(tmp); +} + +WINDOW *newwin(lines, cols, start_l, start_c) +int lines, cols; /* number of lines and columns to be in window */ +int start_l, start_c; /* starting line and column to be inwindow */ +{ + WINDOW *Ntemp; + struct _line *temp_screen; + int i; + + Ntemp = (WINDOW *) malloc(sizeof(WINDOW)); + Ntemp->SR = start_l; + Ntemp->SC = start_c; + Ntemp->Num_lines = lines; + Ntemp->Num_cols = cols; + Ntemp->LX = 0; + Ntemp->LY = 0; + Ntemp->scroll_down = Ntemp->scroll_up = 0; + Ntemp->SCROLL_CLEAR = FALSE; + Ntemp->Attrib = FALSE; + Ntemp->first_line = temp_screen = Screenalloc(cols); + Ntemp->first_line->number = 0; + Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *)); + + Ntemp->line_array[0] = Ntemp->first_line; + + for (i = 1; i < lines; i++) + { + temp_screen->next_screen = Screenalloc(cols); + temp_screen->next_screen->number = i; + temp_screen->next_screen->prev_screen = temp_screen; + temp_screen = temp_screen->next_screen; + Ntemp->line_array[i] = temp_screen; + } + Ntemp->first_line->prev_screen = NULL; + temp_screen->next_screen = NULL; + return(Ntemp); +} + +#ifdef CAP +void +Cap_Out(string, p_list, place) /* interpret the output string if necessary */ +char *string; +int p_list[]; /* stack of values */ +int place; /* place keeper of top of stack */ +{ + char *Otemp; /* temporary string pointer to parse output */ + int delay; + int p1, p2, temp; + float chars; + + if (string == NULL) + return; + + if (p_list != NULL) + { + p1 = p_list[--place]; + p2 = p_list[--place]; + } + delay = 0; + Otemp = string; + if ((*Otemp >= '0') && (*Otemp <= '9')) + { + delay = atoi(Otemp); + while ((*Otemp >= '0') && (*Otemp <= '9')) + Otemp++; + if (*Otemp == '*') + Otemp++; + } + while (*Otemp != (char)NULL) + { + if (*Otemp == '%') + { + Otemp++; + if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+')) + { + if (*Otemp == 'd') + printf("%d", p1); + else if (*Otemp == '2') + printf("%02d", p1); + else if (*Otemp == '3') + printf("%03d", p1); + else if (*Otemp == '+') + { + Otemp++; + p1 += *Otemp; + putchar(p1); + } + else if (*Otemp == '.') + putchar(p1); + p1 = p2; + p2 = 0; + } + else if (*Otemp == '>') + { + Otemp++; + if (p1 > *Otemp) + { + Otemp++; + p1 += *Otemp; + } + else + Otemp++; + } + else if (*Otemp == 'r') + { + temp = p1; + p1 = p2; + p2 = temp; + } + else if (*Otemp == 'i') + { + p1++; + p2++; + } + else if (*Otemp == '%') + putchar(*Otemp); + else if (*Otemp == 'n') + { + p1 ^= 0140; + p2 ^= 0140; + } + else if (*Otemp == 'B') + { + p1 = (16 * (p1/10)) + (p1 % 10); + p2 = (16 * (p2/10)) + (p2 % 10); + } + else if (*Otemp == 'D') + { + p1 = (p1 - 2 * (p1 % 16)); + p2 = (p2 - 2 * (p2 % 16)); + } + } + else + putchar (*Otemp); + Otemp++; + } + if (delay != 0) + { + chars = delay * chars_per_millisecond; + delay = chars; + if ((chars - delay) > 0.0) + delay++; + for (; delay > 0; delay--) + putchar(*String_table[pc__]); + } + fflush(stdout); +} + +#else + + char *Otemp; /* temporary string pointer to parse output */ + float chars; + int p[10]; + int variable[27]; + +int +Operation(Temp_Stack, place) /* handle conditional operations */ +int Temp_Stack[]; +int place; +{ + int temp; + + if (*Otemp == 'd') + { + Otemp++; + temp = Temp_Stack[--place]; + printf("%d", temp); + } + else if (!strncmp(Otemp, "2d", 2)) + { + temp = Temp_Stack[--place]; + printf("%2d", temp); + Otemp++; + Otemp++; + } + else if (!strncmp(Otemp, "3d", 2)) + { + temp = Temp_Stack[--place]; + printf("%0d", temp); + Otemp++; + Otemp++; + } + else if (!strncmp(Otemp, "02d", 3)) + { + temp = Temp_Stack[--place]; + printf("%02d", temp); + Otemp++; + Otemp++; + Otemp++; + } + else if (!strncmp(Otemp, "03d", 3)) + { + temp = Temp_Stack[--place]; + printf("%03d", temp); + Otemp++; + Otemp++; + Otemp++; + } + else if (*Otemp == '+') + { + Otemp++; + temp = Temp_Stack[--place]; + temp += Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '-') + { + Otemp++; + temp = Temp_Stack[--place]; + temp -= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '*') + { + Otemp++; + temp = Temp_Stack[--place]; + temp *= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '/') + { + Otemp++; + temp = Temp_Stack[--place]; + temp /= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == 'm') + { + Otemp++; + temp = Temp_Stack[--place]; + temp %= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '&') + { + Otemp++; + temp = Temp_Stack[--place]; + temp &= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '|') + { + Otemp++; + temp = Temp_Stack[--place]; + temp |= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '^') + { + Otemp++; + temp = Temp_Stack[--place]; + temp ^= Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '=') + { + Otemp++; + temp = Temp_Stack[--place]; + temp = (temp == Temp_Stack[--place]); + Temp_Stack[place++] = temp; + } + else if (*Otemp == '>') + { + Otemp++; + temp = Temp_Stack[--place]; + temp = temp > Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == '<') + { + Otemp++; + temp = Temp_Stack[--place]; + temp = temp < Temp_Stack[--place]; + Temp_Stack[place++] = temp; + } + else if (*Otemp == 'c') + { + Otemp++; + putchar(Temp_Stack[--place]); + } + else if (*Otemp == 'i') + { + Otemp++; + p[1]++; + p[2]++; + } + else if (*Otemp == '%') + { + putchar(*Otemp); + Otemp++; + } + else if (*Otemp == '!') + { + temp = ! Temp_Stack[--place]; + Temp_Stack[place++] = temp; + Otemp++; + } + else if (*Otemp == '~') + { + temp = ~Temp_Stack[--place]; + Temp_Stack[place++] = temp; + Otemp++; + } + else if (*Otemp == 'p') + { + Otemp++; + Temp_Stack[place++] = p[*Otemp - '0']; + Otemp++; + } + else if (*Otemp == 'P') + { + Otemp++; + Temp_Stack[place++] = variable[*Otemp - 'a']; + Otemp++; + } + else if (*Otemp == 'g') + { + Otemp++; + variable[*Otemp - 'a'] = Temp_Stack[--place]; + Otemp++; + } + else if (*Otemp == '\'') + { + Otemp++; + Temp_Stack[place++] = *Otemp; + Otemp++; + Otemp++; + } + else if (*Otemp == '{') + { + Otemp++; + temp = atoi(Otemp); + Temp_Stack[place++] = temp; + while (*Otemp != '}') + Otemp++; + Otemp++; + } + return(place); +} + +void +Info_Out(string, p_list, place) /* interpret the output string if necessary */ +char *string; +int p_list[]; +int place; +{ + char *tchar; + int delay; + int temp; + int Cond_FLAG; + int EVAL; + int Cond_Stack[128]; + int Cond_place; + int Stack[128]; + int Top_of_stack; + + if (string == NULL) + return; + + Cond_FLAG = FALSE; + Cond_place = 0; + Top_of_stack = 0; + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; + p[4] = 0; + p[5] = 0; + p[6] = 0; + p[7] = 0; + p[8] = 0; + p[9] = 0; + if (p_list != NULL) + { + for (temp = 1; (place != 0); temp++) + { + p[temp] = p_list[--place]; + } + } + delay = 0; + Otemp = string; + while (*Otemp != (char) NULL) + { + if (*Otemp == '%') + { + Otemp++; + if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';')) + { + if (*Otemp == '?') + { + Otemp++; + Cond_FLAG = TRUE; + EVAL = TRUE; + while (EVAL) + { + /* + | find the end of the + | conditional statement + */ + while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL)) + { + /* + | move past '%' + */ + Otemp++; + Cond_place = Operation(Cond_Stack, Cond_place); + } + + /* + | if condition is true + */ + if ((Cond_place > 0) && (Cond_Stack[Cond_place-1])) + { + /* + | end conditional + | parsing + */ + EVAL = FALSE; + Otemp++; + Otemp++; + } + else /* condition is false */ + { + /* + | find 'else' or end + | of if statement + */ + while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL)) + Otemp++; + /* + | if an 'else' found + */ + if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2))) + { + Otemp++; + Otemp++; + tchar = Otemp; + /* + | check for 'then' part + */ + while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2))) + tchar++; + /* + | if end of string + */ + if (*tchar == (char) NULL) + { + EVAL = FALSE; + Cond_FLAG = FALSE; + Otemp = tchar; + } + /* + | if end of if found, + | set up to parse + | info + */ + else if (!strncmp(tchar, "%;", 2)) + EVAL = FALSE; + /* + | otherwise, check + | conditional in + | 'else' + */ + } + /* + | if end of if found, + | get out of if + | statement + */ + else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2))) + { + EVAL = FALSE; + Otemp++; + Otemp++; + } + else /* Otemp == NULL */ + { + EVAL = FALSE; + Cond_FLAG = FALSE; + } + } + } + } + else + { + Otemp++; + Cond_FLAG = FALSE; + if (*Otemp != ';') + { + while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2))) + Otemp++; + if (*Otemp != (char) NULL) + { + Otemp++; + Otemp++; + } + } + else + Otemp++; + } + } + else + { + Top_of_stack = Operation(Stack, Top_of_stack); + } + } + else if (!strncmp(Otemp, "$<", 2)) + { + Otemp++; + Otemp++; + delay = atoi(Otemp); + while (*Otemp != '>') + Otemp++; + Otemp++; + chars = delay * chars_per_millisecond; + delay = chars; + if ((chars - delay) > 0.0) + delay++; + if (String_table[pc__] == NULL) + temp = 0; + else + temp = *String_table[pc__]; + for (; delay > 0; delay--) + putc(temp, stdout); + } + else + { + putchar(*Otemp); + Otemp++; + } + } + fflush(stdout); +} +#endif + +void +wmove(window, row, column) /* move cursor to indicated position in window */ +WINDOW *window; +int row, column; +{ + if ((row < window->Num_lines) && (column < window->Num_cols)) + { + window->LX = column; + window->LY = row; + } +} + +void +clear_line(line, column, cols) +struct _line *line; +int column; +int cols; +{ + int j; + + if (column > line->last_char) + { + for (j = line->last_char; j < column; j++) + { + line->row[j] = ' '; + line->attributes[j] = (char) NULL; + } + } + line->last_char = column; + line->row[column] = (char) NULL; + line->attributes[column] = (char) NULL; + line->changed = TRUE; +} + +void +werase(window) /* clear the specified window */ +WINDOW *window; +{ + int i; + struct _line *tmp; + + window->SCROLL_CLEAR = CLEAR; + window->scroll_up = window->scroll_down = 0; + for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen) + clear_line(tmp, 0, window->Num_cols); +} + +void +wclrtoeol(window) /* erase from current cursor position to end of line */ +WINDOW *window; +{ + int column, row; + struct _line *tmp; + + window->SCROLL_CLEAR = CHANGE; + column = window->LX; + row = window->LY; + for (row = 0, tmp = window->first_line; row < window->LY; row++) + tmp = tmp->next_screen; + clear_line(tmp, column, window->Num_cols); +} + +void +wrefresh(window) /* flush all previous output */ +WINDOW *window; +{ + wnoutrefresh(window); +#ifdef DIAG +{ + struct _line *temp; + int value; + fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR); + for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen) + { + if (temp->number == -1) + fprintf(stderr, "line moved "); + if (temp->scroll) + fprintf(stderr, "scroll_x is set: "); + fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row); + } + fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n"); + fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines); + for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen) + { + if (temp->number == -1) + fprintf(stderr, "line moved "); + if (temp->scroll) + fprintf(stderr, "scroll_x is set: "); + fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row); + } + fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines); + for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen) + fprintf(stderr, "line=%s|\n", temp->row); +} +#endif + doupdate(); + virtual_scr->SCROLL_CLEAR = FALSE; + virtual_scr->scroll_down = virtual_scr->scroll_up = 0; + fflush(stdout); +} + +void +touchwin(window) +WINDOW *window; +{ + struct _line *user_line; + int line_counter = 0; + + for (line_counter = 0, user_line = window->first_line; + line_counter < window->Num_lines; line_counter++) + { + user_line->changed = TRUE; + } + window->SCROLL_CLEAR = TRUE; +} + +void +wnoutrefresh(window) +WINDOW *window; +{ + struct _line *user_line; + struct _line *virtual_line; + int line_counter = 0; + int user_col = 0; + int virt_col = 0; + + if (window->SR >= virtual_scr->Num_lines) + return; + user_line = window->first_line; + virtual_line = virtual_scr->first_line; + virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR; + virtual_scr->LX = window->LX + window->SC; + virtual_scr->LY = window->LY + window->SR; + virtual_scr->scroll_up = window->scroll_up; + virtual_scr->scroll_down = window->scroll_down; + if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR)) + return; + for (line_counter = 0; line_counter < window->SR; line_counter++) + { + virtual_line = virtual_line->next_screen; + } + for (line_counter = 0; (line_counter < window->Num_lines) + && ((line_counter + window->SR) < virtual_scr->Num_lines); + line_counter++) + { + if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR)) + { + for (user_col = 0, virt_col = window->SC; + (virt_col < virtual_scr->Num_cols) + && (user_col < user_line->last_char); + virt_col++, user_col++) + { + virtual_line->row[virt_col] = user_line->row[user_col]; + virtual_line->attributes[virt_col] = user_line->attributes[user_col]; + } + for (user_col = user_line->last_char, + virt_col = window->SC + user_line->last_char; + (virt_col < virtual_scr->Num_cols) + && (user_col < window->Num_cols); + virt_col++, user_col++) + { + virtual_line->row[virt_col] = ' '; + virtual_line->attributes[virt_col] = (char) NULL; + } + } + if (virtual_scr->Num_cols != window->Num_cols) + { + if (virtual_line->last_char < (user_line->last_char + window->SC)) + { + if (virtual_line->row[virtual_line->last_char] == (char) NULL) + virtual_line->row[virtual_line->last_char] = ' '; + virtual_line->last_char = + min(virtual_scr->Num_cols, + (user_line->last_char + window->SC)); + } + } + else + virtual_line->last_char = user_line->last_char; + virtual_line->row[virtual_line->last_char] = (char) NULL; + virtual_line->changed = user_line->changed; + virtual_line = virtual_line->next_screen; + user_line = user_line->next_screen; + } + window->SCROLL_CLEAR = FALSE; + window->scroll_up = window->scroll_down = 0; + last_window_refreshed = window; +} + +void +flushinp() /* flush input */ +{ +} + +void +ungetch(c) /* push a character back on input */ +int c; +{ + if (bufp < 100) + in_buff[bufp++] = c; +} + +#ifdef BSD_SELECT +int +timed_getchar() +{ + struct timeval tv; + fd_set fds; + int ret_val; + int nfds = 1; + char temp; + + FD_ZERO(&fds); + tv.tv_sec = 0; + tv.tv_usec = 500000; /* half a second */ + FD_SET(0, &fds); + Time_Out = FALSE; /* just in case */ + + ret_val = select(nfds, &fds, 0, 0, &tv); + + /* + | if ret_val is less than zero, there was no input + | otherwise, get a character and return it + */ + + if (ret_val <= 0) + { + Time_Out = TRUE; + return(-1); + } + + return(read(0, &temp, 1)? temp : -1); +} +#endif + +int +wgetch(window) /* get character from specified window */ +WINDOW *window; +{ + int in_value; + char temp; +#ifndef SYS5 + int old_arg; +#endif /* SYS5 */ + +#ifdef BSD_SELECT + if (Noblock) + in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar()); + else + in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1); +#else /* BSD_SELECT */ +#ifdef SYS5 + in_value = ((bufp > 0) ? in_buff[--bufp] : + (read(0, &temp, 1)> 0) ? temp : -1); +#else /* SYS5 */ + if (Noblock) + { + Time_Out = FALSE; + old_arg = fcntl(0, F_GETFL, 0); + in_value = fcntl(0, F_SETFL, old_arg | FNDELAY); + } + in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1); + if (Noblock) + { + fcntl(0, F_SETFL, old_arg); + if (Time_Out) + in_value = -1; + } +#endif /* SYS5 */ +#endif /* BSD_SELECT */ + + if (in_value != -1) + { + in_value &= 0xff; + if ((Parity) && (Num_bits < 8)) + /* strip eighth bit if parity in use */ + in_value &= 0177; + } + else if (interrupt_flag) + { + interrupt_flag = FALSE; + in_value = wgetch(window); + } + + if ((in_value == '\033') || (in_value == '\037'))/* escape character */ + in_value = Get_key(in_value); + return(in_value); +} + +#ifndef BSD_SELECT +void +Clear(arg) /* notify that time out has occurred */ +int arg; +{ + Time_Out = TRUE; +#ifdef DEBUG +fprintf(stderr, "inside Clear()\n"); +fflush(stderr); +#endif /* DEBUG */ +} +#endif /* BSD_SELECT */ + +int +Get_key(first_char) /* try to decode key sequence */ +int first_char; /* first character of sequence */ +{ + int in_char; + int Count; + char string[128]; + char *Gtemp; + int Found; +#ifdef SYS5 + struct termio Gterminal; +#else + struct sgttyb Gterminal; +#endif + struct KEY_STACK *St_point; +#if (!defined( BSD_SELECT)) || (!defined(SYS5)) + int value; +#endif /* BSD_SELECT */ + + Count = 0; + Gtemp = string; + string[Count++] = first_char; + string[Count] = (char) NULL; + Time_Out = FALSE; +#ifndef BSD_SELECT + signal(SIGALRM, Clear); + value = alarm(1); +#endif /* BSD_SELECT */ + Noblock = TRUE; +#ifdef SYS5 + Gterminal.c_cc[VTIME] = 0; /* timeout value */ + Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */ + Gterminal.c_lflag &= ~ECHO; /* disable echo */ +#endif + Count = 1; + Found = FALSE; + while ((Count < Max_Key_len) && (!Time_Out) && (!Found)) + { + in_char = wgetch(stdscr); +#ifdef DEBUG +fprintf(stderr, "back in GetKey()\n"); +fflush(stderr); +#endif /* DEBUG */ + if (in_char != -1) + { + string[Count++] = in_char; + string[Count] = (char) NULL; + St_point = KEY_TOS; + while ((St_point != NULL) && (!Found)) + { + if (!strcmp(string, St_point->element->string)) + Found = TRUE; + else + St_point = St_point->next; + } + } + } +#ifndef BSD_SELECT + if (!Time_Out) + value = alarm(0); +#endif /* BSD_SELECT */ +#ifdef SYS5 +/* value = ioctl(0, TCSETA, &Terminal);*/ +#else + value = ioctl(0, TIOCSETP, &Terminal); +/* value = fcntl(0, F_SETFL, old_arg);*/ +#endif + Noblock = FALSE; + if (Found) + { + return(St_point->element->value); + } + else + { + while (Count > 1) + { + if ((string[--Count] != -1) && + ((unsigned char) (string[Count]) != 255)) + { +#ifdef DIAG +fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout); +#endif + ungetch(string[Count]); + } + } + return(first_char); + } +} + +void +waddch(window, c) /* output the character in the specified window */ +WINDOW *window; +int c; +{ + int column, j; + int shift; /* number of spaces to shift if a tab */ + struct _line *tmpline; + +#ifdef DIAG +/*printf("starting waddch \n");fflush(stdout);*/ +#endif + column = window->LX; + if (c == '\t') + { + shift = (column + 1) % 8; + if (shift == 0) + shift++; + else + shift = 9 - shift; + while (shift > 0) + { + shift--; + waddch(window, ' '); + } + } + else if ((column < window->Num_cols) && (window->LY < window->Num_lines)) + { + if ((c == '~') && (Booleans[hz__])) + c = '@'; + + if (( c != '\b') && (c != '\n') && (c != '\r')) + { + tmpline = window->line_array[window->LY]; + tmpline->row[column] = c; + tmpline->attributes[column] = window->Attrib; + tmpline->changed = TRUE; + if (column >= tmpline->last_char) + { + if (column > tmpline->last_char) + for (j = tmpline->last_char; j < column; j++) + { + tmpline->row[j] = ' '; + tmpline->attributes[j] = (char) NULL; + } + tmpline->row[column + 1] = (char) NULL; + tmpline->attributes[column + 1] = (char) NULL; + tmpline->last_char = column + 1; + } + } + if (c == '\n') + { + wclrtoeol(window); + window->LX = window->Num_cols; + } + else if (c == '\r') + window->LX = 0; + else if (c == '\b') + window->LX--; + else + window->LX++; + } + if (window->LX >= window->Num_cols) + { + window->LX = 0; + window->LY++; + if (window->LY >= window->Num_lines) + { + window->LY = window->Num_lines - 1; +/* window->LY = row; + wmove(window, 0, 0); + wdeleteln(window); + wmove(window, row, 0);*/ + } + } + window->SCROLL_CLEAR = CHANGE; +} + +void +winsertln(window) /* insert a blank line into the specified window */ +WINDOW *window; +{ + int row, column; + struct _line *tmp; + struct _line *tmp1; + + window->scroll_down += 1; + window->SCROLL_CLEAR = SCROLL; + column = window->LX; + row = window->LY; + for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++) + tmp = tmp->next_screen; + if (tmp->prev_screen != NULL) + tmp->prev_screen->next_screen = NULL; + tmp1 = tmp; + clear_line(tmp1, 0, window->Num_cols); + tmp1->number = -1; + for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++) + tmp = tmp->next_screen; + if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1)) + { + tmp1->next_screen = tmp->next_screen; + tmp->next_screen = tmp1; + tmp->changed = TRUE; + tmp->next_screen->prev_screen = tmp; + } + else if (window->Num_lines > 1) + { + if (tmp->prev_screen != NULL) + tmp->prev_screen->next_screen = tmp1; + tmp1->prev_screen = tmp->prev_screen; + tmp->prev_screen = tmp1; + tmp1->next_screen = tmp; + tmp->changed = TRUE; + tmp->scroll = DOWN; + } + if (window->LY == 0) + window->first_line = tmp1; + + for (row = 0, tmp1 = window->first_line; + row < window->Num_lines; row++) + { + window->line_array[row] = tmp1; + tmp1 = tmp1->next_screen; + } +} + +void +wdeleteln(window) /* delete a line in the specified window */ +WINDOW *window; +{ + int row, column; + struct _line *tmp; + struct _line *tmpline; + + if (window->Num_lines > 1) + { + window->scroll_up += 1; + window->SCROLL_CLEAR = SCROLL; + column = window->LX; + row = window->LY; + for (row = 0, tmp = window->first_line; row < window->LY; row++) + tmp = tmp->next_screen; + if (window->LY == 0) + window->first_line = tmp->next_screen; + if (tmp->prev_screen != NULL) + tmp->prev_screen->next_screen = tmp->next_screen; + if (tmp->next_screen != NULL) + { + tmp->next_screen->changed = TRUE; + tmp->next_screen->scroll = UP; + tmp->next_screen->prev_screen = tmp->prev_screen; + } + tmpline = tmp; + clear_line(tmpline, 0, window->Num_cols); + tmpline->number = -1; + for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++) + tmp = tmp->next_screen; + if (tmp != NULL) + { + tmp->next_screen = tmpline; + tmp->next_screen->prev_screen = tmp; + tmp->changed = TRUE; + tmp = tmp->next_screen; + } + else + tmp = tmpline; + tmp->next_screen = NULL; + + for (row = 0, tmp = window->first_line; row < window->Num_lines; row++) + { + window->line_array[row] = tmp; + tmp = tmp->next_screen; + } + } + else + { + clear_line(window->first_line, 0, window->Num_cols); + } +} + +void +wclrtobot(window) /* delete from current position to end of the window */ +WINDOW *window; +{ + int row, column; + struct _line *tmp; + + window->SCROLL_CLEAR |= CLEAR; + column = window->LX; + row = window->LY; + for (row = 0, tmp = window->first_line; row < window->LY; row++) + tmp = tmp->next_screen; + clear_line(tmp, column, window->Num_cols); + for (row = (window->LY + 1); row < window->Num_lines; row++) + { + tmp = tmp->next_screen; + clear_line(tmp, 0, window->Num_cols); + } + wmove(window, row, column); +} + +void +wstandout(window) /* begin standout mode in window */ +WINDOW *window; +{ + if (Numbers[sg__] < 1) /* if not magic cookie glitch */ + window->Attrib |= A_STANDOUT; +} + +void +wstandend(window) /* end standout mode in window */ +WINDOW *window; +{ + window->Attrib &= ~A_STANDOUT; +} + +void +waddstr(window, string) /* write 'string' in window */ +WINDOW *window; +char *string; +{ + char *wstring; + + for (wstring = string; *wstring != (char) NULL; wstring++) + waddch(window, *wstring); +} + +void +clearok(window, flag) /* erase screen and redraw at next refresh */ +WINDOW *window; +int flag; +{ + Repaint_screen = TRUE; +} + + +void +echo() /* turn on echoing */ +{ + int value; + +#ifdef SYS5 + Terminal.c_lflag |= ECHO; /* enable echo */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#else + Terminal.sg_flags |= ECHO; /* enable echo */ + value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ +#endif +} + +void +noecho() /* turn off echoing */ +{ + int value; + +#ifdef SYS5 + Terminal.c_lflag &= ~ECHO; /* disable echo */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#else + Terminal.sg_flags &= ~ECHO; /* disable echo */ + value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ +#endif +} + +void +raw() /* set to read characters immediately */ +{ + int value; + +#ifdef SYS5 + Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */ + Terminal.c_lflag &= ~ICANON; /* disable canonical operation */ + Terminal.c_lflag &= ~ISIG; /* disable signal checking */ +#ifdef FLUSHO + Terminal.c_lflag &= ~FLUSHO; +#endif +#ifdef PENDIN + Terminal.c_lflag &= ~PENDIN; +#endif +#ifdef IEXTEN + Terminal.c_lflag &= ~IEXTEN; +#endif + Terminal.c_cc[VMIN] = 1; /* minimum of one character */ + Terminal.c_cc[VTIME] = 0; /* timeout value */ + Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#else + Terminal.sg_flags |= RAW; /* enable raw mode */ + value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ +#endif +} + +void +noraw() /* set to normal character read mode */ +{ + int value; + +#ifdef SYS5 + Terminal.c_lflag |= ICANON; /* enable canonical operation */ + Terminal.c_lflag |= ISIG; /* enable signal checking */ + Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */ + Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */ + Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#else + Terminal.sg_flags &= ~RAW; /* disable raw mode */ + value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ +/* old_arg = fcntl(0, F_GETFL, 0); + value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/ +#endif +} + +void +nl() +{ + int value; + +#ifdef SYS5 + Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#endif +} + +void +nonl() +{ + int value; + +#ifdef SYS5 + Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */ + Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */ + value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ +#endif +} + +void +saveterm() +{ +} + +void +fixterm() +{ +} + +void +resetterm() +{ +} + +void +nodelay(window, flag) +WINDOW *window; +int flag; +{ +} + +void +idlok(window, flag) +WINDOW *window; +int flag; +{ +} + +void +keypad(window, flag) +WINDOW *window; +int flag; +{ + if (flag) + String_Out(String_table[ks__], NULL, 0); + else + String_Out(String_table[ke__], NULL, 0); +} + +void +savetty() /* save current tty stats */ +{ + int value; + +#ifdef SYS5 + value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */ +#else + value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */ +#endif +} + +void +resetty() /* restore previous tty stats */ +{ + int value; + +#ifdef SYS5 + value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */ +#else + value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */ +#endif +} + +void +endwin() /* end windows */ +{ + keypad(stdscr, FALSE); + initialized = FALSE; + delwin(curscr); + delwin(virtual_scr); + delwin(stdscr); +#ifndef SYS5 +{ + int old_arg, value; +/* old_arg = fcntl(0, F_GETFL, 0); + value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/ +} +#endif +} + +void +delwin(window) /* delete the window structure */ +WINDOW *window; +{ + int i; + + for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++) + { + window->first_line = window->first_line->next_screen; + free(window->first_line->prev_screen->row); + free(window->first_line->prev_screen->attributes); + free(window->first_line->prev_screen); + } + if (window == last_window_refreshed) + last_window_refreshed = 0; + if (window->first_line != NULL) + { + free(window->first_line->row); + free(window->first_line->attributes); + free(window->first_line); + free(window); + } +} + +#ifndef __STDC__ +void +wprintw(va_alist) +va_dcl +#else /* __STDC__ */ +void +wprintw(WINDOW *window, const char *format, ...) +#endif /* __STDC__ */ +{ +#ifndef __STDC__ + WINDOW *window; + char *format; + va_list ap; +#else + va_list ap; +#endif + int value; + char *fpoint; + char *wtemp; + +#ifndef __STDC__ + va_start(ap); + window = va_arg(ap, WINDOW *); + format = va_arg(ap, char *); +#else /* __STDC__ */ + va_start(ap, format); +#endif /* __STDC__ */ + + fpoint = (char *) format; + while (*fpoint != (char) NULL) + { + if (*fpoint == '%') + { + fpoint++; + if (*fpoint == 'd') + { + value = va_arg(ap, int); + iout(window, value); + } + else if (*fpoint == 'c') + { + value = va_arg(ap, int); + waddch(window, value); + } + else if (*fpoint == 's') + { + wtemp = va_arg(ap, char *); + waddstr(window, wtemp); + } + fpoint++; + } + else if (*fpoint == '\\') + { + fpoint++; + if (*fpoint == 'n') + waddch(window, '\n'); + else if ((*fpoint >= '0') && (*fpoint <= '9')) + { + value = 0; + while ((*fpoint >= '0') && (*fpoint <= '9')) + { + value = (value * 8) + (*fpoint - '0'); + fpoint++; + } + waddch(window, value); + } + fpoint++; + } + else + waddch(window, *fpoint++); + } +#ifdef __STDC__ + va_end(ap); +#endif /* __STDC__ */ +} + +void +iout(window, value) /* output characters */ +WINDOW *window; +int value; +{ + int i; + + if ((i = value / 10) != 0) + iout(window, i); + waddch(window, ((value % 10) + '0')); +} + +int +Comp_line(line1, line2) /* compare lines */ +struct _line *line1; +struct _line *line2; +{ + int count1; + int i; + char *att1, *att2; + char *c1, *c2; + + if (line1->last_char != line2->last_char) + return(2); + + c1 = line1->row; + c2 = line2->row; + att1 = line1->attributes; + att2 = line2->attributes; + i = 0; + while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i])) + i++; + count1 = i + 1; + if ((count1 == 1) && (c1[i] == (char) NULL) && (c2[i] == (char) NULL)) + count1 = 0; /* both lines blank */ + else if ((c1[i] == (char) NULL) && (c2[i] == (char) NULL)) + count1 = -1; /* equal */ + else + count1 = 1; /* lines unequal */ + return(count1); +} + +struct _line * +Insert_line(row, end_row, window) /* insert line into screen */ +int row; +int end_row; +WINDOW *window; +{ + int i; + struct _line *tmp; + struct _line *tmp1; + + for (i = 0, tmp = curscr->first_line; i < window->SR; i++) + tmp = tmp->next_screen; + if ((end_row + window->SR) == 0) + curscr->first_line = curscr->first_line->next_screen; + top_of_win = tmp; + /* + | find bottom line to delete + */ + for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++) + tmp = tmp->next_screen; + if (tmp->prev_screen != NULL) + tmp->prev_screen->next_screen = tmp->next_screen; + if (tmp->next_screen != NULL) + tmp->next_screen->prev_screen = tmp->prev_screen; + tmp1 = tmp; + /* + | clear deleted line + */ + clear_line(tmp, 0, window->Num_cols); + tmp1->number = -1; + for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) + tmp = tmp->next_screen; + top_of_win = tmp; + for (i = 0, tmp = top_of_win; i < row; i++) + tmp = tmp->next_screen; + if ((tmp->prev_screen != NULL) && (window->Num_lines > 0)) + tmp->prev_screen->next_screen = tmp1; + tmp1->prev_screen = tmp->prev_screen; + tmp->prev_screen = tmp1; + tmp1->next_screen = tmp; + if ((row + window->SR) == 0) + curscr->first_line = tmp1; + if (tmp1->next_screen != NULL) + tmp1 = tmp1->next_screen; + + if ((!String_table[cs__]) && (end_row < window->Num_lines)) + { + Position(window, (window->SR + end_row), 0); + String_Out(String_table[dl__], NULL, 0); + } + Position(window, (window->SR + row), 0); + if (String_table[al__] != NULL) + String_Out(String_table[al__], NULL, 0); + else + String_Out(String_table[sr__], NULL, 0); + + for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++) + top_of_win = top_of_win->next_screen; + return(tmp1); +} + + +struct _line * +Delete_line(row, end_row, window) /* delete a line on screen */ +int row; +int end_row; +WINDOW *window; +{ + int i; + struct _line *tmp; + struct _line *tmp1; + struct _line *tmp2; + + i = 0; + tmp = curscr->first_line; + while (i < window->SR) + { + i++; + tmp = tmp->next_screen; + } + /* + | find line to delete + */ + top_of_win = tmp; + if ((row + window->SR) == 0) + curscr->first_line = top_of_win->next_screen; + for (i = 0, tmp = top_of_win; i < row; i++) + tmp = tmp->next_screen; + if (tmp->prev_screen != NULL) + tmp->prev_screen->next_screen = tmp->next_screen; + if (tmp->next_screen != NULL) + tmp->next_screen->prev_screen = tmp->prev_screen; + tmp2 = tmp->next_screen; + tmp1 = tmp; + /* + | clear deleted line + */ + clear_line(tmp1, 0, window->Num_cols); + tmp1->number = -1; + /* + | find location to insert deleted line + */ + for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) + tmp = tmp->next_screen; + top_of_win = tmp; + for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++) + tmp = tmp->next_screen; + tmp1->next_screen = tmp; + tmp1->prev_screen = tmp->prev_screen; + if (tmp1->prev_screen != NULL) + tmp1->prev_screen->next_screen = tmp1; + tmp->prev_screen = tmp1; + + Position(window, (window->SR + row), 0); + String_Out(String_table[dl__], NULL, 0); + if ((!String_table[cs__]) && (end_row < window->Num_lines)) + { + Position(window, (window->SR + end_row), 0); + String_Out(String_table[al__], NULL, 0); + } + else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL)) + { + Position(window, (window->SR + end_row), 0); + putchar('\n'); + } + + if (row == (window->Num_lines-1)) + tmp2 = tmp1; + if ((row + window->SR) == 0) + curscr->first_line = top_of_win = tmp2; + return(tmp2); +} + +void +CLEAR_TO_EOL(window, row, column) +WINDOW *window; +int row, column; +{ + int x, y; + struct _line *tmp1; + + for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++) + tmp1 = tmp1->next_screen; + for (x = column; x<window->Num_cols; x++) + { + tmp1->row[x] = ' '; + tmp1->attributes[x] = (char) NULL; + } + tmp1->row[column] = (char) NULL; + tmp1->last_char = column; + if (column < COLS) + { + if (STAND) + { + STAND = FALSE; + Position(window, row, column); + attribute_off(); + } + if (String_table[ce__] != NULL) + String_Out(String_table[ce__], NULL, 0); + else + { + for (x = column; x < window->Num_cols; x++) + putchar(' '); + Curr_x = x; + } + } +} + +int +check_delete(window, line, offset, pointer_new, pointer_old) +WINDOW *window; +int line, offset; +struct _line *pointer_new, *pointer_old; +{ + int end_old; + int end_new; + int k; + int changed; + char *old_lin; + char *new_lin; + char *old_att; + char *new_att; + + changed = FALSE; + new_lin = pointer_new->row; + new_att = pointer_new->attributes; + old_lin = pointer_old->row; + old_att = pointer_old->attributes; + end_old = end_new = offset; + while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != (char) NULL) && (new_lin[end_old] != (char) NULL)) + end_old++; + if (old_lin[end_old] != (char) NULL) + { + k = 0; + while ((old_lin[end_old+k] == new_lin[end_new+k]) && (new_att[end_new+k] == old_att[end_old+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10)) + k++; + if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))) + { + if (new_lin[end_new+k] == (char) NULL) + { + Position(window, line, (end_new+k)); + CLEAR_TO_EOL(window, line, (end_new+k)); + } + Position(window, line, offset); + for (k = offset; k < end_old; k++) + Char_del(old_lin, old_att, offset, window->Num_cols); + while ((old_lin[offset] != (char) NULL) && (offset < COLS)) + offset++; + pointer_old->last_char = offset; + changed = TRUE; + } + } + return(changed); +} + +/* + | Check if characters were inserted in the middle of a line, and if + | so, insert them. + */ + +int +check_insert(window, line, offset, pointer_new, pointer_old) +WINDOW *window; +int line, offset; +struct _line *pointer_new, *pointer_old; +{ + int changed; + int end_old, end_new; + int k; + int same = FALSE; + int old_off; + int insert; + char *old_lin; + char *new_lin; + char *old_att; + char *new_att; + + changed = FALSE; + new_lin = pointer_new->row; + new_att = pointer_new->attributes; + old_lin = pointer_old->row; + old_att = pointer_old->attributes; + end_old = end_new = offset; + while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != (char) NULL) && (old_lin[end_new] != (char) NULL)) + end_new++; + if (new_lin[end_new] != (char) NULL) + { + k = 0; + while ((old_lin[end_old+k] == new_lin[end_new+k]) && (old_att[end_old+k] == new_att[end_new+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10)) + k++; + /* + | check for commonality between rest of lines (are the old + | and new lines the same, except for a chunk in the middle?) + | if the rest of the lines are common, do not insert text + */ + old_off = end_new; + while ((old_lin[old_off] != (char) NULL) && (new_lin[old_off] != (char) NULL) && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off])) + old_off++; + if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off])) + same = TRUE; + if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))) + { + Position(window, line, offset); + insert = FALSE; + if (String_table[ic__] == NULL) + { + String_Out(String_table[im__], NULL, 0); + insert = TRUE; + } + for (k = offset; k < end_new; k++) + { + if (!insert) + String_Out(String_table[ic__], NULL, 0); + Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols); + } + if (insert) + String_Out(String_table[ei__], NULL, 0); + while ((old_lin[offset] != (char) NULL) && (offset < COLS)) + offset++; + pointer_old->last_char = offset; + changed = TRUE; + } + } + return(changed); +} + +void +doupdate() +{ + WINDOW *window; + int similar; + int diff; + int begin_old, begin_new; + int end_old, end_new; + int count1, j; + int from_top, tmp_ft, offset; + int changed; + int first_time; + int first_same; + int last_same; + int list[10]; + int bottom; + + struct _line *curr; + struct _line *virt; + struct _line *old; + + struct _line *new; + + struct _line *old1, *new1; + + char *cur_lin; + char *vrt_lin; + char *cur_att; + char *vrt_att; + char *att1, *att2; + char *c1, *c2; + + char NC_chinese = FALSE; /* flag to indicate handling Chinese */ + + window = virtual_scr; + + if ((nc_attributes & A_NC_BIG5) != 0) + NC_chinese = TRUE; + + if (Repaint_screen) + { + if (String_table[cl__]) + String_Out(String_table[cl__], NULL, 0); + else + { + from_top = 0; + while (from_top < LINES) + { + Position(curscr, from_top, 0); + if (String_table[ce__] != NULL) + String_Out(String_table[ce__], NULL, 0); + else + { + for (j = 0; j < window->Num_cols; j++) + putchar(' '); + } + from_top++; + } + } + for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen) + { + Position(curscr, from_top, 0); + for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++) + { + Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j); + } + if (STAND) + { + STAND = FALSE; + Position(curscr, from_top, j); + attribute_off(); + } + } + Repaint_screen = FALSE; + } + + similar = 0; + diff = FALSE; + top_of_win = curscr->first_line; + + for (from_top = 0, curr = top_of_win, virt = window->first_line; + from_top < window->Num_lines; from_top++) + { + virtual_lines[from_top] = TRUE; + if ((similar = Comp_line(curr, virt)) > 0) + { + virtual_lines[from_top] = FALSE; + diff = TRUE; + } + curr = curr->next_screen; + virt = virt->next_screen; + } + + from_top = 0; + virt = window->first_line; + curr = top_of_win; + similar = 0; + /* + | if the window has lines that are different, check for scrolling + */ + if (diff) + { + last_same = -1; + changed = FALSE; + for (first_same = window->Num_lines; + (first_same > from_top) && (virtual_lines[first_same - 1]); + first_same--) + ; + for (last_same = 0; + (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE); + last_same++) + ; + while ((from_top < first_same) && nc_scrolling_ability) + /* check entire lines for diffs */ + { + + if (from_top >= last_same) + { + for (last_same = from_top; + (last_same < window->Num_lines) && + (virtual_lines[last_same] == FALSE); + last_same++) + ; + } + if (!virtual_lines[from_top]) + { + diff = TRUE; + /* + | check for lines deleted (scroll up) + */ + for (tmp_ft = from_top+1, old = curr->next_screen; + ((window->scroll_up) && (diff) && + (tmp_ft < last_same) && + (!virtual_lines[tmp_ft])); + tmp_ft++) + { + if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top])) + { + /* + | Find the bottom of the + | area that should be + | scrolled. + */ + for (bottom = tmp_ft, old1 = old, + new1 = virt, count1 = 0; + (bottom < window->Num_lines) && + (Comp_line(old1, new1) <= 0); + bottom++, old1 = old1->next_screen, + new1 = new1->next_screen, + count1++) + ; + if (count1 > 3) + { + if (String_table[cs__]) /* scrolling region */ + { + list[1] = from_top; + list[0] = min((bottom - 1), (window->Num_lines - 1)); + String_Out(String_table[cs__], list, 2); + Curr_y = Curr_x = -1; + } + + for (offset = (tmp_ft - from_top); (offset > 0); offset--) + { + old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window); + diff = FALSE; + } + + if (String_table[cs__]) /* scrolling region */ + { + list[1] = 0; + list[0] = LINES - 1; + String_Out(String_table[cs__], list, 2); + Curr_y = Curr_x = -1; + } + + top_of_win = curscr->first_line; + curr = top_of_win; + for (offset = 0; offset < from_top; offset++) + curr = curr->next_screen; + for (offset = from_top, old=curr, new=virt; + offset < window->Num_lines; + old=old->next_screen, new=new->next_screen, + offset++) + { + similar = Comp_line(old, new); + virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); + } + } + } + else + old = old->next_screen; + } + /* + | check for lines inserted (scroll down) + */ + for (tmp_ft = from_top-1, old = curr->prev_screen; + ((window->scroll_down) && (tmp_ft >= 0) && + (diff) && + (!virtual_lines[tmp_ft])); + tmp_ft--) + { + if (Comp_line(old, virt) == -1) + { + /* + | Find the bottom of the + | area that should be + | scrolled. + */ + for (bottom = from_top, old1 = old, + new1 = virt, count1 = 0; + (bottom < window->Num_lines) && + (Comp_line(old1, new1) <= 0); + bottom++, old1 = old1->next_screen, + new1 = new1->next_screen, + count1++) + ; + if (count1 > 3) + { + if (String_table[cs__]) /* scrolling region */ + { + list[1] = tmp_ft; + list[0] = min((bottom - 1), (window->Num_lines - 1)); + String_Out(String_table[cs__], list, 2); + Curr_y = Curr_x = -1; + } + + for (offset = (from_top - tmp_ft); (offset > 0); offset--) + { + old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window); + diff = FALSE; + } + + if (String_table[cs__]) /* scrolling region */ + { + list[1] = 0; + list[0] = LINES - 1; + String_Out(String_table[cs__], list, 2); + Curr_y = Curr_x = -1; + } + + top_of_win = curscr->first_line; + curr = top_of_win; + for (offset = 0; offset < from_top; offset++) + curr = curr->next_screen; + for (offset = from_top, old=curr, new=virt; + offset < window->Num_lines; + old=old->next_screen, new=new->next_screen, + offset++) + { + similar = Comp_line(old, new); + virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); + } + } + } + else + old = old->prev_screen; + } + } + from_top++; + curr = curr->next_screen; + virt = virt->next_screen; + } + } + + + /* + | Scrolling done, now need to insert, delete, or modify text + | within lines. + */ + + for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++) + curr = curr->next_screen; + top_of_win = curr; + 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) + { + + /* + | If either 'insert mode' or 'insert char' are + | available, enter the following 'if' statement, + | else, need to simply rewrite the contents of the line + | at the point where the contents of the line change. + */ + + if (((String_table[ic__]) || (String_table[im__])) && + (String_table[dc__]) && (curr->row[0] != (char) NULL) && + (!NC_chinese)) + { + j = 0; + first_time = TRUE; + vrt_lin = virt->row; + vrt_att = virt->attributes; + cur_lin = curr->row; + cur_att = curr->attributes; + while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols)) + { + if ((STAND) && (Booleans[xs__])) + { + while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j])) + j++; + if ((STAND) && (!vrt_att[j])) + { + STAND = FALSE; + Position(window, from_top, j); + attribute_off(); + attribute_off(); + } + } + else + { + while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL)) + j++; + } + if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__])) + { + Position(window, from_top, j); +/* CLEAR_TO_EOL(window, from_top, j);*/ + attribute_off(); + attribute_off(); + } + if (vrt_lin[j] != (char) NULL) + { + begin_new = j; + begin_old = j; + end_old = j; + end_new = j; + if ((first_time) && (virt->changed)) + { + if (curr->last_char <= virt->last_char) + changed = check_insert(window, from_top, j, virt, curr); + } + changed = check_delete(window, from_top, j, virt, curr); + first_time = FALSE; + virt->changed = FALSE; + if (!changed) + changed = check_insert(window, from_top, j, virt, curr); + if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols)) + { + if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j])) + cur_lin[j] = ' '; + else + { + Position(window, from_top, j); + Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j); + } + } + if ((vrt_lin[j] != (char) NULL)) + j++; + } + if ((STAND) && (!vrt_att[j])) + { + STAND = FALSE; + Position(window, from_top, j); + attribute_off(); + } + } + if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL)) + { + Position(window, from_top, j); + CLEAR_TO_EOL(window, from_top, j); + } + } + else /*if ((similar != -1) && (similar != 0))*/ + { + j = 0; + c1 = curr->row; + att1 = curr->attributes; + c2 = virt->row; + att2 = virt->attributes; + while ((j < window->Num_cols) && (c2[j] != (char) NULL)) + { + while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL)) + j++; + + /* + | if previous character is an eight bit + | char, start redraw from that character + */ + + if ((NC_chinese) && (highbitset(c1[j - 1]))) + j--; + begin_old = j; + begin_new = j; + if ((j < window->Num_cols) && (c2[j] != (char) NULL)) + { + Position(window, from_top, begin_old); + CLEAR_TO_EOL(window, from_top, j); + Position(window, from_top, begin_old); + for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++) + Char_out(c2[j], att2[j], c1, att1, j); + } + } + if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL)) + { + Position(window, from_top, j); + CLEAR_TO_EOL(window, from_top, j); + } + } + if (STAND) + { + STAND = FALSE; + Position(window, from_top, j); + attribute_off(); + } + virt->number = from_top; + } + Position(window, window->LY, window->LX); +} + +void +Position(window, row, col) /* position the cursor for output on the screen */ +WINDOW *window; +int row; +int col; +{ + int list[10]; + int place; + + int pos_row; + int pos_column; + + pos_row = row + window->SR; + pos_column = col + window->SC; + if ((pos_row != Curr_y) || (pos_column != Curr_x)) + { + if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/ + { + place = 0; + list[place++] = pos_column; + list[place++] = pos_row; + String_Out(String_table[cm__], list, place); + if ((STAND) && (!Booleans[ms__])) + attribute_on(); + } + Curr_x = pos_column; + Curr_y = pos_row; + } +} + +void +Char_del(line, attrib, offset, maxlen) /* delete chars from line */ +char *line; +char *attrib; +int offset; +int maxlen; +{ + int one, two; + + for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++) + { + line[one] = line[two]; + attrib[one] = attrib[two]; + } + String_Out(String_table[dc__], NULL, 0); +} + +void +Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */ +char *line; +char *attrib; +char newc; +char newatt; +int offset; +int maxlen; +{ + int one, two; + + one = 0; + while ((line[one] != (char) NULL) && (one < (maxlen - 2))) + one++; + for (two = one + 1; (two > offset); one--, two--) + { + line[two] = line[one]; + attrib[two] = attrib[one]; + } + line[offset] = newc; + attrib[offset] = newatt; + Char_out(newc, newatt, line, attrib, offset); +} + +void +attribute_on() +{ + if (String_table[sa__]) + { + attributes_set[0] = 1; + String_Out(String_table[sa__], attributes_set, 1); + } + else if (String_table[so__]) + String_Out(String_table[so__], NULL, 0); +} + +void +attribute_off() +{ + if (String_table[me__]) + String_Out(String_table[me__], NULL, 0); + else if (String_table[sa__]) + { + attributes_set[0] = 0; + String_Out(String_table[sa__], attributes_set, 1); + } + else if (String_table[se__]) + String_Out(String_table[se__], NULL, 0); +} + +void +Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */ +char newc; +char newatt; +char *line; +char *attrib; +int offset; +{ + + + if ((newatt) && (!STAND)) + { + STAND = TRUE; + attribute_on(); + } + else if ((STAND) && (!newatt)) + { + STAND = FALSE; + attribute_off(); + } + + if ((newatt) && (STAND) && (Booleans[xs__])) + { + attribute_on(); + } + + if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1)))) + { + putchar(newc); + line[offset] = newc; + attrib[offset] = newatt; + } + Curr_x++; +} + +/* + | + | The two routines that follow, nc_setattrib(), nc_clearattrib(), are + | hacks that notify new_curse to handle characters that have the high + | bit set as the first of two bytes of a multi-byte string. + | + */ + +void +nc_setattrib(flag) +int flag; +{ + nc_attributes |= flag; +} + +void +nc_clearattrib(flag) +int flag; +{ + nc_attributes &= ~flag; +} + |