|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Timothy C. Stoehr. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)curses.c 5.3 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: /* ! 28: * curses.c ! 29: * ! 30: * This source herein may be modified and/or distributed by anybody who ! 31: * so desires, with the following restrictions: ! 32: * 1.) No portion of this notice shall be removed. ! 33: * 2.) Credit shall not be taken for the creation of this source. ! 34: * 3.) This code is not to be traded, sold, or used for personal ! 35: * gain or profit. ! 36: * ! 37: */ ! 38: ! 39: #ifdef CURSES ! 40: ! 41: /* The following is a curses emulation package suitable for the rogue program ! 42: * in which it is included. No other suitability is claimed or suspected. ! 43: * Only those routines currently needed by this rogue program are included. ! 44: * This is being provided for those systems that don't have a suitable ! 45: * curses package and want to run this rogue program. ! 46: * ! 47: * Compile the entire program with -DCURSES to incorporate this package. ! 48: * ! 49: * The following is NOT supported: ! 50: * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string. ! 51: * Terminals in which the cursor motion addresses the row differently from ! 52: * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y" ! 53: * Termcap database stored in the TERMCAP environ variable as returned ! 54: * from md_getenv(). Only the termcap file name can be stored there. ! 55: * See the comments for md_getenv() in machdep.c. ! 56: * Terminals without non-destructive backspace. Backspace (^H) is used ! 57: * for cursor motion regardless of any termcap entries. ! 58: * The ":tc=" termcap entry is ignored. ! 59: * ! 60: * Suggestions: ! 61: * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or ! 62: * ":do=\n" This will help cursor motion optimization. If line-feed ! 63: * won't work, then a short escape sequence will do. ! 64: */ ! 65: ! 66: #include <stdio.h> ! 67: #include "rogue.h" ! 68: ! 69: boolean tc_tname(); ! 70: ! 71: #define BS 010 ! 72: #define LF 012 ! 73: #define CR 015 ! 74: #define ESC '\033' ! 75: #define TAB '\011' ! 76: ! 77: #define ST_MASK 0x80 ! 78: #define BUFLEN 256 ! 79: ! 80: char terminal[DROWS][DCOLS]; ! 81: char buffer[DROWS][DCOLS]; ! 82: char *tc_file; ! 83: ! 84: char cm_esc[16]; ! 85: char cm_sep[16]; ! 86: char cm_end[16]; ! 87: boolean cm_reverse = 0; ! 88: boolean cm_two = 0; ! 89: boolean cm_three = 0; ! 90: boolean cm_char = 0; ! 91: short cm_inc = 0; ! 92: ! 93: boolean screen_dirty; ! 94: boolean lines_dirty[DROWS]; ! 95: boolean buf_stand_out = 0; ! 96: boolean term_stand_out = 0; ! 97: ! 98: int LINES = DROWS; ! 99: int COLS = DCOLS; ! 100: WINDOW scr_buf; ! 101: WINDOW *curscr = &scr_buf; ! 102: ! 103: char *CL = (char *) 0; ! 104: char *CM = (char *) 0; ! 105: char *UC = (char *) 0; /* UP */ ! 106: char *DO = (char *) 0; ! 107: char *VS = ""; ! 108: char *VE = ""; ! 109: char *TI = ""; ! 110: char *TE = ""; ! 111: char *SO = ""; ! 112: char *SE = ""; ! 113: ! 114: short cur_row; ! 115: short cur_col; ! 116: ! 117: initscr() ! 118: { ! 119: clear(); ! 120: get_term_info(); ! 121: printf("%s%s", TI, VS); ! 122: } ! 123: ! 124: endwin() ! 125: { ! 126: printf("%s%s", TE, VE); ! 127: md_cbreak_no_echo_nonl(0); ! 128: } ! 129: ! 130: move(row, col) ! 131: short row, col; ! 132: { ! 133: curscr->_cury = row; ! 134: curscr->_curx = col; ! 135: screen_dirty = 1; ! 136: } ! 137: ! 138: mvaddstr(row, col, str) ! 139: short row, col; ! 140: char *str; ! 141: { ! 142: move(row, col); ! 143: addstr(str); ! 144: } ! 145: ! 146: addstr(str) ! 147: char *str; ! 148: { ! 149: while (*str) { ! 150: addch((int) *str++); ! 151: } ! 152: } ! 153: ! 154: addch(ch) ! 155: register int ch; ! 156: { ! 157: short row, col; ! 158: ! 159: row = curscr->_cury; ! 160: col = curscr->_curx++; ! 161: ! 162: if (buf_stand_out) { ! 163: ch |= ST_MASK; ! 164: } ! 165: buffer[row][col] = (char) ch; ! 166: lines_dirty[row] = 1; ! 167: screen_dirty = 1; ! 168: } ! 169: ! 170: mvaddch(row, col, ch) ! 171: short row, col; ! 172: int ch; ! 173: { ! 174: move(row, col); ! 175: addch(ch); ! 176: } ! 177: ! 178: refresh() ! 179: { ! 180: register i, j, line; ! 181: short old_row, old_col, first_row; ! 182: ! 183: if (screen_dirty) { ! 184: ! 185: old_row = curscr->_cury; ! 186: old_col = curscr->_curx; ! 187: first_row = cur_row; ! 188: ! 189: for (i = 0; i < DROWS; i++) { ! 190: line = (first_row + i) % DROWS; ! 191: if (lines_dirty[line]) { ! 192: for (j = 0; j < DCOLS; j++) { ! 193: if (buffer[line][j] != terminal[line][j]) { ! 194: put_char_at(line, j, buffer[line][j]); ! 195: } ! 196: } ! 197: lines_dirty[line] = 0; ! 198: } ! 199: } ! 200: put_cursor(old_row, old_col); ! 201: screen_dirty = 0; ! 202: fflush(stdout); ! 203: } ! 204: } ! 205: ! 206: wrefresh(scr) ! 207: WINDOW *scr; ! 208: { ! 209: short i, col; ! 210: ! 211: printf("%s", CL); ! 212: cur_row = cur_col = 0; ! 213: ! 214: for (i = 0; i < DROWS; i++) { ! 215: col = 0; ! 216: while (col < DCOLS) { ! 217: while ((col < DCOLS) && (buffer[i][col] == ' ')) { ! 218: col++; ! 219: } ! 220: if (col < DCOLS) { ! 221: put_cursor(i, col); ! 222: } ! 223: while ((col < DCOLS) && (buffer[i][col] != ' ')) { ! 224: put_st_char((int) buffer[i][col]); ! 225: cur_col++; ! 226: col++; ! 227: } ! 228: } ! 229: } ! 230: put_cursor(curscr->_cury, curscr->_curx); ! 231: fflush(stdout); ! 232: scr = scr; /* make lint happy */ ! 233: } ! 234: ! 235: mvinch(row, col) ! 236: short row, col; ! 237: { ! 238: move(row, col); ! 239: return((int) buffer[row][col]); ! 240: } ! 241: ! 242: clear() ! 243: { ! 244: printf("%s", CL); ! 245: fflush(stdout); ! 246: cur_row = cur_col = 0; ! 247: move(0, 0); ! 248: clear_buffers(); ! 249: } ! 250: ! 251: clrtoeol() ! 252: { ! 253: short row, col; ! 254: ! 255: row = curscr->_cury; ! 256: ! 257: for (col = curscr->_curx; col < DCOLS; col++) { ! 258: buffer[row][col] = ' '; ! 259: } ! 260: lines_dirty[row] = 1; ! 261: } ! 262: ! 263: standout() ! 264: { ! 265: buf_stand_out = 1; ! 266: } ! 267: ! 268: standend() ! 269: { ! 270: buf_stand_out = 0; ! 271: } ! 272: ! 273: crmode() ! 274: { ! 275: md_cbreak_no_echo_nonl(1); ! 276: } ! 277: ! 278: noecho() ! 279: { ! 280: /* crmode() takes care of this */ ! 281: } ! 282: ! 283: nonl() ! 284: { ! 285: /* crmode() takes care of this */ ! 286: } ! 287: ! 288: clear_buffers() ! 289: { ! 290: register i, j; ! 291: ! 292: screen_dirty = 0; ! 293: ! 294: for (i = 0; i < DROWS; i++) { ! 295: lines_dirty[i] = 0; ! 296: for (j = 0; j < DCOLS; j++) { ! 297: terminal[i][j] = ' '; ! 298: buffer[i][j] = ' '; ! 299: } ! 300: } ! 301: } ! 302: ! 303: put_char_at(row, col, ch) ! 304: register row, col, ch; ! 305: { ! 306: put_cursor(row, col); ! 307: put_st_char(ch); ! 308: terminal[row][col] = (char) ch; ! 309: cur_col++; ! 310: } ! 311: ! 312: put_cursor(row, col) ! 313: register row, col; ! 314: { ! 315: register i, rdif, cdif; ! 316: short ch, t; ! 317: ! 318: rdif = (row > cur_row) ? row - cur_row : cur_row - row; ! 319: cdif = (col > cur_col) ? col - cur_col : cur_col - col; ! 320: ! 321: if (((row > cur_row) && DO) || ((cur_row > row) && UC)) { ! 322: if ((rdif < 4) && (cdif < 4)) { ! 323: for (i = 0; i < rdif; i++) { ! 324: printf("%s", ((row < cur_row) ? UC : DO)); ! 325: } ! 326: cur_row = row; ! 327: if (col == cur_col) { ! 328: return; ! 329: } ! 330: } ! 331: } ! 332: if (row == cur_row) { ! 333: if (cdif <= 6) { ! 334: for (i = 0; i < cdif; i++) { ! 335: ch = (col < cur_col) ? BS : ! 336: terminal[row][cur_col + i]; ! 337: put_st_char((int) ch); ! 338: } ! 339: cur_row = row; ! 340: cur_col = col; ! 341: return; ! 342: } ! 343: } ! 344: cur_row = row; ! 345: cur_col = col; ! 346: ! 347: row += cm_inc; ! 348: col += cm_inc; ! 349: ! 350: if (cm_reverse) { ! 351: t = row; ! 352: row = col; ! 353: col = t; ! 354: } ! 355: if (cm_two) { ! 356: printf("%s%02d%s%02d%s", cm_esc, row, cm_sep, col, cm_end); ! 357: } else if (cm_three) { ! 358: printf("%s%03d%s%03d%s", cm_esc, row, cm_sep, col, cm_end); ! 359: } else if (cm_char) { ! 360: printf("%s%c%s%c%s", cm_esc, row, cm_sep, col, cm_end); ! 361: } else { ! 362: printf("%s%d%s%d%s", cm_esc, row, cm_sep, col, cm_end); ! 363: } ! 364: } ! 365: ! 366: put_st_char(ch) ! 367: register ch; ! 368: { ! 369: if ((ch & ST_MASK) && (!term_stand_out)) { ! 370: ch &= ~ST_MASK; ! 371: printf("%s%c", SO, ch); ! 372: term_stand_out = 1; ! 373: } else if ((!(ch & ST_MASK)) && term_stand_out) { ! 374: printf("%s%c", SE, ch); ! 375: term_stand_out = 0; ! 376: } else { ! 377: ch &= ~ST_MASK; ! 378: putchar(ch); ! 379: } ! 380: } ! 381: ! 382: get_term_info() ! 383: { ! 384: FILE *fp; ! 385: char *term, *tcf; ! 386: char buf[BUFLEN]; ! 387: ! 388: if (tcf = md_getenv("TERMCAP")) { ! 389: if (strlen(tcf) > 40) { ! 390: clean_up("TERMCAP file name too long"); ! 391: } ! 392: tc_file = tcf; ! 393: } else { ! 394: if (!(tc_file = md_gdtcf())) { ! 395: clean_up("I need a termcap file"); ! 396: } ! 397: } ! 398: ! 399: if (!(term = md_getenv("TERM"))) { ! 400: clean_up("Cannot find TERM variable in environ"); ! 401: } ! 402: if ((fp = fopen(tc_file, "r")) == NULL) { ! 403: sprintf(buf, "Cannot open TERMCAP file: %s", tc_file); ! 404: clean_up(buf); ! 405: } ! 406: ! 407: if (!tc_tname(fp, term, buf)) { ! 408: sprintf(buf, "Cannot find TERM type: %s in TERMCAP file: %s", term, ! 409: tc_file); ! 410: clean_up(buf); ! 411: } ! 412: tc_gtdata(fp, buf); ! 413: fclose(fp); ! 414: } ! 415: ! 416: boolean ! 417: tc_tname(fp, term, buf) ! 418: FILE *fp; ! 419: char *term; ! 420: char *buf; ! 421: { ! 422: short i, j; ! 423: boolean found = 0; ! 424: char *fg; ! 425: ! 426: while (!found) { ! 427: i = 0; ! 428: fg = fgets(buf, BUFLEN, fp); ! 429: if (fg != NULL) { ! 430: if ( (buf[0] != '#') && (buf[0] != ' ') && (buf[0] != TAB) && ! 431: (buf[0] != CR) && (buf[0] != LF)) { ! 432: while (buf[i] && (!found)) { ! 433: j = 0; ! 434: while (buf[i] == term[j]) { ! 435: i++; ! 436: j++; ! 437: } ! 438: if ((!term[j]) && ((buf[i] == '|') || (buf[i] == ':'))) { ! 439: found = 1; ! 440: } else { ! 441: while (buf[i] && (buf[i] != '|') && (buf[i] != ':')) { ! 442: i++; ! 443: } ! 444: if (buf[i]) { ! 445: i++; ! 446: } ! 447: } ! 448: } ! 449: } ! 450: } else { ! 451: break; ! 452: } ! 453: } ! 454: return(found); ! 455: } ! 456: ! 457: tc_gtdata(fp, buf) ! 458: FILE *fp; ! 459: char *buf; ! 460: { ! 461: short i; ! 462: boolean first = 1; ! 463: ! 464: do { ! 465: if (!first) { ! 466: if ((buf[0] != TAB) && (buf[0] != ' ')) { ! 467: break; ! 468: } ! 469: } ! 470: first = 0; ! 471: i = 0; ! 472: while (buf[i]) { ! 473: while (buf[i] && (buf[i] != ':')) { ! 474: i++; ! 475: } ! 476: if (buf[i] == ':') { ! 477: if (!strncmp(buf + i, ":cl=", 4)) { ! 478: tc_gets(buf + i, &CL); ! 479: } else if (!strncmp(buf + i, ":cm=", 4)) { ! 480: tc_gets(buf + i, &CM); ! 481: } else if (!strncmp(buf + i, ":up=", 4)) { ! 482: tc_gets(buf + i, &UC); ! 483: } else if (!strncmp(buf + i, ":do=", 4)) { ! 484: tc_gets(buf + i, &DO); ! 485: } else if (!strncmp(buf + i, ":vs=", 4)) { ! 486: tc_gets(buf + i, &VS); ! 487: } else if (!strncmp(buf + i, ":ve=", 4)) { ! 488: tc_gets(buf + i, &VE); ! 489: } else if (!strncmp(buf + i, ":ti=", 4)) { ! 490: tc_gets(buf + i, &TI); ! 491: } else if (!strncmp(buf + i, ":te=", 4)) { ! 492: tc_gets(buf + i, &TE); ! 493: } else if (!strncmp(buf + i, ":vs=", 4)) { ! 494: tc_gets(buf + i, &VS); ! 495: } else if (!strncmp(buf + i, ":ve=", 4)) { ! 496: tc_gets(buf + i, &VE); ! 497: } else if (!strncmp(buf + i, ":so=", 4)) { ! 498: tc_gets(buf + i, &SO); ! 499: } else if (!strncmp(buf + i, ":se=", 4)) { ! 500: tc_gets(buf + i, &SE); ! 501: } else if (!strncmp(buf + i, ":li#", 4)) { ! 502: tc_gnum(buf + i, &LINES); ! 503: } else if (!strncmp(buf + i, ":co#", 4)) { ! 504: tc_gnum(buf + i, &COLS); ! 505: } ! 506: i++; ! 507: } ! 508: } ! 509: } while (fgets(buf, BUFLEN, fp) != NULL); ! 510: ! 511: if ((!CM) || (!CL)) { ! 512: clean_up("Terminal and termcap must have cm and cl"); ! 513: } ! 514: tc_cmget(); ! 515: } ! 516: ! 517: tc_gets(ibuf, tcstr) ! 518: char *ibuf; ! 519: char **tcstr; ! 520: { ! 521: short i, j, k, n; ! 522: char obuf[BUFLEN]; ! 523: ! 524: i = 4; ! 525: j = 0; ! 526: ! 527: while (ibuf[i] && is_digit(ibuf[i])) { ! 528: i++; ! 529: } ! 530: ! 531: while (ibuf[i] && (ibuf[i] != ':')) { ! 532: if (ibuf[i] == '\\') { ! 533: i++; ! 534: switch(ibuf[i]) { ! 535: case 'E': ! 536: obuf[j] = ESC; ! 537: i++; ! 538: break; ! 539: case 'n': ! 540: obuf[j] = LF; ! 541: i++; ! 542: break; ! 543: case 'r': ! 544: obuf[j] = CR; ! 545: i++; ! 546: break; ! 547: case 'b': ! 548: obuf[j] = BS; ! 549: i++; ! 550: break; ! 551: case 't': ! 552: obuf[j] = TAB; ! 553: i++; ! 554: break; ! 555: case '0': ! 556: case '1': ! 557: case '2': ! 558: case '3': ! 559: case '4': ! 560: case '5': ! 561: case '6': ! 562: case '7': ! 563: case '8': ! 564: case '9': ! 565: n = 0; ! 566: k = 0; ! 567: while (k < 3 && ibuf[i] && is_digit(ibuf[i])) { ! 568: n = (8 * n) + (ibuf[i] - '0'); ! 569: i++; ! 570: k++; ! 571: } ! 572: obuf[j] = (char) n; ! 573: break; ! 574: default: ! 575: obuf[j] = ibuf[i]; ! 576: i++; ! 577: } ! 578: } else if (ibuf[i] == '^') { ! 579: obuf[j] = ibuf[i+1] - 64; ! 580: i += 2; ! 581: } else { ! 582: obuf[j] = ibuf[i++]; ! 583: } ! 584: j++; ! 585: } ! 586: obuf[j] = 0; ! 587: if (!(*tcstr = md_malloc(j + 1))) { ! 588: clean_up("cannot alloc() memory"); ! 589: } ! 590: (void) strcpy(*tcstr, obuf); ! 591: } ! 592: ! 593: tc_gnum(ibuf, n) ! 594: char *ibuf; ! 595: int *n; ! 596: { ! 597: short i; ! 598: int r = 0; ! 599: ! 600: i = 4; ! 601: ! 602: while (is_digit(ibuf[i])) { ! 603: r = (r * 10) + (ibuf[i] - '0'); ! 604: i++; ! 605: } ! 606: *n = r; ! 607: } ! 608: ! 609: tstp() ! 610: { ! 611: endwin(); ! 612: md_tstp(); ! 613: ! 614: start_window(); ! 615: printf("%s%s", TI, VS); ! 616: wrefresh(curscr); ! 617: md_slurp(); ! 618: } ! 619: ! 620: tc_cmget() ! 621: { ! 622: short i = 0, j = 0, rc_spec = 0; ! 623: ! 624: while (CM[i] && (CM[i] != '%') && (j < 15)) { ! 625: cm_esc[j++] = CM[i++]; ! 626: } ! 627: cm_esc[j] = 0; ! 628: ! 629: while (CM[i] && (rc_spec < 2)) { ! 630: if (CM[i] == '%') { ! 631: i++; ! 632: switch(CM[i]) { ! 633: case 'd': ! 634: rc_spec++; ! 635: break; ! 636: case 'i': ! 637: cm_inc = 1; ! 638: break; ! 639: case '2': ! 640: cm_two = 1; ! 641: rc_spec++; ! 642: break; ! 643: case '3': ! 644: cm_three = 1; ! 645: rc_spec++; ! 646: break; ! 647: case '.': ! 648: cm_char = 1; ! 649: rc_spec++; ! 650: break; ! 651: case 'r': ! 652: cm_reverse = 1; ! 653: break; ! 654: case '+': ! 655: i++; ! 656: cm_inc = CM[i]; ! 657: cm_char = 1; ! 658: rc_spec++; ! 659: break; ! 660: } ! 661: i++; ! 662: } else { ! 663: j = 0; ! 664: while (CM[i] && (CM[i] != '%')) { ! 665: cm_sep[j++] = CM[i++]; ! 666: } ! 667: cm_sep[j] = 0; ! 668: } ! 669: } ! 670: ! 671: j = 0; ! 672: if (rc_spec == 2) { ! 673: while (CM[i] && (j < 15)) { ! 674: cm_end[j++] = CM[i++]; ! 675: } ! 676: } ! 677: cm_end[j] = 0; ! 678: } ! 679: ! 680: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.