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