|
|
1.1 ! root 1: /* curses.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 14407 SW Teal Blvd. #C ! 6: * Beaverton, OR 97005 ! 7: * [email protected] ! 8: */ ! 9: ! 10: ! 11: /* This file contains the functions & variables needed for a tiny subset of ! 12: * curses. The principle advantage of this version of curses is its ! 13: * extreme speed. Disadvantages are potentially larger code, few supported ! 14: * functions, limited compatibility with full curses, and only stdscr. ! 15: */ ! 16: ! 17: #include "config.h" ! 18: #include "vi.h" ! 19: ! 20: #if ANY_UNIX ! 21: # if UNIXV ! 22: # ifdef TERMIOS ! 23: # include <termios.h> ! 24: # else ! 25: # include <termio.h> ! 26: # endif ! 27: # ifdef S5WINSIZE ! 28: # include <sys/stream.h> /* winsize struct defined in one of these? */ ! 29: # include <sys/ptem.h> ! 30: # else ! 31: # undef TIOCGWINSZ /* we can't handle it correctly yet */ ! 32: # endif ! 33: # else ! 34: # include <sgtty.h> ! 35: # endif ! 36: #endif ! 37: ! 38: #if TOS ! 39: # include <osbind.h> ! 40: #endif ! 41: ! 42: #if OSK ! 43: # include <sgstat.h> ! 44: #endif ! 45: ! 46: #if VMS ! 47: extern int VMS_read_raw; /* Set in initscr() */ ! 48: #endif ! 49: ! 50: ! 51: extern char *getenv(); ! 52: static void starttcap(); ! 53: ! 54: /* variables, publicly available & used in the macros */ ! 55: char *termtype; /* name of terminal entry */ ! 56: short ospeed; /* speed of the tty, eg B2400 */ ! 57: #if OSK ! 58: char PC_; /* Pad char */ ! 59: char *BC; /* backspace character string */ ! 60: #else ! 61: char PC; /* Pad char */ ! 62: #endif ! 63: WINDOW *stdscr; /* pointer into kbuf[] */ ! 64: WINDOW kbuf[KBSIZ]; /* a very large output buffer */ ! 65: int LINES; /* :li#: number of rows */ ! 66: int COLS; /* :co#: number of columns */ ! 67: int AM; /* :am: boolean: auto margins? */ ! 68: int PT; /* :pt: boolean: physical tabs? */ ! 69: char *VB; /* :vb=: visible bell */ ! 70: char *UP; /* :up=: move cursor up */ ! 71: char *SO = ""; /* :so=: standout start */ ! 72: char *SE = ""; /* :se=: standout end */ ! 73: char *US = ""; /* :us=: underline start */ ! 74: char *UE = ""; /* :ue=: underline end */ ! 75: char *MD = ""; /* :md=: bold start */ ! 76: char *ME = ""; /* :me=: bold end */ ! 77: char *AS = ""; /* :as=: alternate (italic) start */ ! 78: char *AE = ""; /* :ae=: alternate (italic) end */ ! 79: #ifndef NO_VISIBLE ! 80: char *MV; /* :mv=: "visible" selection start */ ! 81: #endif ! 82: char *CM; /* :cm=: cursor movement */ ! 83: char *CE; /* :ce=: clear to end of line */ ! 84: char *CD; /* :cd=: clear to end of screen */ ! 85: char *AL; /* :al=: add a line */ ! 86: char *DL; /* :dl=: delete a line */ ! 87: #if OSK ! 88: char *SR_; /* :sr=: scroll reverse */ ! 89: #else ! 90: char *SR; /* :sr=: scroll reverse */ ! 91: #endif ! 92: char *KU; /* :ku=: key sequence sent by up arrow */ ! 93: char *KD; /* :kd=: key sequence sent by down arrow */ ! 94: char *KL; /* :kl=: key sequence sent by left arrow */ ! 95: char *KR; /* :kr=: key sequence sent by right arrow */ ! 96: char *HM; /* :HM=: key sequence sent by the <Home> key */ ! 97: char *EN; /* :EN=: key sequence sent by the <End> key */ ! 98: char *PU; /* :PU=: key sequence sent by the <PgUp> key */ ! 99: char *PD; /* :PD=: key sequence sent by the <PgDn> key */ ! 100: char *KI; /* :kI=: key sequence sent by the <Insert> key */ ! 101: #ifndef NO_FKEY ! 102: char *FKEY[NFKEYS]; /* :k0=: ... :k9=: sequences sent by function keys */ ! 103: #endif ! 104: char *IM = ""; /* :im=: insert mode start */ ! 105: char *IC = ""; /* :ic=: insert the following character */ ! 106: char *EI = ""; /* :ei=: insert mode end */ ! 107: char *DC; /* :dc=: delete a character */ ! 108: char *TI = ""; /* :ti=: terminal init */ /* GB */ ! 109: char *TE = ""; /* :te=: terminal exit */ /* GB */ ! 110: #ifndef NO_CURSORSHAPE ! 111: #if 1 ! 112: char *CQ = (char *)0;/* :cQ=: normal cursor */ ! 113: char *CX = (char *)1;/* :cX=: cursor used for EX command/entry */ ! 114: char *CV = (char *)2;/* :cV=: cursor used for VI command mode */ ! 115: char *CI = (char *)3;/* :cI=: cursor used for VI input mode */ ! 116: char *CR = (char *)4;/* :cR=: cursor used for VI replace mode */ ! 117: #else ! 118: char *CQ = ""; /* :cQ=: normal cursor */ ! 119: char *CX = ""; /* :cX=: cursor used for EX command/entry */ ! 120: char *CV = ""; /* :cV=: cursor used for VI command mode */ ! 121: char *CI = ""; /* :cI=: cursor used for VI input mode */ ! 122: char *CR = ""; /* :cR=: cursor used for VI replace mode */ ! 123: #endif ! 124: #endif ! 125: char *aend = ""; /* end an attribute -- either UE or ME */ ! 126: char ERASEKEY; /* backspace key taken from ioctl structure */ ! 127: #ifndef NO_COLOR ! 128: char normalcolor[16]; ! 129: char SOcolor[16]; ! 130: char SEcolor[16]; ! 131: char UScolor[16]; ! 132: char UEcolor[16]; ! 133: char MDcolor[16]; ! 134: char MEcolor[16]; ! 135: char AScolor[16]; ! 136: char AEcolor[16]; ! 137: # ifndef NO_POPUP ! 138: char POPUPcolor[16]; ! 139: # endif ! 140: # ifndef NO_VISIBLE ! 141: char VISIBLEcolor[16]; ! 142: # endif ! 143: #endif ! 144: ! 145: #if ANY_UNIX ! 146: # if UNIXV ! 147: # ifdef TERMIOS ! 148: static struct termios oldtermio; /* original tty mode */ ! 149: static struct termios newtermio; /* cbreak/noecho tty mode */ ! 150: # else ! 151: static struct termio oldtermio; /* original tty mode */ ! 152: static struct termio newtermio; /* cbreak/noecho tty mode */ ! 153: # endif ! 154: # else ! 155: static struct sgttyb oldsgttyb; /* original tty mode */ ! 156: static struct sgttyb newsgttyb; /* cbreak/nl/noecho tty mode */ ! 157: static int oldint; /* ^C or DEL, the "intr" character */ ! 158: # ifdef TIOCSLTC ! 159: static int oldswitch; /* ^Z, the "suspend" character */ ! 160: static int olddswitch; /* ^Y, the "delayed suspend" char */ ! 161: static int oldquote; /* ^V, the "quote next char" char */ ! 162: # endif ! 163: # endif ! 164: #endif ! 165: ! 166: #if OSK ! 167: static struct sgbuf oldsgttyb; /* orginal tty mode */ ! 168: static struct sgbuf newsgttyb; /* noecho tty mode */ ! 169: #endif ! 170: ! 171: static char *capbuf; /* capability string buffer */ ! 172: ! 173: ! 174: /* Initialize the Curses package. */ ! 175: void initscr() ! 176: { ! 177: /* make sure TERM variable is set */ ! 178: termtype = getenv("TERM"); ! 179: ! 180: #if VMS ! 181: /* VMS getenv() handles TERM as a environment setting. Foreign ! 182: * terminal support can be implemented by setting the ELVIS_TERM ! 183: * logical or symbol to match a tinytcap entry. ! 184: */ ! 185: if (!strcmp(termtype,"unknown")) ! 186: termtype = getenv("ELVIS_TERM"); ! 187: #endif ! 188: #if MSDOS ! 189: /* For MS-DOS, if TERM is unset we can default to "pcbios", or ! 190: * maybe "rainbow". ! 191: */ ! 192: if (!termtype) ! 193: { ! 194: #ifdef RAINBOW ! 195: if (*(unsigned char far*)(0xffff000eL) == 6 /* Rainbow 100a */ ! 196: || *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */ ! 197: { ! 198: termtype = "rainbow"; ! 199: } ! 200: else ! 201: #endif ! 202: termtype = "pcbios"; ! 203: } ! 204: if (!strcmp(termtype, "pcbios")) ! 205: #else ! 206: if (!termtype) ! 207: #endif ! 208: { ! 209: #if ANY_UNIX ! 210: write(2, "Environment variable TERM must be set\n", (unsigned)38); ! 211: exit(2); ! 212: #endif ! 213: #if OSK ! 214: writeln(2, "Environment variable TERM must be set\n", (unsigned)38); ! 215: exit(2); ! 216: #endif ! 217: #if AMIGA ! 218: termtype = TERMTYPE; ! 219: starttcap(termtype); ! 220: #endif ! 221: #if MSDOS ! 222: starttcap("pcbios"); ! 223: #endif ! 224: #if TOS ! 225: termtype = "vt52"; ! 226: starttcap(termtype); ! 227: #endif ! 228: #if VMS ! 229: write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36); ! 230: exit(2); ! 231: #endif ! 232: } ! 233: else ! 234: { ! 235: #if MSDOS ! 236: *o_pcbios = 0; ! 237: #endif ! 238: /* start termcap stuff */ ! 239: starttcap(termtype); ! 240: } ! 241: ! 242: /* create stdscr and curscr */ ! 243: stdscr = kbuf; ! 244: ! 245: /* change the terminal mode to cbreak/noecho */ ! 246: #if ANY_UNIX ! 247: # if UNIXV ! 248: # ifdef TERMIOS ! 249: tcgetattr(2, &oldtermio); ! 250: # else ! 251: ioctl(2, TCGETA, &oldtermio); ! 252: # endif ! 253: # else ! 254: ioctl(2, TIOCGETP, &oldsgttyb); ! 255: # endif ! 256: #endif ! 257: ! 258: #if OSK ! 259: _gs_opt(0, &oldsgttyb); ! 260: #endif ! 261: ! 262: #if VMS ! 263: VMS_read_raw = 1; /* cbreak/noecho */ ! 264: vms_open_tty(); ! 265: #endif ! 266: resume_curses(TRUE); ! 267: } ! 268: ! 269: /* Shut down the Curses package. */ ! 270: void endwin() ! 271: { ! 272: /* change the terminal mode back the way it was */ ! 273: suspend_curses(); ! 274: #if AMIGA ! 275: amiclosewin(); ! 276: #endif ! 277: } ! 278: ! 279: ! 280: static int curses_active = FALSE; ! 281: ! 282: /* Send any required termination strings. Turn off "raw" mode. */ ! 283: void suspend_curses() ! 284: { ! 285: #if ANY_UNIX && !UNIXV ! 286: struct tchars tbuf; ! 287: # ifdef TIOCSLTC ! 288: struct ltchars ltbuf; ! 289: # endif ! 290: #endif ! 291: #ifndef NO_CURSORSHAPE ! 292: if (has_CQ) ! 293: { ! 294: do_CQ(); ! 295: } ! 296: #endif ! 297: if (has_TE) /* GB */ ! 298: { ! 299: do_TE(); ! 300: } ! 301: #ifndef NO_COLOR ! 302: quitcolor(); ! 303: #endif ! 304: refresh(); ! 305: ! 306: /* change the terminal mode back the way it was */ ! 307: #if ANY_UNIX ! 308: # if UNIXV ! 309: # if TERMIOS ! 310: tcsetattr(2, TCSADRAIN, &oldtermio); ! 311: # else ! 312: ioctl(2, TCSETAW, &oldtermio); ! 313: # endif ! 314: # else ! 315: ioctl(2, TIOCSETP, &oldsgttyb); ! 316: ! 317: ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf); ! 318: tbuf.t_intrc = oldint; ! 319: ioctl(2, TIOCSETC, (struct sgttyb *) &tbuf); ! 320: ! 321: # ifdef TIOCSLTC ! 322: ioctl(2, TIOCGLTC, <buf); ! 323: ltbuf.t_suspc = oldswitch; ! 324: ltbuf.t_dsuspc = olddswitch; ! 325: ltbuf.t_lnextc = oldquote; ! 326: ioctl(2, TIOCSLTC, <buf); ! 327: # endif ! 328: # endif ! 329: #endif ! 330: #if OSK ! 331: _ss_opt(0, &oldsgttyb); ! 332: #endif ! 333: #if AMIGA ! 334: ttyshutdown(); ! 335: #endif ! 336: #if MSDOS ! 337: raw_set_stdio(FALSE); ! 338: #endif ! 339: ! 340: #if VMS ! 341: VMS_read_raw = 0; ! 342: #endif ! 343: curses_active = FALSE; ! 344: } ! 345: ! 346: ! 347: /* put the terminal in RAW mode. If "quietly" is FALSE, then ask the user ! 348: * to hit a key, and wait for keystroke before returning. ! 349: */ ! 350: void resume_curses(quietly) ! 351: int quietly; ! 352: { ! 353: if (!curses_active) ! 354: { ! 355: /* change the terminal mode to cbreak/noecho */ ! 356: #if ANY_UNIX ! 357: # if UNIXV ! 358: ospeed = (oldtermio.c_cflag & CBAUD); ! 359: ERASEKEY = oldtermio.c_cc[VERASE]; ! 360: newtermio = oldtermio; ! 361: newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK); ! 362: newtermio.c_oflag &= ~OPOST; ! 363: newtermio.c_lflag &= ISIG; ! 364: newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */ ! 365: newtermio.c_cc[VMIN] = 1; ! 366: newtermio.c_cc[VTIME] = 0; ! 367: # ifdef VSWTCH ! 368: newtermio.c_cc[VSWTCH] = 0; ! 369: # endif ! 370: # ifdef VSUSP ! 371: newtermio.c_cc[VSUSP] = 0; ! 372: # endif ! 373: # ifdef TERMIOS ! 374: tcsetattr(2, TCSADRAIN, &newtermio); ! 375: # else ! 376: ioctl(2, TCSETAW, &newtermio); ! 377: # endif ! 378: # else /* BSD or V7 or Coherent or Minix */ ! 379: struct tchars tbuf; ! 380: # ifdef TIOCSLTC ! 381: struct ltchars ltbuf; ! 382: # endif ! 383: ! 384: ospeed = oldsgttyb.sg_ospeed; ! 385: ERASEKEY = oldsgttyb.sg_erase; ! 386: newsgttyb = oldsgttyb; ! 387: newsgttyb.sg_flags |= CBREAK; ! 388: newsgttyb.sg_flags &= ~(CRMOD|ECHO|XTABS); ! 389: ioctl(2, TIOCSETP, &newsgttyb); ! 390: ! 391: ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf); ! 392: oldint = tbuf.t_intrc; ! 393: tbuf.t_intrc = ctrl('C'); /* always use ^C for interrupts */ ! 394: ioctl(2, TIOCSETC, (struct sgttyb *) &tbuf); ! 395: ! 396: # ifdef TIOCSLTC ! 397: ioctl(2, TIOCGLTC, <buf); ! 398: oldswitch = ltbuf.t_suspc; ! 399: ltbuf.t_suspc = 0; /* disable ^Z for elvis */ ! 400: olddswitch = ltbuf.t_dsuspc; ! 401: ltbuf.t_dsuspc = 0; /* disable ^Y for elvis */ ! 402: oldquote = ltbuf.t_lnextc; ! 403: ltbuf.t_lnextc = 0; /* disable ^V for elvis */ ! 404: ioctl(2, TIOCSLTC, <buf); ! 405: # endif ! 406: ! 407: # endif ! 408: #endif ! 409: #if OSK ! 410: newsgttyb = oldsgttyb; ! 411: newsgttyb.sg_echo = 0; ! 412: newsgttyb.sg_eofch = 0; ! 413: newsgttyb.sg_kbach = 0; ! 414: newsgttyb.sg_kbich = ctrl('C'); ! 415: _ss_opt(0, &newsgttyb); ! 416: ospeed = oldsgttyb.sg_baud; ! 417: ERASEKEY = oldsgttyb.sg_bspch; ! 418: #endif ! 419: #if AMIGA ! 420: /* turn on window resize and RAW */ ! 421: ttysetup(); ! 422: #endif ! 423: #if MSDOS ! 424: raw_set_stdio(TRUE); ! 425: #endif ! 426: ! 427: #if VMS ! 428: VMS_read_raw = 1; ! 429: { int c; ! 430: read(0,&c,0); /* Flush the tty buffer. */ ! 431: } ! 432: ERASEKEY = '\177'; /* Accept <DEL> as <^H> for VMS */ ! 433: #endif ! 434: ! 435: curses_active = TRUE; ! 436: } ! 437: ! 438: /* If we're supposed to quit quietly, then we're done */ ! 439: if (quietly) ! 440: { ! 441: if (has_TI) /* GB */ ! 442: { ! 443: do_TI(); ! 444: } ! 445: ! 446: return; ! 447: } ! 448: ! 449: signal(SIGINT, SIG_IGN); ! 450: ! 451: move(LINES - 1, 0); ! 452: do_SO(); ! 453: #if VMS ! 454: qaddstr("\n[Press <RETURN> to continue]"); ! 455: #else ! 456: qaddstr("[Press <RETURN> to continue]"); ! 457: #endif ! 458: do_SE(); ! 459: refresh(); ! 460: ttyread(kbuf, 20, 0); /* in RAW mode, so <20 is very likely */ ! 461: if (has_TI) ! 462: { ! 463: do_TI(); ! 464: } ! 465: if (kbuf[0] == ':') ! 466: { ! 467: mode = MODE_COLON; ! 468: addch('\n'); ! 469: refresh(); ! 470: } ! 471: else ! 472: { ! 473: mode = MODE_VI; ! 474: redraw(MARK_UNSET, FALSE); ! 475: } ! 476: exwrote = FALSE; ! 477: ! 478: #if TURBOC || __GNUC__ ! 479: signal(SIGINT, (void(*)()) trapint); ! 480: #else ! 481: signal(SIGINT, trapint); ! 482: #endif ! 483: } ! 484: ! 485: /* This function fetches an optional string from termcap */ ! 486: static void mayhave(T, s) ! 487: char **T; /* where to store the returned pointer */ ! 488: char *s; /* name of the capability */ ! 489: { ! 490: char *val; ! 491: ! 492: val = tgetstr(s, &capbuf); ! 493: if (val) ! 494: { ! 495: *T = val; ! 496: } ! 497: } ! 498: ! 499: ! 500: /* This function fetches a required string from termcap */ ! 501: static void musthave(T, s) ! 502: char **T; /* where to store the returned pointer */ ! 503: char *s; /* name of the capability */ ! 504: { ! 505: mayhave(T, s); ! 506: if (!*T) ! 507: { ! 508: write(2, "This termcap entry lacks the :", (unsigned)30); ! 509: write(2, s, (unsigned)2); ! 510: write(2, "=: capability\n", (unsigned)14); ! 511: #if OSK ! 512: write(2, "\l", 1); ! 513: #endif ! 514: exit(2); ! 515: } ! 516: } ! 517: ! 518: ! 519: /* This function fetches a pair of strings from termcap. If one of them is ! 520: * missing, then the other one is ignored. ! 521: */ ! 522: static void pair(T, U, sT, sU) ! 523: char **T; /* where to store the first pointer */ ! 524: char **U; /* where to store the second pointer */ ! 525: char *sT; /* name of the first capability */ ! 526: char *sU; /* name of the second capability */ ! 527: { ! 528: mayhave(T, sT); ! 529: mayhave(U, sU); ! 530: if (!**T || !**U) ! 531: { ! 532: *T = *U = ""; ! 533: } ! 534: } ! 535: ! 536: ! 537: ! 538: /* Read everything from termcap */ ! 539: static void starttcap(term) ! 540: char *term; ! 541: { ! 542: static char cbmem[800]; ! 543: ! 544: /* allocate memory for capbuf */ ! 545: capbuf = cbmem; ! 546: ! 547: /* get the termcap entry */ ! 548: switch (tgetent(kbuf, term)) ! 549: { ! 550: case -1: ! 551: write(2, "Can't read /etc/termcap\n", (unsigned)24); ! 552: #if OSK ! 553: write(2, "\l", 1); ! 554: #endif ! 555: exit(2); ! 556: ! 557: case 0: ! 558: write(2, "Unrecognized TERM type\n", (unsigned)23); ! 559: #if OSK ! 560: write(2, "\l", 1); ! 561: #endif ! 562: exit(3); ! 563: } ! 564: ! 565: /* get strings */ ! 566: musthave(&UP, "up"); ! 567: mayhave(&VB, "vb"); ! 568: musthave(&CM, "cm"); ! 569: pair(&SO, &SE, "so", "se"); ! 570: mayhave(&TI, "ti"); ! 571: mayhave(&TE, "te"); ! 572: if (tgetnum("ug") <= 0) ! 573: { ! 574: pair(&US, &UE, "us", "ue"); ! 575: pair(&MD, &ME, "md", "me"); ! 576: ! 577: /* get italics, or have it default to underline */ ! 578: pair(&AS, &AE, "as", "ae"); ! 579: if (!*AS) ! 580: { ! 581: AS = US; ! 582: AE = UE; ! 583: } ! 584: } ! 585: #ifndef NO_VISIBLE ! 586: MV = SO; /* by default */ ! 587: mayhave(&MV, "mv"); ! 588: #endif ! 589: mayhave(&AL, "al"); ! 590: mayhave(&DL, "dl"); ! 591: musthave(&CE, "ce"); ! 592: mayhave(&CD, "cd"); ! 593: #if OSK ! 594: mayhave(&SR_, "sr"); ! 595: #else ! 596: mayhave(&SR, "sr"); ! 597: #endif ! 598: pair(&IM, &EI, "im", "ei"); ! 599: mayhave(&IC, "ic"); ! 600: mayhave(&DC, "dc"); ! 601: ! 602: /* other termcap stuff */ ! 603: AM = (tgetflag("am") && !tgetflag("xn")); ! 604: PT = tgetflag("pt"); ! 605: #if AMIGA ! 606: amiopenwin(termtype); /* Must run this before ttysetup(); */ ! 607: ttysetup(); /* Must run this before getsize(0); */ ! 608: #endif ! 609: getsize(0); ! 610: ! 611: /* Key sequences */ ! 612: mayhave(&KU, "ku"); /* up */ ! 613: mayhave(&KD, "kd"); /* down */ ! 614: mayhave(&KL, "kl"); /* left */ ! 615: mayhave(&KR, "kr"); /* right */ ! 616: #if COHERENT ! 617: if (KL && KL[0]=='\b' && !KL[1]) ! 618: { ! 619: /* never use '\b' as a left arrow! */ ! 620: KL = (char *)0; ! 621: } ! 622: #else ! 623: if (KR && KR[0]=='\b' && !KR[1]) ! 624: { ! 625: /* never use '\b' as a right arrow! */ ! 626: KR = (char *)0; ! 627: } ! 628: #endif ! 629: mayhave(&PU, "kP"); /* PgUp */ ! 630: mayhave(&PD, "kN"); /* PgDn */ ! 631: mayhave(&HM, "kh"); /* Home */ ! 632: mayhave(&EN, "kH"); /* End */ ! 633: mayhave(&KI, "kI"); /* Insert */ ! 634: #ifndef CRUNCH ! 635: if (!PU) mayhave(&PU, "K2"); /* "3x3 pad" names for PgUp, etc. */ ! 636: if (!PD) mayhave(&PD, "K5"); ! 637: if (!HM) mayhave(&HM, "K1"); ! 638: if (!EN) mayhave(&EN, "K4"); ! 639: ! 640: mayhave(&PU, "PU"); /* old XENIX names for PgUp, etc. */ ! 641: mayhave(&PD, "PD"); /* (overrides others, if used.) */ ! 642: mayhave(&HM, "HM"); ! 643: mayhave(&EN, "EN"); ! 644: #endif ! 645: #ifndef NO_FKEY ! 646: mayhave(&FKEY[0], "k0"); /* function key codes */ ! 647: mayhave(&FKEY[1], "k1"); ! 648: mayhave(&FKEY[2], "k2"); ! 649: mayhave(&FKEY[3], "k3"); ! 650: mayhave(&FKEY[4], "k4"); ! 651: mayhave(&FKEY[5], "k5"); ! 652: mayhave(&FKEY[6], "k6"); ! 653: mayhave(&FKEY[7], "k7"); ! 654: mayhave(&FKEY[8], "k8"); ! 655: mayhave(&FKEY[9], "k9"); ! 656: # ifndef NO_SHIFT_FKEY ! 657: mayhave(&FKEY[10], "s0"); /* shift function key codes */ ! 658: mayhave(&FKEY[11], "s1"); ! 659: mayhave(&FKEY[12], "s2"); ! 660: mayhave(&FKEY[13], "s3"); ! 661: mayhave(&FKEY[14], "s4"); ! 662: mayhave(&FKEY[15], "s5"); ! 663: mayhave(&FKEY[16], "s6"); ! 664: mayhave(&FKEY[17], "s7"); ! 665: mayhave(&FKEY[18], "s8"); ! 666: mayhave(&FKEY[19], "s9"); ! 667: # ifndef NO_CTRL_FKEY ! 668: mayhave(&FKEY[20], "c0"); /* control function key codes */ ! 669: mayhave(&FKEY[21], "c1"); ! 670: mayhave(&FKEY[22], "c2"); ! 671: mayhave(&FKEY[23], "c3"); ! 672: mayhave(&FKEY[24], "c4"); ! 673: mayhave(&FKEY[25], "c5"); ! 674: mayhave(&FKEY[26], "c6"); ! 675: mayhave(&FKEY[27], "c7"); ! 676: mayhave(&FKEY[28], "c8"); ! 677: mayhave(&FKEY[29], "c9"); ! 678: # ifndef NO_ALT_FKEY ! 679: mayhave(&FKEY[30], "a0"); /* alt function key codes */ ! 680: mayhave(&FKEY[31], "a1"); ! 681: mayhave(&FKEY[32], "a2"); ! 682: mayhave(&FKEY[33], "a3"); ! 683: mayhave(&FKEY[34], "a4"); ! 684: mayhave(&FKEY[35], "a5"); ! 685: mayhave(&FKEY[36], "a6"); ! 686: mayhave(&FKEY[37], "a7"); ! 687: mayhave(&FKEY[38], "a8"); ! 688: mayhave(&FKEY[39], "a9"); ! 689: # endif ! 690: # endif ! 691: # endif ! 692: #endif ! 693: ! 694: #ifndef NO_CURSORSHAPE ! 695: /* cursor shapes */ ! 696: CQ = tgetstr("cQ", &capbuf); ! 697: if (has_CQ) ! 698: { ! 699: CX = tgetstr("cX", &capbuf); ! 700: if (!CX) CX = CQ; ! 701: CV = tgetstr("cV", &capbuf); ! 702: if (!CV) CV = CQ; ! 703: CI = tgetstr("cI", &capbuf); ! 704: if (!CI) CI = CQ; ! 705: CR = tgetstr("cR", &capbuf); ! 706: if (!CR) CR = CQ; ! 707: } ! 708: # ifndef CRUNCH ! 709: else ! 710: { ! 711: CQ = CV = ""; ! 712: pair(&CQ, &CV, "ve", "vs"); ! 713: CX = CI = CR = CQ; ! 714: } ! 715: # endif /* !CRUNCH */ ! 716: #endif /* !NO_CURSORSHAPE */ ! 717: ! 718: #ifndef NO_COLOR ! 719: strcpy(SOcolor, SO); ! 720: strcpy(SEcolor, SE); ! 721: strcpy(AScolor, AS); ! 722: strcpy(AEcolor, AE); ! 723: strcpy(MDcolor, MD); ! 724: strcpy(MEcolor, ME); ! 725: strcpy(UScolor, US); ! 726: strcpy(UEcolor, UE); ! 727: # ifndef NO_POPUP ! 728: strcpy(POPUPcolor, SO); ! 729: # endif ! 730: # ifndef NO_VISIBLE ! 731: strcpy(VISIBLEcolor, MV); ! 732: # endif ! 733: #endif ! 734: ! 735: } ! 736: ! 737: ! 738: /* This function gets the window size. It uses the TIOCGWINSZ ioctl call if ! 739: * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't. ! 740: * This function is called once during initialization, and thereafter it is ! 741: * called whenever the SIGWINCH signal is sent to this process. ! 742: */ ! 743: int getsize(signo) ! 744: int signo; ! 745: { ! 746: int lines; ! 747: int cols; ! 748: #ifdef TIOCGWINSZ ! 749: struct winsize size; ! 750: #endif ! 751: ! 752: #ifdef SIGWINCH ! 753: /* reset the signal vector */ ! 754: signal(SIGWINCH, getsize); ! 755: #endif ! 756: ! 757: /* get the window size, one way or another. */ ! 758: lines = cols = 0; ! 759: #ifdef TIOCGWINSZ ! 760: if (ioctl(2, TIOCGWINSZ, &size) >= 0) ! 761: { ! 762: lines = size.ws_row; ! 763: cols = size.ws_col; ! 764: } ! 765: #endif ! 766: #if AMIGA ! 767: /* Amiga gets window size by asking the console.device */ ! 768: if (!strcmp(TERMTYPE, termtype)) ! 769: { ! 770: auto long len; ! 771: auto char buf[30]; ! 772: ! 773: Write(Output(), "\2330 q", 4); /* Ask the console.device */ ! 774: len = Read(Input(), buf, 29); ! 775: buf[len] = '\000'; ! 776: sscanf(&buf[5], "%d;%d", &lines, &cols); ! 777: } ! 778: #endif ! 779: if ((lines == 0 || cols == 0) && signo == 0) ! 780: { ! 781: #if COHERENT ! 782: char * temp; ! 783: ! 784: temp = getenv("COLUMNS"); ! 785: if (temp) ! 786: COLS = atoi(temp); ! 787: else ! 788: COLS = tgetnum("co"); ! 789: ! 790: temp = getenv("LINES"); ! 791: if (temp) ! 792: LINES = atoi(temp); ! 793: else ! 794: LINES = tgetnum("li"); ! 795: #else ! 796: LINES = tgetnum("li"); ! 797: COLS = tgetnum("co"); ! 798: #endif ! 799: } ! 800: #if MSDOS ! 801: # ifdef RAINBOW ! 802: if (!strcmp(termtype, "rainbow")) ! 803: { ! 804: /* Determine whether Rainbow is in 80-column or 132-column mode */ ! 805: cols = *(unsigned char far *)0xee000f57L; ! 806: } ! 807: else ! 808: # endif ! 809: { ! 810: lines = v_rows(); ! 811: cols = v_cols(); ! 812: } ! 813: #endif ! 814: if (lines >= 2 && cols >= 30) ! 815: { ! 816: LINES = lines; ! 817: COLS = cols; ! 818: } ! 819: ! 820: /* Make sure we got values that we can live with */ ! 821: if (LINES < 2 || COLS < 30) ! 822: { ! 823: write(2, "Screen too small\n", (unsigned)17); ! 824: #if OSK ! 825: write(2, "\l", 1); ! 826: #endif ! 827: endwin(); ! 828: exit(2); ! 829: } ! 830: ! 831: #if AMIGA ! 832: if (*o_lines != LINES || *o_columns != COLS) ! 833: { ! 834: *o_lines = LINES; ! 835: *o_columns = COLS; ! 836: } ! 837: #endif ! 838: ! 839: return 0; ! 840: } ! 841: ! 842: ! 843: /* This is a function version of addch() -- it is used by tputs() */ ! 844: int faddch(ch) ! 845: int ch; ! 846: { ! 847: #if 0 ! 848: if (stdscr) ! 849: addch(ch); ! 850: else ! 851: msg("OOPS! tried to access null stdscr"); ! 852: #else ! 853: addch(ch); ! 854: #endif ! 855: ! 856: return 0; ! 857: } ! 858: ! 859: /* This function quickly adds a string to the output queue. It does *NOT* ! 860: * convert \n into <CR><LF>. ! 861: */ ! 862: void qaddstr(str) ! 863: char *str; ! 864: { ! 865: REG char *s_, *d_; ! 866: ! 867: #if MSDOS ! 868: if (o_pcbios[0]) ! 869: { ! 870: while (*str) ! 871: qaddch(*str++); ! 872: return; ! 873: } ! 874: #endif ! 875: for (s_=(str), d_=stdscr; *d_++ = *s_++; ) ! 876: { ! 877: } ! 878: stdscr = d_ - 1; ! 879: } ! 880: ! 881: /* Output the ESC sequence needed to go into any video mode, if supported */ ! 882: void attrset(a) ! 883: int a; ! 884: { ! 885: do_aend(); ! 886: if (a == A_BOLD) ! 887: { ! 888: do_MD(); ! 889: aend = ME; ! 890: } ! 891: else if (a == A_UNDERLINE) ! 892: { ! 893: do_US(); ! 894: aend = UE; ! 895: } ! 896: else if (a == A_ALTCHARSET) ! 897: { ! 898: do_AS(); ! 899: aend = AE; ! 900: } ! 901: else ! 902: { ! 903: aend = ""; ! 904: } ! 905: } ! 906: ! 907: ! 908: /* Insert a single character into the display */ ! 909: void insch(ch) ! 910: int ch; ! 911: { ! 912: if (has_IM) ! 913: do_IM(); ! 914: do_IC(); ! 915: qaddch(ch); ! 916: if (has_EI) ! 917: do_EI(); ! 918: } ! 919: ! 920: void wrefresh() ! 921: { ! 922: if (stdscr != kbuf) ! 923: { ! 924: VOIDBIOS(;,ttywrite(kbuf, (unsigned)(stdscr - kbuf))); ! 925: stdscr = kbuf; ! 926: } ! 927: } ! 928: ! 929: void wqrefresh() ! 930: { ! 931: if (stdscr - kbuf > 2000) ! 932: { ! 933: VOIDBIOS(stdscr = kbuf, ! 934: { ! 935: ttywrite(kbuf, (unsigned)(stdscr - kbuf)); ! 936: stdscr = kbuf; ! 937: }); ! 938: } ! 939: } ! 940: ! 941: #ifndef NO_COLOR ! 942: /* This function is called during termination. It resets color modes */ ! 943: int ansiquit() ! 944: { ! 945: /* if ANSI color terminal, then reset the colors */ ! 946: if (!strcmp(UP, "\033[A")) ! 947: { ! 948: tputs("\033[37;40m\033[m", 1, faddch); ! 949: clrtoeol(); ! 950: return 1; ! 951: } ! 952: return 0; ! 953: } ! 954: ! 955: /* This sets the color strings that work for ANSI terminals. If the TERMCAP ! 956: * doesn't look like an ANSI terminal, then it returns FALSE. If the colors ! 957: * aren't understood, it also returns FALSE. If all goes well, it returns TRUE ! 958: */ ! 959: int ansicolor(cmode, attrbyte) ! 960: int cmode; /* mode to set, e.g. A_NORMAL */ ! 961: int attrbyte; /* IBM PC attribute byte */ ! 962: { ! 963: char temp[16]; /* hold the new mode string */ ! 964: ! 965: /* if not ANSI-ish, then fail */ ! 966: if (strcmp(UP, "\033[A") && strcmp(UP, "\033OA")) ! 967: { ! 968: #if COHERENT ! 969: return 1; ! 970: #else ! 971: msg("Don't know how to set colors for this terminal"); ! 972: return 0; ! 973: #endif ! 974: } ! 975: ! 976: /* construct the color string */ ! 977: sprintf(temp, "\033[m\033[3%c;4%c%s%sm", ! 978: "04261537"[attrbyte & 0x07], ! 979: "04261537"[(attrbyte >> 4) & 0x07], ! 980: (attrbyte & 0x08) ? ";1" : "", ! 981: (attrbyte & 0x80) ? ";5" : ""); ! 982: ! 983: /* stick it in the right place */ ! 984: switch (cmode) ! 985: { ! 986: case A_NORMAL: ! 987: if (!strcmp(MEcolor, normalcolor)) ! 988: strcpy(MEcolor, temp); ! 989: if (!strcmp(UEcolor, normalcolor)) ! 990: strcpy(UEcolor, temp); ! 991: if (!strcmp(AEcolor, normalcolor)) ! 992: strcpy(AEcolor, temp); ! 993: if (!strcmp(SEcolor, normalcolor)) ! 994: strcpy(SEcolor, temp); ! 995: ! 996: strcpy(normalcolor, temp); ! 997: tputs(normalcolor, 1, faddch); ! 998: break; ! 999: ! 1000: case A_BOLD: ! 1001: strcpy(MDcolor, temp); ! 1002: strcpy(MEcolor, normalcolor); ! 1003: break; ! 1004: ! 1005: case A_UNDERLINE: ! 1006: strcpy(UScolor, temp); ! 1007: strcpy(UEcolor, normalcolor); ! 1008: break; ! 1009: ! 1010: case A_ALTCHARSET: ! 1011: strcpy(AScolor, temp); ! 1012: strcpy(AEcolor, normalcolor); ! 1013: break; ! 1014: ! 1015: case A_STANDOUT: ! 1016: strcpy(SOcolor, temp); ! 1017: strcpy(SEcolor, normalcolor); ! 1018: break; ! 1019: ! 1020: #ifndef NO_POPUP ! 1021: case A_POPUP: ! 1022: strcpy(POPUPcolor, temp); ! 1023: break; ! 1024: #endif ! 1025: ! 1026: #ifndef NO_VISIBLE ! 1027: case A_VISIBLE: ! 1028: strcpy(VISIBLEcolor, temp); ! 1029: break; ! 1030: #endif ! 1031: } ! 1032: ! 1033: return 1; ! 1034: } ! 1035: ! 1036: ! 1037: /* This function outputs the ESC sequence needed to switch the screen back ! 1038: * to "normal" mode. On color terminals which haven't had their color set ! 1039: * yet, this is one of the termcap strings; for color terminals that really ! 1040: * have had colors defined, we just the "normal color" escape sequence. ! 1041: */ ! 1042: int ! 1043: endcolor() ! 1044: { ! 1045: if (aend == ME) ! 1046: tputs(MEcolor, 1, faddch); ! 1047: else if (aend == UE) ! 1048: tputs(UEcolor, 1, faddch); ! 1049: else if (aend == AE) ! 1050: tputs(AEcolor, 1, faddch); ! 1051: else if (aend == SE) ! 1052: tputs(SEcolor, 1, faddch); ! 1053: aend = ""; ! 1054: return 0; ! 1055: } ! 1056: ! 1057: ! 1058: #endif /* !NO_COLOR */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.