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