This allows me to merge our custom changes to ee(1) back on top of original sources, with correct mergeinfo.
3814 lines
86 KiB
C
3814 lines
86 KiB
C
/*
|
|
| 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;
|
|
}
|
|
|