|
|
1.1 ! root 1: /* curses.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 16820 SW Tallac Way ! 6: * Beaverton, OR 97006 ! 7: * [email protected], or ...uunet!tektronix!psueea!jove!kirkenda ! 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: # include <termio.h> ! 23: # undef TIOCWINSZ /* we can't handle it correctly yet */ ! 24: # else ! 25: # include <sgtty.h> ! 26: # endif ! 27: #endif ! 28: ! 29: #if TOS ! 30: # include <osbind.h> ! 31: #endif ! 32: ! 33: #if OSK ! 34: # include <sgstat.h> ! 35: #endif ! 36: ! 37: #include <signal.h> ! 38: ! 39: extern char *getenv(); ! 40: static void starttcap(); ! 41: ! 42: /* variables, publicly available & used in the macros */ ! 43: short ospeed; /* speed of the tty, eg B2400 */ ! 44: #if OSK ! 45: char PC_; /* Pad char */ ! 46: char *BC; /* backspace character string */ ! 47: #else ! 48: char PC; /* Pad char */ ! 49: #endif ! 50: WINDOW *stdscr; /* pointer into kbuf[] */ ! 51: WINDOW kbuf[KBSIZ]; /* a very large output buffer */ ! 52: int LINES; /* :li#: number of rows */ ! 53: int COLS; /* :co#: number of columns */ ! 54: int AM; /* :am: boolean: auto margins? */ ! 55: int PT; /* :pt: boolean: physical tabs? */ ! 56: char *VB; /* :vb=: visible bell */ ! 57: char *UP; /* :up=: move cursor up */ ! 58: char *SO; /* :so=: standout start */ ! 59: char *SE; /* :se=: standout end */ ! 60: char *US = ""; /* :us=: underline start */ ! 61: char *UE = ""; /* :ue=: underline end */ ! 62: char *MD = ""; /* :md=: bold start */ ! 63: char *ME = ""; /* :me=: bold end */ ! 64: char *AS; /* :as=: alternate (italic) start */ ! 65: char *AE; /* :ae=: alternate (italic) end */ ! 66: char *CM; /* :cm=: cursor movement */ ! 67: char *CE; /* :ce=: clear to end of line */ ! 68: char *CD; /* :cd=: clear to end of screen */ ! 69: char *AL; /* :al=: add a line */ ! 70: char *DL; /* :dl=: delete a line */ ! 71: #if OSK ! 72: char *SR_; /* :sr=: scroll reverse */ ! 73: #else ! 74: char *SR; /* :sr=: scroll reverse */ ! 75: #endif ! 76: char *KS; /* :ks=: init string for cursor */ ! 77: char *KE; /* :ke=: restore string for cursor */ ! 78: char *KU; /* :ku=: key sequence sent by up arrow */ ! 79: char *KD; /* :kd=: key sequence sent by down arrow */ ! 80: char *KL; /* :kl=: key sequence sent by left arrow */ ! 81: char *KR; /* :kr=: key sequence sent by right arrow */ ! 82: char *HM; /* :HM=: key sequence sent by the <Home> key */ ! 83: char *EN; /* :EN=: key sequence sent by the <End> key */ ! 84: char *PU; /* :PU=: key sequence sent by the <PgUp> key */ ! 85: char *PD; /* :PD=: key sequence sent by the <PgDn> key */ ! 86: char *IM; /* :im=: insert mode start */ ! 87: char *IC = ""; /* :ic=: insert the following character */ ! 88: char *EI; /* :ei=: insert mode end */ ! 89: char *DC; /* :dc=: delete a character */ ! 90: char *TI; /* :ti=: terminal init */ /* GB */ ! 91: char *TE; /* :te=: terminal exit */ /* GB */ ! 92: #ifndef NO_CURSORSHAPE ! 93: char *CQ = (char *)0;/* :cQ=: normal cursor */ ! 94: char *CX = (char *)1;/* :cX=: cursor used for EX command/entry */ ! 95: char *CV = (char *)2;/* :cV=: cursor used for VI command mode */ ! 96: char *CI = (char *)3;/* :cI=: cursor used for VI input mode */ ! 97: char *CR = (char *)4;/* :cR=: cursor used for VI replace mode */ ! 98: #endif ! 99: char *aend = ""; /* end an attribute -- either UE or ME */ ! 100: char ERASEKEY; /* backspace key taken from ioctl structure */ ! 101: ! 102: #if ANY_UNIX ! 103: # if UNIXV ! 104: static struct termio oldtermio; /* original tty mode */ ! 105: static struct termio newtermio; /* cbreak/noecho tty mode */ ! 106: # else ! 107: static struct sgttyb oldsgttyb; /* original tty mode */ ! 108: static struct sgttyb newsgttyb; /* cbreak/nl/noecho tty mode */ ! 109: static int oldint; /* ^C or DEL, the "intr" character */ ! 110: # ifdef TIOCSLTC ! 111: static int oldswitch; /* ^Z, the "suspend" character */ ! 112: static int oldquote; /* ^V, the "quote next char" char */ ! 113: # endif ! 114: # endif ! 115: #endif ! 116: ! 117: #if OSK ! 118: static struct sgbuf oldsgttyb; /* orginal tty mode */ ! 119: static struct sgbuf newsgttyb; /* noecho tty mode */ ! 120: #endif ! 121: ! 122: static char *capbuf; /* capability string buffer */ ! 123: ! 124: ! 125: void initscr() ! 126: { ! 127: /* make sure TERM variable is set */ ! 128: #if MSDOS ! 129: char *val; ! 130: if (! (val = getenv("TERM")) ! 131: || !strcmp(val, "pcbios")) ! 132: #else ! 133: if (!getenv("TERM")) ! 134: #endif ! 135: { ! 136: #if ANY_UNIX ! 137: write(2, "Environment variable TERM must be set\n", (unsigned)38); ! 138: exit(1); ! 139: #endif ! 140: #if OSK ! 141: writeln(2, "Environment variable TERM must be set\n", (unsigned)38); ! 142: exit(1); ! 143: #endif ! 144: #if MSDOS || TOS ! 145: getsize(0); ! 146: #endif ! 147: } ! 148: else ! 149: { ! 150: #if MSDOS ! 151: *o_pcbios=0; ! 152: #endif ! 153: /* start termcap stuff */ ! 154: starttcap(); ! 155: } ! 156: ! 157: /* create stdscr and curscr */ ! 158: stdscr = kbuf; ! 159: ! 160: /* change the terminal mode to cbreak/noecho */ ! 161: #if ANY_UNIX ! 162: # if UNIXV ! 163: ioctl(2, TCGETA, &oldtermio); ! 164: # else ! 165: ioctl(2, TIOCGETP, &oldsgttyb); ! 166: # endif ! 167: #endif ! 168: ! 169: #if OSK ! 170: _gs_opt(0, &oldsgttyb); ! 171: #endif ! 172: resume_curses(TRUE); ! 173: } ! 174: ! 175: ! 176: void endwin() ! 177: { ! 178: /* change the terminal mode back the way it was */ ! 179: suspend_curses(); ! 180: } ! 181: ! 182: ! 183: static int curses_active = FALSE; ! 184: ! 185: void suspend_curses() ! 186: { ! 187: #if ANY_UNIX && !UNIXV ! 188: struct tchars tbuf; ! 189: # ifdef TIOCSLTC ! 190: struct ltchars ltbuf; ! 191: # endif ! 192: #endif ! 193: #ifndef NO_CURSORSHAPE ! 194: if (has_CQ) ! 195: { ! 196: do_CQ(); ! 197: } ! 198: #endif ! 199: if (has_TE) /* GB */ ! 200: { ! 201: do_TE(); ! 202: } ! 203: if (has_KE) ! 204: { ! 205: do_KE(); ! 206: } ! 207: refresh(); ! 208: ! 209: /* change the terminal mode back the way it was */ ! 210: #if ANY_UNIX ! 211: # if UNIXV ! 212: ioctl(2, TCSETAW, &oldtermio); ! 213: # else ! 214: ioctl(2, TIOCSETP, &oldsgttyb); ! 215: ! 216: ioctl(2, TIOCGETC, &tbuf); ! 217: tbuf.t_intrc = oldint; ! 218: ioctl(2, TIOCSETC, &tbuf); ! 219: ! 220: # ifdef TIOCSLTC ! 221: ioctl(2, TIOCGLTC, <buf); ! 222: ltbuf.t_suspc = oldswitch; ! 223: ltbuf.t_lnextc = oldquote; ! 224: ioctl(2, TIOCSLTC, <buf); ! 225: # endif ! 226: # endif ! 227: #endif ! 228: #if OSK ! 229: _ss_opt(0, &oldsgttyb); ! 230: #endif ! 231: curses_active = FALSE; ! 232: } ! 233: ! 234: void resume_curses(quietly) ! 235: int quietly; ! 236: { ! 237: if (!curses_active) ! 238: { ! 239: /* change the terminal mode to cbreak/noecho */ ! 240: #if ANY_UNIX ! 241: # if UNIXV ! 242: ospeed = (oldtermio.c_cflag & CBAUD); ! 243: ERASEKEY = oldtermio.c_cc[VERASE]; ! 244: newtermio = oldtermio; ! 245: newtermio.c_iflag &= (IXON|IXOFF|IXANY|ISTRIP|IGNBRK); ! 246: newtermio.c_oflag &= ~OPOST; ! 247: newtermio.c_lflag &= ISIG; ! 248: newtermio.c_cc[VINTR] = ctrl('C'); /* always use ^C for interrupts */ ! 249: newtermio.c_cc[VMIN] = 1; ! 250: newtermio.c_cc[VTIME] = 0; ! 251: # ifdef VSWTCH ! 252: newtermio.c_cc[VSWTCH] = 0; ! 253: # endif ! 254: ioctl(2, TCSETAW, &newtermio); ! 255: # else /* BSD or V7 or Coherent or Minix */ ! 256: struct tchars tbuf; ! 257: # ifdef TIOCSLTC ! 258: struct ltchars ltbuf; ! 259: # endif ! 260: ! 261: ospeed = oldsgttyb.sg_ospeed; ! 262: ERASEKEY = oldsgttyb.sg_erase; ! 263: newsgttyb = oldsgttyb; ! 264: newsgttyb.sg_flags |= CBREAK; ! 265: newsgttyb.sg_flags &= ~(CRMOD|ECHO|XTABS); ! 266: ioctl(2, TIOCSETP, &newsgttyb); ! 267: ! 268: ioctl(2, TIOCGETC, &tbuf); ! 269: oldint = tbuf.t_intrc; ! 270: tbuf.t_intrc = ctrl('C'); /* always use ^C for interrupts */ ! 271: ioctl(2, TIOCSETC, &tbuf); ! 272: ! 273: # ifdef TIOCSLTC ! 274: ioctl(2, TIOCGLTC, <buf); ! 275: oldswitch = ltbuf.t_suspc; ! 276: ltbuf.t_suspc = 0; /* disable ^Z for elvis */ ! 277: oldquote = ltbuf.t_lnextc; ! 278: ltbuf.t_lnextc = 0; /* disable ^V for elvis */ ! 279: ioctl(2, TIOCSLTC, <buf); ! 280: # endif ! 281: ! 282: # endif ! 283: #endif ! 284: #if OSK ! 285: newsgttyb = oldsgttyb; ! 286: newsgttyb.sg_echo = 0; ! 287: newsgttyb.sg_eofch = 0; ! 288: newsgttyb.sg_kbach = 0; ! 289: newsgttyb.sg_kbich = ctrl('C'); ! 290: _ss_opt(0, &newsgttyb); ! 291: ospeed = oldsgttyb.sg_baud; ! 292: ERASEKEY = oldsgttyb.sg_bspch; ! 293: #endif ! 294: ! 295: if (has_TI) /* GB */ ! 296: { ! 297: do_TI(); ! 298: } ! 299: if (has_KS) ! 300: { ! 301: do_KS(); ! 302: } ! 303: ! 304: curses_active = TRUE; ! 305: } ! 306: ! 307: /* If we're supposed to quit quietly, then we're done */ ! 308: if (quietly) ! 309: { ! 310: return; ! 311: } ! 312: ! 313: signal(SIGINT, SIG_IGN); ! 314: ! 315: move(LINES - 1, 0); ! 316: do_SO(); ! 317: qaddstr("[Press <RETURN> to continue]"); ! 318: do_SE(); ! 319: refresh(); ! 320: ttyread(kbuf, 20); /* in RAW mode, so <20 is very likely */ ! 321: if (kbuf[0] == ':') ! 322: { ! 323: mode = MODE_COLON; ! 324: addch('\n'); ! 325: refresh(); ! 326: } ! 327: else ! 328: { ! 329: mode = MODE_VI; ! 330: redraw(MARK_UNSET, FALSE); ! 331: } ! 332: exwrote = FALSE; ! 333: ! 334: #if TURBOC ! 335: signal(SIGINT, (void(*)()) trapint); ! 336: #else ! 337: signal(SIGINT, trapint); ! 338: #endif ! 339: } ! 340: ! 341: static void lacking(s) ! 342: char *s; ! 343: { ! 344: write(2, "This termcap entry lacks the :", (unsigned)30); ! 345: write(2, s, (unsigned)2); ! 346: write(2, "=: capability\n", (unsigned)14); ! 347: #if OSK ! 348: write(2, "\l", 1); ! 349: #endif ! 350: exit(1); ! 351: } ! 352: ! 353: static void starttcap() ! 354: { ! 355: char *str; ! 356: static char cbmem[800]; ! 357: #define MUSTHAVE(T,s) if (!(T = tgetstr(s, &capbuf))) lacking(s) ! 358: #define MAYHAVE(T,s) if (str = tgetstr(s, &capbuf)) T = str ! 359: #define PAIR(T,U,sT,sU) T=tgetstr(sT,&capbuf);U=tgetstr(sU,&capbuf);if (!T||!U)T=U="" ! 360: ! 361: /* allocate memory for capbuf */ ! 362: capbuf = cbmem; ! 363: ! 364: /* get the termcap entry */ ! 365: switch (tgetent(kbuf, getenv("TERM"))) ! 366: { ! 367: case -1: ! 368: write(2, "Can't read /etc/termcap\n", (unsigned)24); ! 369: #if OSK ! 370: write(2, "\l", 1); ! 371: #endif ! 372: exit(2); ! 373: ! 374: case 0: ! 375: write(2, "Unrecognized TERM type\n", (unsigned)23); ! 376: #if OSK ! 377: write(2, "\l", 1); ! 378: #endif ! 379: exit(3); ! 380: } ! 381: ! 382: /* get strings */ ! 383: MUSTHAVE(UP, "up"); ! 384: MAYHAVE(VB, "vb"); ! 385: MUSTHAVE(CM, "cm"); ! 386: PAIR(SO, SE, "so", "se"); ! 387: PAIR(TI, TE, "ti", "te"); ! 388: if (tgetnum("ug") <= 0) ! 389: { ! 390: PAIR(US, UE, "us", "ue"); ! 391: PAIR(MD, ME, "md", "me"); ! 392: ! 393: /* get italics, or have it default to underline */ ! 394: PAIR(AS, AE, "as", "ae"); ! 395: if (!*AS) ! 396: { ! 397: AS = US; ! 398: AE = UE; ! 399: } ! 400: } ! 401: MAYHAVE(AL, "al"); ! 402: MAYHAVE(DL, "dl"); ! 403: MUSTHAVE(CE, "ce"); ! 404: MAYHAVE(CD, "cd"); ! 405: #if OSK ! 406: MAYHAVE(SR_, "sr"); ! 407: #else ! 408: MAYHAVE(SR, "sr"); ! 409: #endif ! 410: PAIR(IM, EI, "im", "ei"); ! 411: MAYHAVE(IC, "ic"); ! 412: MAYHAVE(DC, "dc"); ! 413: ! 414: /* other termcap stuff */ ! 415: AM = tgetflag("am"); ! 416: PT = tgetflag("pt"); ! 417: getsize(0); ! 418: ! 419: /* Key sequences */ ! 420: PAIR(KS, KE, "ks", "ke"); ! 421: MAYHAVE(KU, "ku"); /* up */ ! 422: MAYHAVE(KD, "kd"); /* down */ ! 423: MAYHAVE(KL, "kl"); /* left */ ! 424: MAYHAVE(KR, "kr"); /* right */ ! 425: MAYHAVE(PU, "kP"); /* PgUp */ ! 426: MAYHAVE(PD, "kN"); /* PgDn */ ! 427: MAYHAVE(HM, "kh"); /* Home */ ! 428: MAYHAVE(EN, "kH"); /* End */ ! 429: #ifndef CRUNCH ! 430: if (!PU) MAYHAVE(PU, "K2"); /* "3x3 pad" names for PgUp, etc. */ ! 431: if (!PD) MAYHAVE(PD, "K5"); ! 432: if (!HM) MAYHAVE(HM, "K1"); ! 433: if (!EN) MAYHAVE(EN, "K4"); ! 434: ! 435: MAYHAVE(PU, "PU"); /* old XENIX names for PgUp, etc. */ ! 436: MAYHAVE(PD, "PD"); /* (overrides others, if used.) */ ! 437: MAYHAVE(HM, "HM"); ! 438: MAYHAVE(EN, "EN"); ! 439: #endif ! 440: ! 441: #ifndef NO_CURSORSHAPE ! 442: /* cursor shapes */ ! 443: CQ = tgetstr("cQ", &capbuf); ! 444: if (has_CQ) ! 445: { ! 446: CX = tgetstr("cX", &capbuf); ! 447: if (!CX) CX = CQ; ! 448: CV = tgetstr("cV", &capbuf); ! 449: if (!CV) CV = CQ; ! 450: CI = tgetstr("cI", &capbuf); ! 451: if (!CI) CI = CQ; ! 452: CR = tgetstr("cR", &capbuf); ! 453: if (!CR) CR = CQ; ! 454: } ! 455: # ifndef CRUNCH ! 456: else ! 457: { ! 458: PAIR(CQ, CV, "ve", "vs"); ! 459: CX = CI = CR = CQ; ! 460: } ! 461: # endif /* !CRUNCH */ ! 462: #endif /* !NO_CURSORSHAPE */ ! 463: ! 464: #undef MUSTHAVE ! 465: #undef MAYHAVE ! 466: #undef PAIR ! 467: } ! 468: ! 469: ! 470: /* This function gets the window size. It uses the TIOCGWINSZ ioctl call if ! 471: * your system has it, or tgetnum("li") and tgetnum("co") if it doesn't. ! 472: * This function is called once during initialization, and thereafter it is ! 473: * called whenever the SIGWINCH signal is sent to this process. ! 474: */ ! 475: int getsize(signo) ! 476: int signo; ! 477: { ! 478: int lines; ! 479: int cols; ! 480: #ifdef TIOCGWINSZ ! 481: struct winsize size; ! 482: #endif ! 483: ! 484: #ifdef SIGWINCH ! 485: /* reset the signal vector */ ! 486: signal(SIGWINCH, getsize); ! 487: #endif ! 488: ! 489: /* get the window size, one way or another. */ ! 490: lines = cols = 0; ! 491: #ifdef TIOCGWINSZ ! 492: if (ioctl(2, TIOCGWINSZ, &size) >= 0) ! 493: { ! 494: lines = size.ws_row; ! 495: cols = size.ws_col; ! 496: } ! 497: #endif ! 498: if ((lines == 0 || cols == 0) && signo == 0) ! 499: { ! 500: LINES = CHECKBIOS(v_rows(), tgetnum("li")); ! 501: COLS = CHECKBIOS(v_cols(), tgetnum("co")); ! 502: } ! 503: if (lines >= 2 && cols >= 30) ! 504: { ! 505: LINES = lines; ! 506: COLS = cols; ! 507: } ! 508: ! 509: /* Make sure we got values that we can live with */ ! 510: if (LINES < 2 || COLS < 30) ! 511: { ! 512: write(2, "Screen too small\n", (unsigned)17); ! 513: #if OSK ! 514: write(2, "\l", 1); ! 515: #endif ! 516: endwin(); ! 517: exit(2); ! 518: } ! 519: ! 520: /* !!! copy the new values into Elvis' options */ ! 521: { ! 522: extern char o_columns[], o_lines[]; ! 523: ! 524: *o_columns = COLS; ! 525: *o_lines = LINES; ! 526: } ! 527: ! 528: return 0; ! 529: } ! 530: ! 531: ! 532: /* This is a function version of addch() -- it is used by tputs() */ ! 533: int faddch(ch) ! 534: int ch; ! 535: { ! 536: addch(ch); ! 537: ! 538: return 0; ! 539: } ! 540: ! 541: /* These functions are equivelent to the macros of the same names... */ ! 542: ! 543: void qaddstr(str) ! 544: char *str; ! 545: { ! 546: REG char *s_, *d_; ! 547: ! 548: #if MSDOS ! 549: if (o_pcbios[0]) ! 550: { ! 551: while (*str) ! 552: qaddch(*str++); ! 553: return; ! 554: } ! 555: #endif ! 556: for (s_=(str), d_=stdscr; *d_++ = *s_++; ) ! 557: { ! 558: } ! 559: stdscr = d_ - 1; ! 560: } ! 561: ! 562: void attrset(a) ! 563: int a; ! 564: { ! 565: do_aend(); ! 566: if (a == A_BOLD) ! 567: { ! 568: do_MD(); ! 569: aend = ME; ! 570: } ! 571: else if (a == A_UNDERLINE) ! 572: { ! 573: do_US(); ! 574: aend = UE; ! 575: } ! 576: else if (a == A_ALTCHARSET) ! 577: { ! 578: do_AS(); ! 579: aend = AE; ! 580: } ! 581: else ! 582: { ! 583: aend = ""; ! 584: } ! 585: } ! 586: ! 587: ! 588: void insch(ch) ! 589: int ch; ! 590: { ! 591: if (has_IM) ! 592: do_IM(); ! 593: do_IC(); ! 594: qaddch(ch); ! 595: if (has_EI) ! 596: do_EI(); ! 597: } ! 598: ! 599: #if MSDOS ! 600: ! 601: static int alarmtime; ! 602: ! 603: /* raw read - #defined to read (0, ...) on non-MSDOS. ! 604: * With MSDOS, am maximum of 1 byte is read. ! 605: * If more bytes should be read, just change the loop. ! 606: * The following code uses the IBM-PC-System-Timer, so probably wont't work ! 607: * on non-compatibles. ! 608: */ ! 609: /*ARGSUSED*/ ! 610: ttyread(buf, len) ! 611: char *buf; ! 612: int len; ! 613: { ! 614: volatile char far *biostimer; ! 615: char oldtime; ! 616: int nticks = 0; ! 617: int pos = 0; ! 618: ! 619: biostimer = (char far *)0x0040006cl; ! 620: oldtime = *biostimer; ! 621: ! 622: while (!pos && (!alarmtime || nticks<alarmtime)) ! 623: { if (kbhit()) ! 624: if ((buf[pos++] = getch()) == 0) /* function key */ ! 625: buf[pos-1] = '#'; ! 626: if (oldtime != *biostimer) ! 627: { nticks++; ! 628: oldtime = *biostimer; ! 629: } ! 630: } ! 631: return pos; ! 632: } ! 633: ! 634: alarm(time) ! 635: int time; ! 636: { ! 637: alarmtime = 2 * time; /* ticks are 1/18 sec. */ ! 638: } ! 639: #endif ! 640: ! 641: #if TOS ! 642: ! 643: static int alarmtime; ! 644: static long timer; ! 645: ! 646: static gettime() ! 647: { ! 648: timer = *(long *)(0x4ba); ! 649: } ! 650: ! 651: /*ARGSUSED*/ ! 652: ttyread(buf, len) ! 653: char *buf; ! 654: int len; ! 655: { ! 656: int pos=0; ! 657: long l; ! 658: long endtime; ! 659: ! 660: Supexec(gettime); ! 661: endtime = timer+alarmtime; ! 662: ! 663: while (!pos && (!alarmtime || timer<endtime)) ! 664: { ! 665: if (Bconstat(2)) ! 666: { ! 667: l = Bconin(2); ! 668: if ((buf[pos++]=l) == '\0') ! 669: { ! 670: buf[pos-1]='#'; ! 671: buf[pos++]=l>>16; ! 672: } ! 673: } ! 674: Supexec(gettime); ! 675: } ! 676: return pos; ! 677: } ! 678: ! 679: alarm(time) ! 680: int time; ! 681: { ! 682: alarmtime = 50 * time; /* ticks are 1/200 sec. */ ! 683: } ! 684: ! 685: ttywrite(buf, len) ! 686: char *buf; ! 687: int len; ! 688: { ! 689: while (len--) ! 690: Bconout(2, *buf++); ! 691: } ! 692: #endif ! 693: ! 694: #if OSK ! 695: ttyread(buf, len) ! 696: char *buf; ! 697: int len; ! 698: { ! 699: REG int i; ! 700: if ((i = _gs_rdy(0)) > 0) ! 701: return read(0, buf, i < len ? i : len); ! 702: else ! 703: return read(0, buf, 1); ! 704: } ! 705: ! 706: alarm(time) ! 707: int time; ! 708: { ! 709: #define TIME(secs) ((secs << 8) | 0x80000000) ! 710: static int alrmid; ! 711: ! 712: if (time) ! 713: alrmid = alm_set(SIGQUIT, TIME(time)); ! 714: else ! 715: alm_delete(alrmid); ! 716: } ! 717: #endif /* OSK */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.