|
|
1.1 ! root 1: /* EMACS_MODES: c !fill */ ! 2: ! 3: #include "emacs_io.h" ! 4: #include "emacs_gb.h" ! 5: #include "emacs_disp.h" ! 6: #ifdef TERMINFO ! 7: #include <sys/types.h> ! 8: #include <sys/termio.h> ! 9: #define SGTTY struct termio ! 10: #include <term.h> ! 11: #endif ! 12: ! 13: /* character insert */ ! 14: ! 15: /* inserts count occurances of the character c in the file */ ! 16: ! 17: ! 18: ! 19: insertc(count,c) ! 20: ! 21: register char c; ! 22: register int count; ! 23: ! 24: { ! 25: ! 26: if (count < 0) return; /* Reject bad count */ ! 27: while (count--) { ! 28: if ((OVERW) && (c != EOL) && (clptr[column] != EOL)) { ! 29: ! 30: clptr[column] = c; ! 31: sputl(curln,column,curln); /* fix this line */ ! 32: modify(curln); ! 33: column++; ! 34: } else { ! 35: if(put(c)==0) break; ! 36: } ! 37: } ! 38: } ! 39: ! 40: /* insert one character into the file at current position */ ! 41: ! 42: put(c) ! 43: ! 44: register char c; ! 45: /* Keywords: commands:10 insertion line-representation:50 */ ! 46: { ! 47: ! 48: register char tc; ! 49: register int xcol; ! 50: ! 51: if (c == EOL) { ! 52: nl(1); ! 53: return(1); ! 54: } ! 55: xcol=column; ! 56: while (c!= EOL) { ! 57: tc = clptr[xcol]; ! 58: clptr[xcol++] = c; ! 59: c = tc; ! 60: } ! 61: modify(curln); ! 62: clptr = ckline(curln,xcol); ! 63: if (clptr == NULL) { ! 64: clptr = mkline(curln); ! 65: *(clptr+xcol-1) = EOL; ! 66: return(0); ! 67: } ! 68: clptr[xcol] = EOL; ! 69: sputl(curln,column,curln); /* fix this line */ ! 70: move(curln,column+1); ! 71: return(1); ! 72: } ! 73: ! 74: /* tabc -- tab command */ ! 75: /* inserts a tab unless notabs mode is on, in which case */ ! 76: /* it inserts spaces up to next tabstop. */ ! 77: ! 78: tabc(count,arg) ! 79: ! 80: register int count; ! 81: int arg; ! 82: ! 83: /* Keywords: commands insertion */ ! 84: { ! 85: if (infrn >= 0) { /* no dice in macro */ ! 86: if (NOTABS) { ! 87: while (count--) { ! 88: do { ! 89: put(' '); ! 90: } while (column%TABSTOP); ! 91: } ! 92: } else { ! 93: insertc(count,arg); ! 94: } ! 95: } ! 96: return(1); ! 97: } ! 98: ! 99: /* mvc -- move with checking for c<=length(l) */ ! 100: ! 101: ! 102: ! 103: mvc(l,c) ! 104: register int l; ! 105: register int c; ! 106: ! 107: /* Keywords: commands:40 movement */ ! 108: { ! 109: register int x; ! 110: ! 111: if ((x = leng(l)) < c) move(l,x); ! 112: else move (l,c); ! 113: } ! 114: /* move to new position in the file */ ! 115: ! 116: move (newln,newcol) ! 117: register int newln; ! 118: register int newcol; ! 119: ! 120: { ! 121: /* Keywords: movement buffer-allocation:20 */ ! 122: ! 123: if (newln < 1) newln = 1; ! 124: if (newln >= NPTRS) { ! 125: if (!growbuf(newln)) { ! 126: newln = NPTRS-1; ! 127: } ! 128: } ! 129: curln = newln; ! 130: clptr = mkline(curln); ! 131: column = newcol; ! 132: return; ! 133: } ! 134: ! 135: /* move both the display matrix pointer and the actual display to the ! 136: * specified line and column */ ! 137: ! 138: mgo(x,y) ! 139: ! 140: register int x,y; ! 141: ! 142: { ! 143: ! 144: sgo(mline = x,mcol = y); ! 145: } ! 146: ! 147: ! 148: /* move the display cursor to the specified destination. sgo attempts ! 149: * to optimize the movement, using single character or absolute ! 150: * positioning */ ! 151: #ifdef PC ! 152: sgo(x,y) ! 153: register int x,y; ! 154: { ! 155: ! 156: video(REG(POS_CUR,0),REG(PAGE_0,0),0,REG(x,y)); ! 157: ! 158: } ! 159: #else ! 160: sgo(x,y) ! 161: /* Keywords: screen-handling the-screen-cursor */ ! 162: register int x,y; ! 163: ! 164: { ! 165: int mx,my; ! 166: int xcost; /* cost with all relative movement */ ! 167: int ycost; /* cost with carriage return */ ! 168: /* acost is cost of absolute positioning */ ! 169: ! 170: /* calculate relative costs of various movements. cost functions */ ! 171: /* automatically indicate that un-doable motions have infinite cost */ ! 172: ! 173: ! 174: if (umode) unline(); /* out of "underline mode" */ ! 175: ! 176: /* calculate xcost and ycost */ ! 177: ! 178: mx = x-scrlin; ! 179: if (mx<0) { ! 180: mx = -mx; ! 181: xcost = mx*lUP; ! 182: } else xcost = mx*lDOWN; ! 183: ! 184: ycost = y + xcost + lCR; ! 185: ! 186: my = y-scrcol; ! 187: if (my<0) { ! 188: my = -my; ! 189: xcost +=my*lBAK; ! 190: } else xcost += my; ! 191: ! 192: if (xcost == 0) return; /* Catch spurious calls to sgo */ ! 193: ! 194: if (acost < ycost) { ! 195: if (acost < xcost) { ! 196: /* do absolute positioning */ ! 197: if (CURAD) { ! 198: absmove(x,y); ! 199: } else { /* have relative addrs */ ! 200: if (x>scrlin) eprintf (RELDOWN,mx); ! 201: if (x<scrlin) eprintf (RELUP,mx); ! 202: if (y>scrcol) eprintf (RELFORW,my); ! 203: if (y<scrcol) eprintf (RELBACK,my); ! 204: } ! 205: scrlin=x; ! 206: scrcol=y; ! 207: return; ! 208: } /* else relative is cheap, do it */ ! 209: } else { ! 210: if (osert && (MI == 0)) { ! 211: unsert(); /* LEAVE insert character mode */ ! 212: } ! 213: if (ycost < xcost) { ! 214: /* do carriage return processing */ ! 215: PUTS(CR); /* carriage return */ ! 216: scrcol = 0; ! 217: ! 218: /* fall through to finish with relative motion */ ! 219: } ! 220: } ! 221: ! 222: while (x != scrlin) { ! 223: if (x < scrlin) { ! 224: PUTS(UP); ! 225: scrlin--; ! 226: } else { ! 227: PUTS(DOWN); ! 228: scrlin++; ! 229: } ! 230: } ! 231: ! 232: /* now correct row */ ! 233: ! 234: while (y != scrcol) { ! 235: if (y < scrcol) { ! 236: PUTS(BACK); ! 237: scrcol--; ! 238: } else { ! 239: if ((FORWARD == NULL)|| (FORWARD[1] && (osert==0))) { ! 240: if (osert) { ! 241: unsert(); ! 242: } ! 243: x = cmap[scrlin] [scrcol]; ! 244: if (x == 0) x=cmap[scrlin] [scrcol] = ' '; ! 245: if (x & 0200) pu(x); /* underlined character */ ! 246: else { ! 247: if (umode) unline(); ! 248: putchar(x); /* re-write to move; */ ! 249: } ! 250: } else { ! 251: PUTS(FORWARD); ! 252: } ! 253: scrcol++; ! 254: } ! 255: }; ! 256: return; ! 257: } ! 258: ! 259: /* unsert -- LEAVE insert character mode */ ! 260: ! 261: unsert() ! 262: { ! 263: /* Keywords: screen-handling terminal-parameters insertion character-at-a-time */ ! 264: PUTS(OSERTC); /* can't stay inserting */ ! 265: osert = 0; ! 266: } ! 267: ! 268: unline() ! 269: { ! 270: /* Keywords: screen-handling terminal-parameters underlining */ ! 271: PUTS(UEND); ! 272: umode = 0; ! 273: } ! 274: ! 275: /* vshift -- shift the display image from top to bottom (inclusive) by x */ ! 276: ! 277: ! 278: vshift(top,bottom,x) ! 279: /* Keywords: scrolling the-screen-map terminal-parameters:20 display-update:80 */ ! 280: int top; ! 281: int bottom; ! 282: int x; ! 283: ! 284: { ! 285: register int i; ! 286: register int j; ! 287: char *cp1; ! 288: char *cp2; ! 289: int *jnkptr; ! 290: int *mapptr; ! 291: int start; ! 292: int stop; ! 293: register int off; ! 294: ! 295: if (x > 0) { ! 296: off = 1; ! 297: start = top; ! 298: stop = bottom+1; ! 299: } else { ! 300: off = -1; ! 301: start = bottom; ! 302: stop = top-1; ! 303: } ! 304: for (i = start,mapptr = scrmap+i,jnkptr = scrjnk+i; i != stop-x; i+=off,mapptr+=off,jnkptr+=off) { ! 305: *jnkptr = *(jnkptr+x); ! 306: *mapptr = *(mapptr+x); ! 307: cp1 = cmap[i]; ! 308: cp2 = cmap[i+x]; ! 309: for (j = 0; j < *jnkptr; j++) { ! 310: *cp1++ = *cp2++; ! 311: } ! 312: } ! 313: while (i != stop) { ! 314: if (off > 0) { ! 315: *mapptr++ = *jnkptr++ = 0; ! 316: i++; ! 317: } else { ! 318: *mapptr-- = *jnkptr-- = 0; ! 319: i--; ! 320: } ! 321: } ! 322: } ! 323: ! 324: /* adjust vertical position of line -- open (or close) lines on */ ! 325: /* the screen argument is the number of lines to add (or drop). */ ! 326: ! 327: vadjust(x,xline) ! 328: ! 329: register int x; ! 330: int xline; ! 331: /* Keywords: display-update:90 deletion:50 insertion:50 terminal-parameters:90 the-screen-map scrolling:20 screen-lines screen-handling */ ! 332: { ! 333: register int i; ! 334: register int j; ! 335: int oldx; ! 336: ! 337: ! 338: oldx = xline; ! 339: TRACE(VADJUST); ! 340: TRACE(curln); ! 341: TRACE(x); ! 342: if (x<0) { ! 343: x = -x; ! 344: i = 1; ! 345: } else i = 0; ! 346: if (((j = lastln-xline-x) <= 0)|| ! 347: ((x*VCOST)>(j*ttywarp*CFILL))) return; /* nothing to save */ ! 348: SREGION=SCRLINES-oldx; /* effected region */ ! 349: if (i) { /* if deleting lines */ ! 350: sgo(xline,0); ! 351: ! 352: if (SCREG && CURAD) { /*if vt100 stype scrolling */ ! 353: PUTS(TPARM(SCREG,oldx+XBASE,SCRLINES+XBASE-1)); /*define region*/ ! 354: absmove(0,0); ! 355: sgo(SCRLINES-1,0); ! 356: do_n(CLSCROLL,SSCROLL,x); /* Scroll up x lines */ ! 357: PUTS(TPARM(SCREG,XBASE,REALBOT+XBASE-1)); ! 358: absmove(oldx,0); ! 359: } else { ! 360: do_n(CLDEL,LDEL,x); ! 361: sgo(SCRLINES-x,0); ! 362: do_n(CLOPEN,LOPEN,x); ! 363: } ! 364: sgo(oldx,0); ! 365: vshift (oldx,SCRLINES-1,x); ! 366: } else { ! 367: if (SCREG && CURAD && RSCROLL) { /* if vt100 style scrolling */ ! 368: ! 369: PUTS(TPARM(SCREG,oldx+XBASE,SCRLINES+XBASE-1)); /*define region */ ! 370: absmove(xline,0); ! 371: do_n(CRSCROLL,RSCROLL,x); ! 372: PUTS(TPARM(SCREG,XBASE,REALBOT+XBASE-1)); ! 373: absmove(oldx,0); ! 374: } else { ! 375: sgo(SCRLINES-x,0); ! 376: do_n(CLDEL,LDEL,x); ! 377: sgo(oldx,0); ! 378: do_n(CLOPEN,LOPEN,x); ! 379: } ! 380: mgo(oldx,0); ! 381: ! 382: vshift(oldx,SCRLINES-1,-x); ! 383: } ! 384: SREGION=1; ! 385: } ! 386: ! 387: do_n(mulcap,sincap,n) ! 388: char *mulcap; ! 389: register char *sincap; ! 390: register int n; ! 391: ! 392: /* Keywords: scrolling:20 screen-lines:40 terminal-parameters argument-processing screen-handling */ ! 393: ! 394: { ! 395: if (mulcap && (n>1)) { ! 396: /* If we can do all at once */ ! 397: #ifdef TERMINFO ! 398: putpad(tparm(mulcap,n)); ! 399: #else ! 400: PUTS(mulcap,n); ! 401: #endif ! 402: } else { ! 403: while (n--) PUTS(sincap); ! 404: } ! 405: } ! 406: ! 407: absmove(x, y) ! 408: int x; ! 409: int y; ! 410: { ! 411: /* Keywords: terminal-parameters the-screen-cursor screen-handling */ ! 412: ! 413: #ifdef TERMINFO ! 414: putpad(tparm(CURAD, x, y)); ! 415: #else ! 416: #ifdef TERMCAP ! 417: putpad(tgoto(CURAD, y, x)); ! 418: #else ! 419: if (SRCADD) { ! 420: eprintf(CURAD,x+XBASE,y+YBASE); ! 421: } else { ! 422: eprintf(CURAD,y+YBASE,x+XBASE); ! 423: } ! 424: #endif ! 425: #endif ! 426: scrlin=x; ! 427: scrcol=y; ! 428: } ! 429: ! 430: /* sscroll -- try to fix display by scrolling */ ! 431: ! 432: sscroll(x) ! 433: ! 434: register int x; ! 435: /* Keywords: terminal-parameters scrolling screen-handling */ ! 436: { ! 437: register int i; ! 438: ! 439: ! 440: if (SSCROLL == NULL || twowind || (SCRLINES-x < 3) || (curbf != disbuf[cwind])) return; ! 441: ! 442: ! 443: sgo(REALBOT-1,0); /* to bottom */ ! 444: SREGION=REALBOT; /* number of lines effected */ ! 445: do_n(CLSCROLL,SSCROLL,x); ! 446: SREGION=1; ! 447: vshift (0,SCRNLIN-1,x); ! 448: if (timemd) disptime = 1; /* Wiped out time display */ ! 449: } ! 450: ! 451: #endif PC ! 452: ! 453: /* delete chars -- delete characters starting at . */ ! 454: ! 455: /* all characters must be on the same line */ ! 456: ! 457: delc(count) ! 458: ! 459: register int count; ! 460: ! 461: /* Keywords: deletion line-representation killstack:50 stacking:50 commands:20 */ ! 462: ! 463: { ! 464: register char *cp1; ! 465: register char *cp2; ! 466: ! 467: undel(); ! 468: killstk(curln,column,curln,column+count); /* stack even on 0 */ ! 469: if (count == 0) { ! 470: beep(); ! 471: return(0); /* nothing to modify */ ! 472: } ! 473: cp1 = clptr+column; ! 474: cp2 = cp1+count; ! 475: if (NODEL) { ! 476: while (cp1<cp2) *cp1++=' '; ! 477: } else { ! 478: while ((*cp1++ = *cp2++) != EOL); ! 479: } ! 480: sputl(curln,column,curln); ! 481: modify(curln); ! 482: move(curln,column); ! 483: return(1); ! 484: } ! 485: ! 486: /* open up count blank lines in the file */ ! 487: ! 488: openl(count) ! 489: ! 490: register int count; ! 491: ! 492: ! 493: /* Keywords: insertion line-representation memory-allocation:30 text-lines the-screen-map:20 screen-lines:50 */ ! 494: ! 495: { ! 496: ! 497: register int i; ! 498: register char *lp; ! 499: char *lp1; ! 500: char *lp2; ! 501: int oldcol; ! 502: int oldln; ! 503: ! 504: /* first fix the file */ ! 505: ! 506: if (nlines+count >= NPTRS) { ! 507: if (!growbuf(nlines+count)) { ! 508: return; ! 509: } ! 510: } ! 511: if (curln<nlines) { ! 512: for (i = fbkno; i < NBLOCK; i++) { ! 513: if (hipt[i]>curln) hipt[i]+=count; ! 514: if (lowpt[i]>curln) lowpt[i]+=count; ! 515: } ! 516: for (i = nlines; i > curln; i--) { ! 517: ptrs[i+count] = ptrs[i]; ! 518: } ! 519: } ! 520: nlines += count; ! 521: for (i = curln+1; i <= curln+count; i++) ptrs[i] = 0; ! 522: if (clptr[column] != EOL) { ! 523: if(ckline(curln+count,leng(curln)-column)!=NULL) { ! 524: holdin(curln,curln+count); ! 525: lp1 = mkline(curln+count); ! 526: lp2 = lp = mkline(curln) + column; ! 527: while ((*lp1++ = *lp++)!= EOL); ! 528: *lp2 = EOL; ! 529: } ! 530: } ! 531: modify(curln); ! 532: modify(curln+count); ! 533: ! 534: /* now fix the display */ ! 535: ! 536: oldln = curln; ! 537: oldcol = column; ! 538: if (TABMD && (RARE == 0)) { ! 539: tabjust(curln+count); ! 540: } ! 541: if (disbuf[cwind] == curbf) { ! 542: ! 543: /* Adjust scrmap to reflect the change. All lines past oldln in the ! 544: * current buffer that show on the screen are bumped up by count. The ! 545: * current line is bumped only if the whole line moved */ ! 546: ! 547: for (i = wbase; i < SCRLINES; i++) { ! 548: if ((scrmap[i]) && ((nln = scrmap[i]&SCRMSK) >= oldln)) { ! 549: if ((nln != oldln) || (oldcol == 0)) scrmap[i] += count; ! 550: } ! 551: } ! 552: } ! 553: sputl(oldln,oldcol,REST); ! 554: move(oldln,oldcol); ! 555: } ! 556: ! 557: ! 558: /* getname prompts for a string, using ps, and inputs a string */ ! 559: ! 560: /* rubout and @ can be used to edit the string as enterred, and causes ! 561: * a quit, returning no input string ! 562: * ^Y causes the current buffer name to be brought out ! 563: */ ! 564: ! 565: char * ! 566: getname(ps) ! 567: ! 568: register char *ps; ! 569: ! 570: /* Keywords: user-interface prompting key-bindings:50 reading:50 filenames:50 commands:20 text-lines:40 the-screen-cursor:30 macro-hooks:10 */ ! 571: ! 572: { ! 573: register int i; ! 574: register char c; ! 575: int cnt = 1; ! 576: char *xp; ! 577: ! 578: if (infrn < 0) { /* if in macro */ ! 579: if(retrvs(fnbuf,FNLEN)>=0){ ! 580: return(fnbuf); ! 581: } else return(NULL); ! 582: } ! 583: if (hooks[Read_Name_Hook]) { ! 584: stkstr(ps); ! 585: if (hook(Read_Name_Hook) && (retrvs(fnbuf,FNLEN) >= 0)) { ! 586: return(fnbuf); ! 587: }else return(NULL); ! 588: } ! 589: fnbuf[i=0] = 0; ! 590: for (;;) { ! 591: if (infrn == 0 ){ ! 592: prompt(ECHOL,"%s%s",ps,fnbuf); /* display prompt */ ! 593: if (c=fnbuf[i]) { /* If there is stuff past the cursor */ ! 594: ! 595: /* UGH, To find out where the cursor goes, we must duplicate a lot */ ! 596: /* of ugly code out of prompt! */ ! 597: ! 598: char pbuf[256]; ! 599: mline = ECHOL; ! 600: mcol = 0; ! 601: fnbuf[i]=0; ! 602: seprintf(pbuf,"%s%s",ps,fnbuf); ! 603: fnbuf[i]=c; ! 604: xputl(pbuf,0); ! 605: } ! 606: mgo(mline,mcol); ! 607: } ! 608: cnt = 1; ! 609: getbak: donttime=1; /* Avoid time & mail */ ! 610: c = getchar(); ! 611: donttime=0; /* Restore time display */ ! 612: switch(map_it[c]) { ! 613: ! 614: case CQUOTE: ! 615: c = getchar(); ! 616: goto regchar; ! 617: ! 618: case CCTLU: ! 619: cnt*=4; ! 620: goto getbak; /* Bypass re-initilizing cnt! */ ! 621: ! 622: case CEQUIT: ! 623: case CEXIT: ! 624: beep(); ! 625: unprompt(); ! 626: return(NULL); ! 627: case CCTLX: ! 628: xp = mkline(curln); ! 629: goto wrdin; ! 630: case CYANK: ! 631: xp = fname(); ! 632: wrdin: while ((*xp!= 0) && (*xp != EOL)&& (i<FNLEN-1)) { ! 633: cram(fnbuf,i++,*xp++); ! 634: } ! 635: continue; ! 636: default: ! 637: ! 638: ! 639: /* anything that isn't otherwise mapped comes here. Most just insert, */ ! 640: /* but we do check for '@' */ ! 641: ! 642: if (c == '@') { ! 643: fnbuf[0]=0; ! 644: i = 0; ! 645: continue; ! 646: } ! 647: ! 648: if (c>=' ') { ! 649: regchar: if (i<FNLEN-1) cram(fnbuf,i++,c); ! 650: continue; ! 651: } else { ! 652: if ((c != CTRLJ) && (c != CTRLM)) { ! 653: beep; ! 654: continue; ! 655: } ! 656: } ! 657: ! 658: /* Fall through to handle newlines re-mapped by the user */ ! 659: ! 660: case CNEWLINE: ! 661: case CMETA: ! 662: unprompt(); ! 663: if (infrn == 0) mflush(stdout); /* Indicate that we got it */ ! 664: return(fnbuf); ! 665: case CREFRESH: ! 666: clear(); ! 667: continue; ! 668: case CBDEL: ! 669: while (cnt--) { ! 670: if (i) { ! 671: i--; ! 672: mstrcpy(fnbuf+i,fnbuf+i+1); ! 673: } else beep(); ! 674: } ! 675: continue; ! 676: case CFDEL: ! 677: while (cnt--) { ! 678: if (fnbuf[i]) { ! 679: mstrcpy(fnbuf+i,fnbuf+i+1); ! 680: } else beep(); ! 681: } ! 682: continue; ! 683: case CXPOSE: ! 684: if (fnbuf[i] && fnbuf[i+1]) { ! 685: c = fnbuf[i]; ! 686: fnbuf[i]=fnbuf[i+1]; ! 687: fnbuf[++i] = c; ! 688: } ! 689: break; ! 690: case CFORW: ! 691: while (cnt--) { ! 692: if (fnbuf[i]) { ! 693: i++; ! 694: } else beep(); ! 695: } ! 696: continue; ! 697: case CBEGIN: ! 698: i = 0; ! 699: continue; ! 700: case CENDL: ! 701: i = lng(fnbuf); ! 702: continue; ! 703: case CBACK: ! 704: i-=cnt; ! 705: if (i<0) { ! 706: beep(); ! 707: i=0; ! 708: } ! 709: continue; ! 710: case CEKILL: ! 711: fnbuf[i]=0; ! 712: continue; ! 713: } ! 714: } ! 715: } ! 716: ! 717: /* Cram character into the middle of a filename string */ ! 718: ! 719: cram(sp,pos,cchar) ! 720: register char *sp; ! 721: register int pos,cchar; ! 722: /* Keywords: user-interface prompting string-handling:40 */ ! 723: ! 724: { ! 725: ! 726: int nc; ! 727: ! 728: while (cchar) { ! 729: if (pos == FNLEN-1) { ! 730: beep(); ! 731: break; ! 732: } ! 733: nc = sp[pos]; ! 734: sp[pos]=cchar; ! 735: pos++; ! 736: cchar=nc; ! 737: } ! 738: sp[pos]=0; ! 739: } ! 740: ! 741: /* gechar: get EMACS character: */ ! 742: /* returns 0200+c for meta chars, 0400+c for ^X chars */ ! 743: ! 744: ! 745: gechar(ps) ! 746: register char *ps; ! 747: /* Keywords: user-interface character-at-a-time prompting:40 ^-and-M-processing:70 */ ! 748: { ! 749: register int c; ! 750: ! 751: prompt1("%s: ",ps); ! 752: c = getchar(); ! 753: if (map_it[c] == CMETA) { ! 754: prompt1("%s: M-",ps); ! 755: c = 0200+getchar(); ! 756: } ! 757: if (map_it[c] == CCTLX) { ! 758: prompt1("%s: ^X",ps); ! 759: c = 0400+getchar(); ! 760: } ! 761: unprompt(); ! 762: return(c); ! 763: } ! 764: /* putout outputs a string (like eprintf) at the current position */ ! 765: ! 766: /* position is advanced by one line. If the position overflows the screen ! 767: * -MORE- is printed, and input is read. Any character except ^G ! 768: * continues the display, ^G quits by returning -1 */ ! 769: ! 770: /*VARARGS1*/ ! 771: ! 772: putout(string,arg1) ! 773: char *string; ! 774: /* Keywords: prompting:10 informational-displays MORE-processing */ ! 775: { ! 776: if (mline>=SCRLINES) { ! 777: prompt1("-- MORE --"); ! 778: if ((infrn == 0) && ((getchar()) == CTRLG)) return(-1); ! 779: unprompt(); ! 780: mline=0; /* TOP */ ! 781: } ! 782: prompt2(mline,string,&arg1); ! 783: clrl(); ! 784: mgo(++mline,0); ! 785: return(0); ! 786: } ! 787: ! 788: /* put out a string on ECHOL */ ! 789: /*VARARGS1*/ ! 790: ! 791: prompt1(string,arg1) ! 792: char *string; ! 793: /* Keywords: prompting */ ! 794: ! 795: { ! 796: if (infrn) return; /* prompt only if input from stdin */ ! 797: prompt2(ECHOL,string,&arg1); ! 798: if (mcol) sgo(mline,mcol); /* Move cursor only if something is there! */ ! 799: } ! 800: ! 801: /* Keywords: informational-displays time-processing:50 mail-processing:50 */ ! 802: ! 803: prompt3(string,arg1) ! 804: char *string; ! 805: { ! 806: if (infrn) return; ! 807: prompt2(ECHOL-1,string,&arg1); ! 808: scrmap[ECHOL-1] = ECHOHACK; /* Flag for next unprompt */ ! 809: } ! 810: /* put out a string at a specified line */ ! 811: ! 812: /*VARARGS2*/ ! 813: ! 814: prompt(ecl,string,arg1) ! 815: int ecl; ! 816: char *string; ! 817: int arg1; ! 818: /* Keywords: informational-displays mode-line user-interface:20 */ ! 819: { ! 820: prompt2(ecl,string,&arg1); ! 821: } ! 822: ! 823: /* Internal subroutine for all prompting */ ! 824: ! 825: prompt2(ecl,string,argl) ! 826: char *string; ! 827: register int ecl; ! 828: unsigned int *argl; ! 829: ! 830: /* Keywords: prompting informational-displays the-screen-map:40 */ ! 831: ! 832: { ! 833: char pbuf[256]; ! 834: ! 835: mline = ecl; ! 836: scrmap[mline] = 0; /* wipe out previous display */ ! 837: mcol = 0; ! 838: sxprintf(pbuf,string,argl); ! 839: xputl(pbuf,0); ! 840: psx = mline; ! 841: psy = mcol; ! 842: clrl(); ! 843: ! 844: } ! 845: ! 846: /* clear out prompt */ ! 847: ! 848: unprompt() ! 849: /* Keywords: prompting informational-displays the-screen-map:40 deletion:10 */ ! 850: { ! 851: if (infrn) return; /* unprompt only if input from termial */ ! 852: mline = ECHOL; ! 853: mcol = 0; ! 854: clrl(); ! 855: if (scrmap[ECHOL-1] == ECHOHACK) { ! 856: mline = ECHOL-1; ! 857: clrl(); ! 858: } ! 859: if (timemd) disptime = 1; /* put time back */ ! 860: } ! 861: ! 862: /* multi-line deleter */ ! 863: ! 864: /* deletes the text between current position, and kline, kcol */ ! 865: /* all deleted text is stacked */ ! 866: ! 867: tkill() ! 868: /* Keywords: deletion picture-mode:50 killstack:50 stacking:50 the-screen-map:60 */ ! 869: /* arguments are kline,kcol */ ! 870: { ! 871: int oldcol; ! 872: register int x; ! 873: register int y; ! 874: register char *cp; ! 875: char *cp1; ! 876: ! 877: if (kline < 1) kline = 1; ! 878: if (kline >nlines) { ! 879: kline = nlines; ! 880: kcol = leng(kline); ! 881: } ! 882: if ((kline < curln) || ((kline == curln) && (kcol < column))) { ! 883: x = curln; ! 884: y = column; ! 885: move (kline, kcol); ! 886: kcol = y; ! 887: kline = x; ! 888: } ! 889: ! 890: ! 891: if (kline == curln) { ! 892: return(delc (kcol-column)); /* cheap out */ ! 893: } ! 894: oldcol = column; ! 895: undel(); ! 896: killstk(curln,column,kline,kcol); ! 897: if (PICMODE) { ! 898: int mincol; ! 899: int maxcol; ! 900: int ln; ! 901: register int c; ! 902: ! 903: ln = curln; ! 904: if (kcol<column) { ! 905: mincol=kcol; ! 906: maxcol=column; ! 907: } else { ! 908: mincol=column; ! 909: maxcol=kcol; ! 910: } ! 911: while (ln<=kline) { ! 912: cp = mkline(ln); ! 913: c = 0; ! 914: if (NODEL) { ! 915: while (c<maxcol) { ! 916: if (cp[c]==EOL) break; ! 917: if (c>=mincol) cp[c] = ' '; ! 918: c++; ! 919: } ! 920: } else { ! 921: int lln; ! 922: ! 923: lln = leng(ln); ! 924: if (lln > mincol) { ! 925: if (lln < maxcol) { ! 926: cp[mincol]=EOL; ! 927: } else { ! 928: c = mincol; ! 929: while (1) { ! 930: cp[c]=(*(cp+c+maxcol-mincol)); ! 931: if (*(cp+(c++))==EOL) break; ! 932: } ! 933: } ! 934: } ! 935: } ! 936: modify(ln); ! 937: ln++; ! 938: } ! 939: sputl(curln,column,REST); ! 940: mvc(curln,column); ! 941: return(1); ! 942: } ! 943: if(ckline(curln,column+leng(kline)-kcol) == NULL) return(0); ! 944: holdin(curln,kline); ! 945: cp1 = mkline(curln)+column; ! 946: cp = mkline(kline)+kcol; ! 947: while ((*cp1++ = *cp++)!= EOL) column++; ! 948: modify(curln); ! 949: ! 950: /* current line is fixed, fix rest */ ! 951: ! 952: x = kline-curln; ! 953: ! 954: /* Adjust block ranges to account for movement in lines. high point ! 955: * shifts if its above the deleted region. Low point shifts if it's ! 956: * in or above */ ! 957: ! 958: if (curln+x<nlines) { ! 959: for (y = fbkno; y < NBLOCK; y++) { ! 960: if (hipt[y]>curln+x) hipt[y]-=x; ! 961: if (lowpt[y]>curln) lowpt[y]-=x; ! 962: } ! 963: } ! 964: ! 965: for (y = curln+1+x; y <= nlines; y++) { ! 966: ptrs[y-x] = ptrs[y]; ! 967: } ! 968: nlines -= x; ! 969: ! 970: if (disbuf[cwind] == curbf) { ! 971: ! 972: /* Adjust scrmap to reflect the change. All lines past oldln in the ! 973: * current buffer that show on the screen are bumped up by count. The ! 974: * current line is bumped only if the whole line moved */ ! 975: ! 976: for (y = wbase; y < SCRLINES; y++) { ! 977: if ((scrmap[y]) && ((nln = scrmap[y]&SCRMSK) >= curln)) { ! 978: if ((nln == curln) && oldcol) continue; /* dont wipe out curln */ ! 979: if (nln >= (curln+x)) scrmap[y]-=x; /* map down for lines past the deletion */ ! 980: else scrmap[y] = 0; /* this line has been killed */ ! 981: } ! 982: } ! 983: } ! 984: ! 985: sputl(curln,oldcol,REST); ! 986: move(curln,oldcol); ! 987: return(1); ! 988: } ! 989: ! 990: /* refresh the screen */ ! 991: ! 992: /* clear and force refresh */ ! 993: ! 994: refresh(arg) ! 995: ! 996: register unsigned arg; ! 997: /* Keywords: display-update commands the-screen-cursor:40 windows:20 */ ! 998: { ! 999: ! 1000: ! 1001: if (numarg) dspage(curln-arg,0); ! 1002: else clear(); ! 1003: } ! 1004: ! 1005: /* mark a region of the displayy for fixing. Arguments are the */ ! 1006: /* first line and (file) character position to fix, and the last line */ ! 1007: ! 1008: sputl(from, col, to) ! 1009: ! 1010: int col; ! 1011: register int from; ! 1012: int to; ! 1013: { ! 1014: /* Keywords: screen-handling:60 commands:30 display-update:30 deletion:50 insertion:50 */ ! 1015: register int *fmp; ! 1016: int wwid; ! 1017: ! 1018: if (disbuf[cwind] != curbf) return; /* not in this window */ ! 1019: from -= minln; ! 1020: wwid = SCRLINES-wbase; ! 1021: fmp = fmap; ! 1022: to -= minln; ! 1023: if (to > wwid) to = wwid; ! 1024: if ((from >= 0) && (from <= wwid)) { ! 1025: if (fmp[from] > col) fmp[from]= col; ! 1026: } ! 1027: while (++from<=to) if (from >= 0) fmp[from]=0; ! 1028: return; ! 1029: } ! 1030: ! 1031: /* Display output routines. This is probably less clean than the ! 1032: * previous version, but handles underlining and also does a better ! 1033: * job with insert/delete character. */ ! 1034: ! 1035: /* The functions are: ! 1036: ! 1037: cflush(buf,n) -- put n-mcol characters starting at buf+mcol on the ! 1038: screen at current mline,mcol. This is ! 1039: assumed not to overflow one line. ! 1040: ! 1041: xputl(line,flag,col) -- The hard work. Maps a string to one ! 1042: or more screen lines. The exact nature of ! 1043: the mapping is different for buffer lines ! 1044: than for strings, as indicated by flag. ! 1045: */ ! 1046: ! 1047: ! 1048: /* Cflush is the main vehicle for the escape of characters. All ! 1049: * charcters that actaually print (as opposed to terminal ! 1050: * control) go through here. The general strategy is that if the ! 1051: * desired character is by some odd chance there already, nothing ! 1052: * happens. If the desired character is a space and the terminal is ! 1053: * beyond the end of the line, nothing happens. If insert or delete ! 1054: * characters will help bring cp into line with what's on the ! 1055: * screen, then it will use them as necessary. Underlining is ! 1056: * handled, including the pain of making it work on various ! 1057: * brain-damaged terminals. */ ! 1058: ! 1059: /* These general principals followed in a way that is optimized for ! 1060: * common cases, including: display of a whole line that is already ! 1061: * on the screen. Display of a whole line that does not correspond ! 1062: * to what's on the screen, and display of one new character. */ ! 1063: ! 1064: ! 1065: #ifdef PC ! 1066: #define EOM 0 /* End of string marker */ ! 1067: #else ! 1068: #define EOM '\337' /* End of line marker */ ! 1069: #endif PC ! 1070: ! 1071: cflush(cp,n) ! 1072: ! 1073: register char *cp; ! 1074: int n; ! 1075: ! 1076: /* Keywords: character-at-a-time:40 insertion:30 deletion:30 character-output screen-handling terminal-parameters:20 */ ! 1077: { ! 1078: register char *mp; ! 1079: register int x; ! 1080: register int y; ! 1081: int z; ! 1082: int jnk; ! 1083: int stop; ! 1084: ! 1085: cp[n] = EOM; /* Mark end of line */ ! 1086: ! 1087: ! 1088: #ifdef PC ! 1089: mcol += vout(mline,mcol,cp+mcol); ! 1090: if (scrjnk[mline]< mcol) scrjnk[mline]=mcol; ! 1091: #else ! 1092: mp = cmap[mline]; /* character map pointer */ ! 1093: x = jnk = scrjnk[mline]; ! 1094: while (x < n) mp[x++] = BLANK; /* Clear out the spaces we will write */ ! 1095: x = mcol; /* Get mcol into a register */ ! 1096: stop = 0; ! 1097: while (1) { ! 1098: while (mp[x]== cp[x]) x++; /* skip rapidly over same stuff */ ! 1099: if ((mp[x] == 0) && (cp[x] == ' ')) { ! 1100: x++; ! 1101: continue; ! 1102: } ! 1103: if ((cp[x] == EOM)) { ! 1104: mcol = x; ! 1105: if (x < jnk) x = jnk; ! 1106: scrjnk[mline] = x; ! 1107: ! 1108: if ((scrcol > REALWID) && SCRWRAP) { ! 1109: scrlin++; ! 1110: scrcol=0; ! 1111: } ! 1112: return; ! 1113: } ! 1114: ! 1115: /* Character was not there, we must do some work here! */ ! 1116: ! 1117: nmput++; /* count for stats */ ! 1118: if ((x != scrcol) || (mline != scrlin)) sgo(mline,x); ! 1119: ! 1120: /* First, see if we have enough left to worry about insert/delete */ ! 1121: ! 1122: if (jnk-x >= lDELC) { ! 1123: if (stop == 0) { ! 1124: ! 1125: /* Find the last matching position */ ! 1126: ! 1127: stop = n-1; ! 1128: if (stop >= jnk) stop = jnk; ! 1129: while ((mp[stop] == 0) && (cp[stop] == ' ')) stop--; ! 1130: while (mp[stop] == cp[stop]) stop--; ! 1131: stop++; ! 1132: } ! 1133: ! 1134: /* Try to use DELC. Must have at least lDELC characters match within ! 1135: * DLOOK characters of the current position. */ ! 1136: ! 1137: /* Note: If there are ANY nulls in the characters to be deleted, we */ ! 1138: /* Can't use DELC, since the concept-style terminals won't delete*/ ! 1139: ! 1140: ! 1141: if (DELC&& mp[x]) { ! 1142: ! 1143: y = 1; ! 1144: while (y < DLOOK && mp[x+y]) { ! 1145: if (mp[x+y] == cp[x] ) { ! 1146: z = dccost * y; ! 1147: if (y+z+x >stop) goto NoDEL; ! 1148: if (strncmp(cp+x,mp+x+y,z)) goto NoDEL; ! 1149: /* Should be next_del, but this is faster */ ! 1150: ! 1151: /* Delete y characters from under the cursor */ ! 1152: ! 1153: SREGION=SCRWID-x; /* number of char's gobbled */ ! 1154: if ((DELMODE==1) && (osert == 0)) { ! 1155: PUTS(INSERTM); /* enter "delete mode, UGH!!!" */ ! 1156: osert = 1; ! 1157: } ! 1158: if ((DELMODE==2) && osert) { ! 1159: unsert(); /* Must not be in insert mode */ ! 1160: } ! 1161: if (x > jnk) jnk = x; ! 1162: while (y--) { ! 1163: ! 1164: PUTS(DELC); /*clobber next char */ ! 1165: jnk = lshift(scrlin,x,jnk-1); ! 1166: } ! 1167: stop = 0; /* Don't know where to stop any more */ ! 1168: SREGION=1; ! 1169: x += z; /* This many matched */ ! 1170: goto donec; /* Process next character */ ! 1171: } ! 1172: next_del: y++; ! 1173: } ! 1174: } ! 1175: ! 1176: ! 1177: /* Now see if insertion will help. It will be used if lINSC ! 1178: * characters can be matched within ILOOK characters of the cursor. */ ! 1179: ! 1180: NoDEL: ! 1181: if ((INSERTC || INSERTM) && (stop > x+lINSC) && ((cp[x] & 0200) == 0)) { ! 1182: y = 1; ! 1183: while ((y<ILOOK) && (x+y < stop) && ((cp[x+y]&0200) == 0)) { ! 1184: if (cp[x+y] == mp[x]) { ! 1185: ! 1186: /* Found a match, now figure out how much we should have to see before inserting */ ! 1187: ! 1188: if (INSERTC) z = y * iccost; ! 1189: /* If inserting is per-character, then each one costs iccost */ ! 1190: /* Otherwise, it costs iccost to go into and out of icmode */ ! 1191: ! 1192: else { ! 1193: if (osert) z = 0; ! 1194: else z = iccost; ! 1195: } ! 1196: /* After a successful insert, we will need cursor motion, so add that too. */ ! 1197: z += acost; ! 1198: if ((x+y+z)>stop) goto NOINS; ! 1199: if (strncmp(cp+x+y,mp+x,z)) goto NOINS; ! 1200: ! 1201: ! 1202: ! 1203: /* Now insert y characters at point, taking from cp and putting out to ! 1204: * screen. Note that underscores and overstrikes are rejected ! 1205: * above, so that nothing here will overstrike. We just blast out ! 1206: * the characters. */ ! 1207: if (x > jnk) jnk = x; ! 1208: SREGION=jnk-x; /* number of char's moved */ ! 1209: if (umode) unline(); ! 1210: if ((osert == 0) && INSERTM) { ! 1211: PUTS(INSERTM); /* insert mode */ ! 1212: osert++; ! 1213: } ! 1214: ! 1215: while (y--) { ! 1216: if (INSERTC) PUTS(INSERTC); /* insert prepare */ ! 1217: putchar(cp[x]); ! 1218: if (INSERTP) PUTS(INSERTP); /* insert pad */ ! 1219: jnk = rshift(scrlin,scrcol+1,mp[scrcol]); ! 1220: mp[scrcol++] = cp[x++]; ! 1221: } ! 1222: x+= z; ! 1223: SREGION=1; ! 1224: stop = 0; /* Stop is no good any more */ ! 1225: goto donec; /* process next character */ ! 1226: } ! 1227: next_ins: y++; ! 1228: } ! 1229: } ! 1230: } ! 1231: NOINS: if (osert) { ! 1232: unsert(); ! 1233: } ! 1234: ! 1235: /* Underscore processing. relevant variables are EOVER and ULINE. ! 1236: * EOVER should be one if writing over an underlined position clears ! 1237: * it, otherwise, make it zero, and we will clear the line to get ! 1238: * rid of unwanted underscores. ULINE is a string parameter that ! 1239: * contains whatever is needed to print the character with an ! 1240: * underline. If the terminal underscores naturally, then ULINE is ! 1241: * %c<BS>_. If the terminal has an underscore character mode, ! 1242: * then ULINE is underscore mode on, %c, underscore mode off. If ! 1243: * the terminal has an underscore single character command, then ! 1244: * ULINE is underscore character %c. This is inefficient in ! 1245: * underscoring giant blocks of text, but this should be rare */ ! 1246: ! 1247: ! 1248: if (cp[x]&0200){ ! 1249: pu(cp[x]); /* underlined character */ ! 1250: } else { ! 1251: if (umode) unline(); ! 1252: if ((mp[x]&0200)&& (!EOVER)) { /* If re-writing won't erase */ ! 1253: PUTS(CLINE); /* wipe line */ ! 1254: while (jnk > scrcol) mp[--jnk] = BLANK; /* Wipeout array */ ! 1255: } ! 1256: putchar(cp[x]); ! 1257: } ! 1258: mp[scrcol++] = cp[x++]; ! 1259: donec: continue; ! 1260: } ! 1261: } ! 1262: ! 1263: /* print an underscored character. */ ! 1264: ! 1265: ! 1266: pu(c) ! 1267: register char c; ! 1268: { ! 1269: /* Keywords: screen-handling:20 underlining character-output:40 */ ! 1270: ! 1271: register int oc; ! 1272: if (osert) unsert(); ! 1273: c &= 0177; ! 1274: if ((c == 0)|| (c == 040)) { ! 1275: /* bare underscore */ ! 1276: oc = cmap[mline][mcol]&0137; /* Map space to null */ ! 1277: if (EOVER && (UEND || (oc == 0))) { ! 1278: if (umode) unline(); ! 1279: putchar ('_'); ! 1280: return; /* just put out the underscore */ ! 1281: } ! 1282: c = ' '; /* make sure that we blank over whats there */ ! 1283: } ! 1284: if (UEND == 0) { ! 1285: eprintf(ULINE,c); ! 1286: } else { ! 1287: if (umode == 0) eprintf(ULINE); /* enter "underscore mode" */ ! 1288: putchar(c); ! 1289: umode = 1; ! 1290: } ! 1291: } ! 1292: ! 1293: ! 1294: ! 1295: /* lshift -- left shift the screen to account for delete character */ ! 1296: ! 1297: lshift (line,col,limit) ! 1298: int line; ! 1299: register int col; ! 1300: register int limit; ! 1301: ! 1302: /* Keywords: character-output the-screen-map deletion */ ! 1303: { ! 1304: register char *lp; ! 1305: int x; ! 1306: ! 1307: lp = cmap[line]; ! 1308: while (col < limit) { ! 1309: if ((lp[col]=lp[col+1]) == 0) break; ! 1310: col++; ! 1311: } ! 1312: lp[col] = 0; ! 1313: if (IN && (col == SCRWID)) { ! 1314: x = lp[col] = cmap[++line] [0]; ! 1315: limit++; ! 1316: if (x) scrjnk[line] = lshift(line,0,scrjnk[line]-1); ! 1317: } ! 1318: return(limit); ! 1319: } ! 1320: ! 1321: /* rshift -- right shift the screen to account for insert character */ ! 1322: ! 1323: rshift (line,col,x) ! 1324: int line; /* effected line */ ! 1325: int col; /* column to start in */ ! 1326: register int x; /* displaced character that goes in col */ ! 1327: { ! 1328: /* Keywords: character-output the-screen-map insertion */ ! 1329: ! 1330: int y; ! 1331: int jnk; ! 1332: register char *stop; ! 1333: register char *lp; ! 1334: ! 1335: lp = cmap[line]; ! 1336: jnk = scrjnk[line]; ! 1337: if (jnk <=SCRWID) lp[jnk] = 0; ! 1338: ! 1339: stop = lp+SCRWID; ! 1340: lp += col; ! 1341: ! 1342: while (x && (lp<= stop)) { ! 1343: y = *lp; ! 1344: *lp++ = x; ! 1345: x = y; ! 1346: } ! 1347: if (IN) { ! 1348: y = lp - cmap[line]; ! 1349: if (y > jnk) jnk = y; ! 1350: if (x) rshift(line+1,0,x); ! 1351: } else { ! 1352: if (jnk < SCRWID) jnk++; ! 1353: } ! 1354: scrjnk[line] = jnk; ! 1355: return(jnk); ! 1356: #endif ! 1357: } ! 1358: ! 1359: /* put a "logical line" of characters on the screen at the current position */ ! 1360: ! 1361: /* NOTE: This is not very clean, but seems necessary to handle all of the ! 1362: * various strange possibilities for displaying characters. We must ! 1363: * process a line at a time in order to handle things like ! 1364: * underscoring, by which multiple characters map to a single ! 1365: * display position. The general principals here are: that there ! 1366: * two ways of calling it, one with a C string to be printed, and ! 1367: * one with a buffer string to be printed. C strings end in nulls, ! 1368: * and cause a special character to be mapped to embedded newlines. ! 1369: * Buffer strings end in newlines, and map normally. Underscoring ! 1370: * is inidicated by the presence of the meta (0200) bit on ! 1371: * characters in the display map, so that mapping is done here. To ! 1372: * do this, a whole line is buffered for cput. Underscoring will ! 1373: * work fine so long as the underscores are done one at a time, or ! 1374: * the underscores don't wrap lines. Control and meta characters ! 1375: * map to their special emacs equivalents. ! 1376: */ ! 1377: ! 1378: ! 1379: xputl(cp,flg,col) ! 1380: ! 1381: register char *cp; /* string pointer */ ! 1382: int flg; /* disposition flag */ ! 1383: int col; ! 1384: ! 1385: /* Keywords: character-output the-screen-map:20 screen-handling conversions:50 underlining:20 the-screen-cursor:10 ^-and-M-processing:40 */ ! 1386: ! 1387: { ! 1388: char cbuf[256]; /* line buffer */ ! 1389: register int i; ! 1390: register int b; ! 1391: int mb; ! 1392: int a; ! 1393: ! 1394: mb = b = mcol; /* buffer pointer */ ! 1395: ! 1396: while (1) { ! 1397: if (b > mb) mb = b; ! 1398: if (b > SCRWID) { ! 1399: ! 1400: /* Line has wrapped. Put a ! on the end, and wrap anything that is left ! 1401: * over to the next line */ ! 1402: ! 1403: i = cbuf[SCRWID]; ! 1404: a = cbuf[SCRWID+1]; ! 1405: ! 1406: /* i is the character overwritten by the !, a is the character */ ! 1407: /* overwritten by the EOM in cflush */ ! 1408: ! 1409: if (mline>=SCRNLIN-1) { ! 1410: ! 1411: /* Wrap from last line on screen, fold back up and don't write in ! 1412: * the last position! */ ! 1413: cflush(cbuf,SCRWID); ! 1414: mline--; /* don't run overboard */ ! 1415: } else { ! 1416: cbuf[SCRWID]='!'; ! 1417: cflush(cbuf,SCRWID+1); ! 1418: if (flg && PICMODE) { ! 1419: if (col>0) hrem = 1+column-col; ! 1420: return; ! 1421: } ! 1422: mline++; ! 1423: scrmap[mline] = scrow+SCRCNL; /* mark continuation */ ! 1424: } ! 1425: mcol = 0; ! 1426: b = 0; ! 1427: while(b < LNOMOD*LNOWID) cbuf[b++] = ' '; ! 1428: cbuf[b++] = i; ! 1429: i = SCRWID+2; ! 1430: if (SCRWID+1<mb) cbuf[b++] = a; ! 1431: while (i < mb) { ! 1432: cbuf[b++] = cbuf[i++]; ! 1433: } ! 1434: mb = b; /* RESET */ ! 1435: } ! 1436: ! 1437: /* Process Next character */ ! 1438: ! 1439: i = (*cp++)&0377; /* next char */ ! 1440: ! 1441: if (flg) { /* if buffer invocation */ ! 1442: if (col++ == column) { ! 1443: nln = mline; ! 1444: ncol = b; ! 1445: } ! 1446: if (i == EOL) { ! 1447: cflush(cbuf,mb); ! 1448: return; /* done */ ! 1449: } ! 1450: } else { ! 1451: if (i == 0) { ! 1452: cflush(cbuf,mb); ! 1453: return; /* done */ ! 1454: } ! 1455: if (i == NEWLINE) { /* embedded newline */ ! 1456: cflush(cbuf,b); ! 1457: clrl(); ! 1458: mb = b = 0; ! 1459: if (mline < SCRNLIN) mline++; /* don't overflow */ ! 1460: scrmap[mline] = 0; ! 1461: mcol = 0; ! 1462: continue; /* re-loop */ ! 1463: } ! 1464: } ! 1465: ! 1466: if ((i & META)&& (bit8== 0)) { ! 1467: cbuf[b++] ='M'; ! 1468: cbuf[b++] = '-'; ! 1469: if (b>mb) mb=b; ! 1470: i-= META; ! 1471: } ! 1472: reswitch: switch(ctype[i&0177]) { ! 1473: case UL: ! 1474: if (ULINE) i = 0200; /* terminal underlines */ ! 1475: ! 1476: /* else just a plain old character */ ! 1477: ! 1478: case PLAIN: ! 1479: if ((b < mb) && ((i & 0200) || (cbuf[b] & 0200))){ ! 1480: i |= cbuf[b]; /* overstrike */ ! 1481: } ! 1482: cbuf[b++] = i; ! 1483: break; ! 1484: ! 1485: case BACKSP: ! 1486: if (b>mcol) b--; ! 1487: break; ! 1488: ! 1489: /*Fall through to handle backspace in normal mode */ ! 1490: ! 1491: case CONTRL: ! 1492: ! 1493: cbuf[b++] = '^'; ! 1494: i = i^0100; ! 1495: goto reswitch; /* Handle things like ^_ correctly! */ ! 1496: case TAB: ! 1497: i = TABSTOP-((b-(LNOMOD*LNOWID))%TABSTOP); ! 1498: while (i--) { ! 1499: cbuf[b++] = ' '; ! 1500: } ! 1501: break; ! 1502: } ! 1503: } ! 1504: } ! 1505: ! 1506: /* cput -- put a character in the file, like xputl */ ! 1507: ! 1508: ! 1509: cput(c) ! 1510: register int c; ! 1511: /* Keywords: insertion help-messages ^-and-M-processing */ ! 1512: { ! 1513: c &= 0377; ! 1514: if (c & META) { ! 1515: put('M'); ! 1516: put('-'); ! 1517: c-= META; ! 1518: } ! 1519: switch(ctype[c]) { ! 1520: ! 1521: case UL: ! 1522: case PLAIN: ! 1523: put(c); ! 1524: break; ! 1525: default: ! 1526: put('^'); ! 1527: put(c^0100); ! 1528: break; ! 1529: } ! 1530: } ! 1531: ! 1532: ! 1533: ! 1534: /* clear the rest of the line, checking to see if the line previously ! 1535: * displayed corresponds to the one displayed here now */ ! 1536: ! 1537: clrl() ! 1538: /* Keywords: prompting:10 display-format:20 informational-displays:30 screen-lines clearing */ ! 1539: { ! 1540: register int x; ! 1541: register int y; ! 1542: register int z; ! 1543: char *xln; ! 1544: int xcol; ! 1545: #ifdef PC ! 1546: char buf[130]; ! 1547: #endif ! 1548: x = mline; ! 1549: z = mcol; ! 1550: y = scrjnk[mline] - mcol; ! 1551: if (y > 0) { ! 1552: #ifdef PC ! 1553: buf[y]=0; ! 1554: for (x = 0; x < y; x++) buf[x] = ' '; ! 1555: x = mline; ! 1556: vout(mline,mcol,buf); ! 1557: #else ! 1558: sgo(mline,mcol); /* go for real */ ! 1559: if (CLINE) { ! 1560: PUTS(CLINE); ! 1561: } else { ! 1562: xln = cmap[mline]; ! 1563: xcol = mcol; ! 1564: while (y--) { ! 1565: if (xln[xcol] && xln[xcol] != ' ') { ! 1566: sgo(mline,xcol); ! 1567: putchar(' '); /* wipe line */ ! 1568: if ((scrcol++ >= REALWID) && SCRWRAP) { ! 1569: scrlin++; ! 1570: scrcol=0; ! 1571: } ! 1572: } ! 1573: xcol++; ! 1574: } ! 1575: } ! 1576: #endif ! 1577: scrjnk[x] = z; ! 1578: } ! 1579: } ! 1580: ! 1581: /* findline -- find a line on the screen */ ! 1582: ! 1583: /* findline makes no judgement as to whether or not the line is correct */ ! 1584: /* whether or not the screen is OK up to the line */ ! 1585: ! 1586: findline(line) ! 1587: register int line; ! 1588: ! 1589: /* Keywords: the-screen-cursor screen-lines screen-handling the-screen-map:10 */ ! 1590: ! 1591: { ! 1592: register int i; ! 1593: ! 1594: if (disbuf[cwind] == curbf) { ! 1595: for (i = wbase; i < SCRLINES; i++) { ! 1596: if (scrmap[i] == line) { ! 1597: nln = i; ! 1598: return(1); ! 1599: } ! 1600: } ! 1601: } ! 1602: return(0); ! 1603: } ! 1604: ! 1605: /* find the screen address of a file */ ! 1606: ! 1607: /* The result is to set mcol and mline and return 1 if found ! 1608: * found, otherwise 0 is returned */ ! 1609: ! 1610: ! 1611: findpos(line,col) ! 1612: ! 1613: register char *line; ! 1614: register int col; ! 1615: ! 1616: /* Keywords: the-screen-cursor ^-and-M-processing:50 screen-lines screen-handling the-screen-map:10 picture-mode:10 */ ! 1617: { ! 1618: register int i; ! 1619: char c; ! 1620: ! 1621: mcol = LNOMOD*LNOWID; ! 1622: i = 0; ! 1623: while (i < hcol) if (line[i++] == EOL) return(0); ! 1624: for (i = hcol; i < col; i++) { ! 1625: if ((c= line[i]) == EOL) return(0); ! 1626: if (c & META) mcol += metal; ! 1627: switch(ctype[c&0177]) { ! 1628: ! 1629: case PLAIN: ! 1630: case UL: ! 1631: mcol++; ! 1632: break; ! 1633: case BACKSP: ! 1634: if (mcol) mcol--; ! 1635: break; ! 1636: case CONTRL: ! 1637: mcol+=2; ! 1638: break; ! 1639: case TAB: ! 1640: mcol = mcol+TABSTOP-((mcol-(LNOMOD*LNOWID))%TABSTOP); ! 1641: break; ! 1642: } ! 1643: if (mcol>SCRWID) { ! 1644: if (PICMODE) { ! 1645: hrem = col-i; ! 1646: return(0); ! 1647: } ! 1648: if (++mline>SCRLINES) return(0); ! 1649: mcol = mcol-SCRWID; ! 1650: if (LNOMOD) mcol+= LNOWID; ! 1651: } ! 1652: } ! 1653: return(1); ! 1654: } ! 1655: ! 1656: /* The following function scans the text above "line" to compute ! 1657: * it's physical size. The scan continues until either hstop physical ! 1658: * screen lines are found or the line lstop is reached. The line at ! 1659: * which the scan stopped is returned, and the screen area is left ! 1660: * in the global "dsize" */ ! 1661: ! 1662: areal(line,hstop,lstop) ! 1663: /* Keywords: screen-lines display-update:30 screen-handling */ ! 1664: ! 1665: ! 1666: int line; ! 1667: int hstop; ! 1668: int lstop; ! 1669: ! 1670: { ! 1671: register char *lp; ! 1672: register int col; ! 1673: register int c; ! 1674: ! 1675: dsize = 0; ! 1676: while ((line > lstop) && (dsize < hstop)) { ! 1677: --line; ! 1678: dsize++; ! 1679: if (PICMODE) continue; /* Picture mode gets one line/line */ ! 1680: ! 1681: lp = mkline(line); ! 1682: col = LNOMOD*LNOWID; ! 1683: while ((c = *lp++) != EOL) { ! 1684: if (c & META) col += metal; ! 1685: switch(ctype[c&0177]) { ! 1686: ! 1687: case PLAIN: ! 1688: case UL: ! 1689: col++; ! 1690: break; ! 1691: case BACKSP: ! 1692: if (col) col--; ! 1693: break; ! 1694: case CONTRL: ! 1695: col+=2; ! 1696: break; ! 1697: case TAB: ! 1698: col = col+TABSTOP-((col-(LNOMOD*LNOWID))%TABSTOP); ! 1699: break; ! 1700: } ! 1701: if (col>SCRWID) { ! 1702: dsize++; ! 1703: col = col-SCRWID; ! 1704: if (LNOMOD) col+= LNOWID; ! 1705: } ! 1706: } ! 1707: } ! 1708: return(line); ! 1709: } ! 1710: ! 1711: /* print a line number(x) */ ! 1712: ! 1713: lnumb(x) ! 1714: ! 1715: /* Keywords: line-numbers informational-displays screen-handling */ ! 1716: { ! 1717: register int i; ! 1718: char tbuf[8]; ! 1719: ! 1720: for (i=0; i<8; i++) tbuf[i]=0; ! 1721: seprintf(tbuf,"%d",x); ! 1722: mcol = 0; /* make sure were at start of line */ ! 1723: ! 1724: for (i=0; i<LNOWID; i++) { ! 1725: if (tbuf[i] == 0) tbuf[i] = ' '; ! 1726: } ! 1727: cflush(tbuf,LNOWID); /* output to terminal */ ! 1728: } ! 1729: /* putin -- insert string into file */ ! 1730: ! 1731: ! 1732: putin(xp) ! 1733: ! 1734: register char *xp; ! 1735: ! 1736: /* Keywords: informational-displays help-messages:50 error-messages:50 screen-handling */ ! 1737: { ! 1738: register int c; ! 1739: RARE = 1; ! 1740: while (c = *xp++) { ! 1741: if (c == NEWLINE) { /* Note that NEWLINE != '\n' */ ! 1742: nl(1); ! 1743: put(' '); ! 1744: } ! 1745: else put(c); ! 1746: } ! 1747: RARE = 0; ! 1748: } ! 1749: ! 1750: /* dspage -- re-position display with (line) first. If */ ! 1751: /* the move argument is non-zero, the cursor is moved into the middle */ ! 1752: /* of the new display */ ! 1753: ! 1754: dspage(line,moves) ! 1755: int line; ! 1756: int moves; ! 1757: ! 1758: /* Keywords: commands display-update:30 the-screen-cursor scrolling */ ! 1759: { ! 1760: if (line<1) { ! 1761: if (minln > 1) line=1; ! 1762: else { ! 1763: beep(); ! 1764: return(0); ! 1765: } ! 1766: } ! 1767: if (line > nlines) { ! 1768: if (maxln < nlines) line = nlines; ! 1769: else { ! 1770: beep(); ! 1771: return(0); ! 1772: } ! 1773: } ! 1774: fclear(); /* just blew up file */ ! 1775: if (disbuf[cwind] != curbf) { ! 1776: ! 1777: /* NOTE: This is a pain! display is out of date because we were ! 1778: * called from a macro, If we don't do something here, disup will pick ! 1779: * a new window when we change buffers. What we do is not very ! 1780: * good, but it works? ! 1781: */ ! 1782: ! 1783: if (junked || ((twowind == 0) && (CLINE == 0))) { ! 1784: clear(); /* dumb terminal or command */ ! 1785: } else { ! 1786: xclear(); /* others, just clobber map */ ! 1787: } ! 1788: disbuf[cwind] = curbf; /* avoid reset in disup */ ! 1789: } ! 1790: minln = line; ! 1791: maxln = line+SCRLINES-wbase; /* This is just a guess, but should make it to disup all right. */ ! 1792: if (maxln > nlines) maxln = nlines; ! 1793: if (moves) move((minln+maxln)/2,0); ! 1794: return(0); ! 1795: } ! 1796: /* nxtpag -- move to next page */ ! 1797: ! 1798: nxtpage(count) ! 1799: ! 1800: register int count; ! 1801: ! 1802: /* Keywords: display-update:20 the-screen-cursor:30 movement commands forwards paging */ ! 1803: ! 1804: { ! 1805: ! 1806: return(dspage((maxln+1+((count-1)*(SCRLINES-wbase)))-keepg,1)); ! 1807: } ! 1808: ! 1809: /* move to top of page (current line becomes first line) */ ! 1810: ! 1811: toppage() ! 1812: ! 1813: /* Keywords: display-update:20 the-screen-cursor:30 movement scrolling commands backwards */ ! 1814: { ! 1815: dspage(curln,0); ! 1816: } ! 1817: ! 1818: /* move to previous page */ ! 1819: ! 1820: lstpage(count) ! 1821: ! 1822: register int count; ! 1823: ! 1824: /* Keywords: display-update:20 the-screen-cursor:30 movement commands backwards upward-movement:50 paging */ ! 1825: { ! 1826: return(dspage((minln-count*(SCRLINES-wbase))+keepg,1)); ! 1827: } ! 1828: ! 1829: clear() ! 1830: /* Keywords: clearing screen-handling the-screen-map:40 terminal-parameters:20 terminal-initialization:30 */ ! 1831: { ! 1832: register int i; ! 1833: #ifdef PC ! 1834: ! 1835: video(REG(SCRL_UP,0),REG(NORMATB,0),0,REG(SCRNLIN,SCRWID)); ! 1836: #else ! 1837: PUTS(CLEAR); ! 1838: #endif ! 1839: for (i = 0; i < SCRNLIN; i++) scrmap[i] = scrjnk[i] = 0; ! 1840: scrlin = scrcol = mline = mcol = 0; ! 1841: disbuf[0]=disbuf[1]= -1; ! 1842: junked = minln = maxln = 0; ! 1843: if (timemd) disptime = 1; /* Wiped out time display */ ! 1844: } ! 1845: ! 1846: ! 1847: /* didle (display idle) update display and idle for the specified time */ ! 1848: ! 1849: didle(count) ! 1850: ! 1851: int count; ! 1852: { ! 1853: /* Keywords: macro-programming display-update:10 time-processing:20 screen-handling */ ! 1854: ! 1855: if (count > 100) count = 100; /* limit to 10 seconds */ ! 1856: pushin(NULL); /* make sure we will update */ ! 1857: disup(); ! 1858: mflush(stdout); ! 1859: #ifndef PC ! 1860: while (count--) PUTS (WAIT1); ! 1861: #endif ! 1862: inpop(); ! 1863: } ! 1864: ! 1865: /* disup() update display. disup should be called whenever you want the */ ! 1866: /* to be up to date. disup does not update if there is more input */ ! 1867: /* available from the current input source. */ ! 1868: ! 1869: /* This is the high level display algorithm, which translates the ! 1870: * buffer into a screen image. The pparameters affecting the algorithm are ! 1871: * ! 1872: * scrmap[SCRNLIN] map from the display line to the file line on ! 1873: * that line of the display. ! 1874: * fmap[SCRNLIN] map from the file indicating what the smallest ! 1875: * column in the file containing undisplayed changes ! 1876: * is. A special value (LGOOD) indicates that ! 1877: * the whole line is good. This avoids looking at ! 1878: * the lines in the file that are known to be ok. ! 1879: * minln The file line appearing at the top of the current ! 1880: * window. ! 1881: * maxln The last file line appearing in this window. ! 1882: * lastln The screen line on which maxln is displayed. ! 1883: * curbf[2] The buffer displayed in each window. ! 1884: * dahead Flag indicating that we are displaying the line ! 1885: * with the cursor ahead of schedule. ! 1886: * ! 1887: * The basic algorithm is to firsst check to see if the window is properly ! 1888: * positioned to hold the cursor. If not, a new window is chosen and minln ! 1889: * reset. Then, each line that should be displayed is examined for ! 1890: * changes. Any lines needing updating are redisplay. A side effect of ! 1891: * the scan is to find the screen address of the current line. If the ! 1892: * screen address is found, the mode line and window splitting line are ! 1893: * updated (if necessary), and any other lines are blanked. If the cursor ! 1894: * wasn't found, it tries once again to display starting with the current ! 1895: * line. This can happen only if the line before the current line or the ! 1896: * current line is gigantic, wrapping lots of times around the screen. ! 1897: * Repeated failures signal a fatal error and indicate a bug or an ! 1898: * enormous current line. ! 1899: */ ! 1900: ! 1901: /* status display */ ! 1902: ! 1903: char mdchar[2] = {'=', '>'}; ! 1904: ! 1905: ! 1906: disup() /* force update display */ ! 1907: ! 1908: { ! 1909: ! 1910: /* Keywords: clearing:5 screen-handling display-update scrolling:10 insertion:10 deletion:10 */ ! 1911: ! 1912: /* Keywords: lookahead:20 the-screen-cursor:20 the-screen-map:20 screen-lines:10 mode-line:20 macro-hooks:10 */ ! 1913: register int col; ! 1914: int fixed; ! 1915: register char *cp; ! 1916: long pm; ! 1917: int *fmp; ! 1918: int dahead; ! 1919: char pmbuf[10]; ! 1920: char hcbuf[10]; ! 1921: char smap[NSCRLIN]; ! 1922: int smapped; ! 1923: ! 1924: if (MOREIN) return; ! 1925: fixed = smapped = 0 ; ! 1926: dahead = 0; ! 1927: nln = ncol = hrem = -1; ! 1928: ! 1929: /* Check to see if what is on the screen is from the same buffer. If ! 1930: * not, don't try to re-use it ! 1931: */ ! 1932: if (disbuf[cwind] != curbf) { ! 1933: minln = 0; /* force repositioning */ ! 1934: if (CLINE || twowind) { ! 1935: xclear(); /* force redisplay */ ! 1936: } else { ! 1937: clear(); /* try to optimize dumb terminal */ ! 1938: } ! 1939: disbuf[cwind] = curbf; /* mark buffer up to date */ ! 1940: } ! 1941: ! 1942: /* See if the current line is on the screen. The check is not absolutely ! 1943: * perfect. If the current line is not on the screen, a new position ! 1944: * is picked. Mis-guessing will be caught eventually. ! 1945: */ ! 1946: ! 1947: ! 1948: if ((minln == 0) ||(curln <minln) || ((curln> maxln) && (curln-maxln+lastln>=SCRLINES))) { ! 1949: ! 1950: /* display position is bad */ ! 1951: ! 1952: if (junked) { ! 1953: clear(); ! 1954: disbuf[cwind] = curbf; /* mark buffer up to date */ ! 1955: } ! 1956: badpos: ! 1957: if (hrem>0) { ! 1958: hcol = hcol+4+(hrem-hrem%4); ! 1959: hrem = -1; ! 1960: fclear(); ! 1961: goto retry; ! 1962: } ! 1963: if(fixed++) { ! 1964: if (fixed > 2) error(FATAL,42); /* can't find cursor */ ! 1965: minln = curln; ! 1966: } else { ! 1967: minln = areal(curln,(SCRLINES-wbase)/2,1); ! 1968: } ! 1969: fclear(); /* file bad */ ! 1970: if (SCREG || LOPEN) { ! 1971: if ((minln > 1) && (minln < curln)) dahead = wbase+dsize; ! 1972: } ! 1973: maxln = curln; ! 1974: } ! 1975: ! 1976: if (column<hcol) { ! 1977: hcol = column-column%4; ! 1978: dispmod(); ! 1979: fclear(); ! 1980: } ! 1981: ! 1982: /* Now for the real work, check all of the lines. A line can be bad if ! 1983: * scrmap indicates that its not in the right place on the display ! 1984: * or if fmap indicates that it may have changed since being put up. ! 1985: */ ! 1986: ! 1987: retry: fmp = &fmap[-minln]; ! 1988: mcol = 0; ! 1989: for (scrow = minln, mline = wbase; (scrow <= nlines) && (mline < SCRLINES);scrow++) { ! 1990: if (scrmap[mline] != scrow) { ! 1991: ! 1992: /* line is bad, first try to bring it into position by scrolling or by ! 1993: * inserting/deleting lines. This could result in the display being ! 1994: * corrected. ! 1995: */ ! 1996: #ifndef PC ! 1997: if ((smapped == 0) && (LOPEN || (SSCROLL && (mline == 0)))) { ! 1998: ! 1999: ! 2000: /* There is some hope for scrolling, build the display map. */ ! 2001: /* We scan remaining screen lines for ones that may be of use. */ ! 2002: ! 2003: /* smap[line-minln] = screen line (if any) */ ! 2004: /* scrmap[line] = 0 if known to be useless */ ! 2005: ! 2006: register int x; ! 2007: ! 2008: for (x = 0; x < SCRLINES; x++) smap[x] = 0; ! 2009: smapped = scrow+SCRLINES-mline-1; ! 2010: for (x = mline+1; x < SCRLINES; x++) { ! 2011: col = scrmap[x]; ! 2012: if ((col & SCRCNL) == 0) { ! 2013: if ((col<scrow) || (col > smapped)) { ! 2014: scrmap[x] = 0; /* Useless */ ! 2015: } else { ! 2016: smap[col-minln] = x; ! 2017: } ! 2018: } ! 2019: } ! 2020: } ! 2021: ! 2022: /* try to scroll the screen up with newlines */ ! 2023: ! 2024: if ((mline == 0) && SSCROLL && (col=smap[scrow-minln])) { ! 2025: sscroll(col); ! 2026: smapped = 0; ! 2027: } else if(LOPEN) { ! 2028: ! 2029: /* try to adjust screen by ! 2030: * opening and closing lines */ ! 2031: ! 2032: if (col=smap[scrow-minln]) { ! 2033: vadjust(mline-col,mline); ! 2034: smapped = 0; ! 2035: } else if (((col=scrmap[mline]&SCRMSK)>scrow) && (col <= nlines)) { ! 2036: smapped = areal(col,SCRLINES-mline,scrow); ! 2037: vadjust(dsize,mline); ! 2038: smapped = 0; ! 2039: } ! 2040: } ! 2041: ! 2042: #endif ! 2043: goto fixline; ! 2044: } ! 2045: if (fmp[scrow] < LGOOD) { ! 2046: ! 2047: fixline: ! 2048: ! 2049: /* Check for display-ahead. If we are on the first line, jump ahead ! 2050: * to the current line and show it first, being careful to return ! 2051: * when appropriate */ ! 2052: ! 2053: ! 2054: if (dahead>0) { ! 2055: ! 2056: /* Pick line for display ahead. Note that in some cases, the ! 2057: * current line is on the screen, in which case we just use it. If ! 2058: * not, we try the middle of the screen. If this is marked as ! 2059: * belonging to some other line, we just ignore dahead. */ ! 2060: ! 2061: if (findline(curln)) mline = nln; ! 2062: else { ! 2063: if (scrmap[dahead]) { ! 2064: dahead = 0; ! 2065: goto disline; ! 2066: } ! 2067: if ((scrmap[dahead-1]&SCRMSK) != curln-1) { ! 2068: mgo(dahead-1,0); ! 2069: scrmap[mline]=0; ! 2070: clrl(); ! 2071: } ! 2072: if ((scrmap[dahead+1]&SCRMSK) != curln+1) { ! 2073: mgo(dahead+1,0); ! 2074: scrmap[mline]=0; ! 2075: clrl(); ! 2076: } ! 2077: mline = dahead; ! 2078: } ! 2079: dahead = -1; ! 2080: scrow = curln; ! 2081: } ! 2082: disline: ! 2083: ! 2084: /* Now fix the display of this line. fmap indicates where we start */ ! 2085: ! 2086: ! 2087: cp = mkline(scrow); ! 2088: if ((scrmap[mline] == scrow) && (col =fmp[scrow])) { ! 2089: if (col == LGOOD) goto skipit; ! 2090: if ((scrow == curln) && (col > column)) { ! 2091: col = column; ! 2092: ! 2093: } ! 2094: ! 2095: /* Note that if we have backspace mode on, then we can't start the ! 2096: * line in the middle, because the line may have backspaces that ! 2097: * span the cursor, or have had them in its previous form. The only ! 2098: * safe thing to do is re-format the whole thing and let cflush ! 2099: * throw most of it away. */ ! 2100: ! 2101: if ((col == 0) || BACKP) goto numbline; ! 2102: if (col<hcol) col=hcol; ! 2103: if (findpos(cp,col)==0) goto badpos; ! 2104: cp +=col; ! 2105: } else { ! 2106: scrmap[mline] = scrow; /* mark line */ ! 2107: numbline: if(LNOMOD) lnumb(scrow); ! 2108: col = 0; ! 2109: while (col < hcol) { ! 2110: if (*cp==EOL) break; ! 2111: cp++; ! 2112: col++; ! 2113: } ! 2114: } ! 2115: xputl(cp,1,((curln==scrow)?col:-1000)); /* process line */ ! 2116: clrl(); ! 2117: mline++; ! 2118: mcol = 0; ! 2119: fmp[scrow] = LGOOD; ! 2120: ! 2121: /* if we have NDELAY I/O available, see if there is any type ahead */ ! 2122: ! 2123: if (((int) _stdout._cnt *ttywarp) > PATIENCE) { ! 2124: ttfill(); /* try to fill tty buffer */ ! 2125: if (MOREIN) { ! 2126: clptr = mkline(curln); ! 2127: if (maxln < scrow) maxln = scrow; ! 2128: return; ! 2129: } ! 2130: } ! 2131: ! 2132: } else { ! 2133: ! 2134: /* line on the screen is OK, see if the current cursor position is in it */ ! 2135: ! 2136: ! 2137: skipit: if (scrow == curln) { ! 2138: cp = mkline(curln); ! 2139: if (findpos(cp,column)) { ! 2140: nln = mline; ! 2141: ncol = mcol; ! 2142: } else { ! 2143: goto badpos; ! 2144: } ! 2145: } ! 2146: mline++; ! 2147: while ((scrmap[mline]) == (scrow|SCRCNL)) mline++; ! 2148: mcol = 0; ! 2149: } ! 2150: if (dahead<0) { ! 2151: dahead = 0; ! 2152: nln = -1; /* Make sure we find this line later */ ! 2153: mline = wbase; ! 2154: scrow = minln; ! 2155: goto disline; /* If displaying ahead, return to finish display */ ! 2156: } ! 2157: /* done re-creating the display, now clean up the rest of the lines */ ! 2158: ! 2159: } ! 2160: maxln = scrow-1; /* last line on the screen */ ! 2161: wminln[cwind] = minln; ! 2162: wmaxln[cwind] = maxln; ! 2163: lastln = mline-1; /* last display line used */ ! 2164: ! 2165: if (twowind && (mline == SCRLINES) && (cwind == 0)) { ! 2166: prompt(mline,endput); ! 2167: scrmap[mline]=0; ! 2168: } ! 2169: if ((scrow > nlines) || (mline == SCRLINES)) { ! 2170: while (mline < SCRLINES+1) { ! 2171: if ((twowind == 0) || (mline < SCRLINES) || cwind) { ! 2172: if (scrjnk[mline])clrl(); ! 2173: scrmap[mline++]=0; ! 2174: } else mline++; ! 2175: } ! 2176: } ! 2177: if (nln < 0) { ! 2178: goto badpos; /* oops, blew it agaiin */ ! 2179: } ! 2180: if ((scrmap[MODLN] != MODHACK)||PMODE) { ! 2181: ! 2182: /* Pre-format sections for display-percent mode and horizontal scrolling */ ! 2183: ! 2184: if (hcol) { ! 2185: seprintf(hcbuf,"<%d ",hcol); ! 2186: } else hcbuf[0] = 0; ! 2187: if (PMODE) { ! 2188: pm = (nlines == 1)?1:nlines-1; ! 2189: pm = (100L*((long) curln-1))/pm; ! 2190: seprintf (pmbuf," %D%%",pm); ! 2191: } else pmbuf[0] = 0; ! 2192: if (hooks[Mode_Line_Hook]) { ! 2193: hook(Mode_Line_Hook); ! 2194: retrvs(fnbuf,FNLEN); ! 2195: prompt(MODLN,"%s",fnbuf); ! 2196: } else { ! 2197: ! 2198: prompt(MODLN,"%s%s %s (%d) %s %c %s%s",hcbuf,myname,version,bfnumb(),bname(),mdchar[modded()], fname(),pmbuf); ! 2199: } ! 2200: if (lgripe && (infrn == 0)) { ! 2201: prompt(ECHOL,"I can only use %d lines by %d columns of your screen",SCRNLIN,SCRWID+1); ! 2202: lgripe = 0; ! 2203: } ! 2204: scrmap[MODLN] = MODHACK; ! 2205: if (twowind) { ! 2206: col = w1base-1; ! 2207: prompt(col,endput); ! 2208: scrmap[col] = 0; /* SPPML */ ! 2209: } ! 2210: mgo(nln,ncol); /* Restore cursor */ ! 2211: } ! 2212: clptr = mkline(curln); /* make sure we get this one */ ! 2213: mgo(nln,ncol); ! 2214: } ! 2215: ! 2216: /* Initialize screen size */ ! 2217: ! 2218: setsize() ! 2219: /* Keywords: modes:50 screen-handling display-format terminal-initialization:10 */ ! 2220: { ! 2221: ! 2222: /* Set safe defaults for height and width, and set dependent parameters */ ! 2223: ! 2224: if (SCRNLIN<=4) SCRNLIN=5; ! 2225: if (SCRNLIN>NSCRLIN) { ! 2226: SCRNLIN=NSCRLIN; ! 2227: lgripe++; ! 2228: } ! 2229: if (SCRWID>NSCRCOL-1) { ! 2230: lgripe++; ! 2231: SCRWID=NSCRCOL-1; ! 2232: } ! 2233: if (SCRWID > REALWID) { ! 2234: lgripe++; ! 2235: SCRWID = REALWID; ! 2236: } ! 2237: SCRLINES=SCRNLIN-4; ! 2238: ECHOL = SCRNLIN-1; ! 2239: MODLN = SCRNLIN-3; ! 2240: } ! 2241: ! 2242: /* display the mode line */ ! 2243: ! 2244: dispmod() ! 2245: /* Keywords: mode-line */ ! 2246: { ! 2247: scrmap[MODLN] = 0; ! 2248: } ! 2249: ! 2250: ! 2251: ttype() /* set terminal type */ ! 2252: ! 2253: { ! 2254: /* Keywords: commands terminal-initialization terminal-modes:20 terminal-parameters:50 */ ! 2255: ! 2256: register char *mp; ! 2257: #ifndef PC ! 2258: mp = expenv(getname("Terminal Type? ")); ! 2259: if (mp == NULL) return; ! 2260: sttype(mp); ! 2261: #endif ! 2262: } ! 2263: #if defined(TERMCAP) || defined(TERMINFO) ! 2264: /* Like putchar but a function which can be passed to putpad */ ! 2265: pchar(c) ! 2266: { ! 2267: putchar(c); ! 2268: } ! 2269: /* ! 2270: * Print out string str with padding. ! 2271: */ ! 2272: putpad(str) ! 2273: char *str; ! 2274: { ! 2275: if (str) { ! 2276: tputs(str, SREGION, pchar); ! 2277: } ! 2278: } ! 2279: ! 2280: #endif ! 2281: #if defined(TERMINFO) ! 2282: ! 2283: sttype(mp) ! 2284: register char *mp; ! 2285: { ! 2286: #ifndef SINGLE ! 2287: extern struct term _first_term; /* statically allocated terminal structure */ ! 2288: #endif ! 2289: char tbuf[1024]; ! 2290: static char bufspace[512]; ! 2291: char *xp; ! 2292: char *pt = bufspace; ! 2293: int rc = 1; ! 2294: ! 2295: cur_term = 0; /* Force setupterm to use default */ ! 2296: if (mp == NULL) mp = dumbterm; ! 2297: setupterm(mp, 1, &rc); ! 2298: if (rc != 1) { ! 2299: if (mp == dumbterm) { ! 2300: write(1,"\n\r\n\rI Can't understand your terminal type\n\r",43); ! 2301: quit(); ! 2302: } ! 2303: cur_term = & _first_term; /* Restore terminal pointer */ ! 2304: IGNORE(error(WARN,86,mp,em_dir)); ! 2305: return; ! 2306: } ! 2307: UP = cursor_up; ! 2308: RELUP = parm_up_cursor; ! 2309: DOWN = cursor_down; ! 2310: if (DOWN == NULL) ! 2311: DOWN = "\n"; ! 2312: RELDOWN = parm_down_cursor; ! 2313: BACK = cursor_left; ! 2314: RELBACK = parm_left_cursor; ! 2315: FORWARD = cursor_right; ! 2316: RELFORW = parm_right_cursor; ! 2317: CLEAR = clear_screen; ! 2318: CLINE = clr_eol; ! 2319: BELL = bell; ! 2320: CURAD = cursor_address; ! 2321: NOP = pad_char; ! 2322: LOPEN = insert_line; ! 2323: CLOPEN = parm_insert_line; ! 2324: LDEL = delete_line; ! 2325: CLDEL = parm_delete_line; ! 2326: INSERTC = insert_character; ! 2327: INSERTM = enter_insert_mode; ! 2328: OSERTC = exit_insert_mode; ! 2329: INSERTP = insert_padding; ! 2330: IN = insert_null_glitch; ! 2331: /* ! 2332: DELMODE = enter_delete_mode; /* Note that DM is a flag in emacs * / ! 2333: */ ! 2334: DELC = delete_character; ! 2335: RSCROLL = scroll_reverse; ! 2336: SSCROLL = scroll_forward; ! 2337: CLSCROLL= parm_index; ! 2338: CRSCROLL= parm_rindex; ! 2339: if ((SSCROLL == NULL) && (!eat_newline_glitch)) SSCROLL = "\n"; ! 2340: SCREG = change_scroll_region; ! 2341: ! 2342: /* UNDERLINING */ ! 2343: ! 2344: if (transparent_underline) { ! 2345: ULINE = "%c_"; /* underline this way */ ! 2346: EOVER = erase_overstrike; ! 2347: } ! 2348: else if (underline_char) { ! 2349: /* underscore by magic word */ ! 2350: ULINE = pt; ! 2351: pt = strcpy(pt,"%c"); ! 2352: pt = strcpy(pt,underline_char); ! 2353: EOVER = !ceol_standout_glitch; ! 2354: pt++; ! 2355: } else if (xp = enter_underline_mode) { /* underscore mode */ ! 2356: ULINE=xp; ! 2357: UEND= exit_underline_mode; ! 2358: EOVER = !ceol_standout_glitch; ! 2359: } ! 2360: CR = carriage_return; ! 2361: SCINIT = enter_ca_mode; ! 2362: VEXIT = exit_ca_mode; ! 2363: MI = move_insert_mode; ! 2364: if ((CURAD == NULL) && (CURAD = cursor_mem_address)) SSCROLL=NULL; ! 2365: ! 2366: /* Use memory addressing and no scrolling if forced */ ! 2367: ! 2368: SCRWID = columns - 1; ! 2369: SCRNLIN = lines; ! 2370: SCRWRAP = auto_right_margin; ! 2371: #ifdef JWINSIZE ! 2372: ! 2373: /* ! 2374: * Courtesy of Mark Horton - CDB ! 2375: * ! 2376: * ioctls for Blit - you may need to #include <jioctl.h> ! 2377: * This ioctl defines the window size and overrides what ! 2378: * it says in the terminal description file. ! 2379: */ ! 2380: { ! 2381: struct jwinsize w; ! 2382: ! 2383: if (ioctl(1, JWINSIZE, &w) != -1) { ! 2384: SCRNLIN = w.bytesy; ! 2385: SCRWID = w.bytesx - 1; ! 2386: } ! 2387: } ! 2388: if (getenv ("LINES")) ! 2389: IGNORE (nscan (getenv ("LINES"), &SCRNLIN)); ! 2390: if (getenv ("COLUMNS")) ! 2391: { ! 2392: IGNORE (nscan (getenv ("COLUMNS"), &SCRWID)); ! 2393: SCRWID--; ! 2394: } ! 2395: ! 2396: #endif ! 2397: REALWID=SCRWID; ! 2398: REALBOT=SCRNLIN; ! 2399: setsize(); ! 2400: if (IN) BLANK= 0; ! 2401: else BLANK= ' '; ! 2402: if (VCOST == 0) VCOST = 1; ! 2403: if (CURAD) { ! 2404: acost = dcost(CURAD); ! 2405: } else { ! 2406: acost = dcost(RELUP)+dcost(RELFORW); ! 2407: } ! 2408: dccost = dcost(DELC); ! 2409: if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC); ! 2410: else iccost = dcost (INSERTC); ! 2411: lUP = dcost(UP); ! 2412: lDOWN = dcost(DOWN); ! 2413: lBAK = dcost(BACK); ! 2414: lCR = dcost(CR); ! 2415: if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */ ! 2416: if (ULINE) BACKP = 1; /* Set backspace mode if terminal underscores */ ! 2417: vinit(); ! 2418: TERMIQ = 0; /* Compute terminal's IQ */ ! 2419: if (CURAD) TERMIQ += 1; ! 2420: if (CLINE) TERMIQ += 2; ! 2421: if (LOPEN || SCREG) TERMIQ += 4; ! 2422: if (INSERTC || INSERTM) TERMIQ += 8; ! 2423: clear(); ! 2424: } ! 2425: ! 2426: /* for costing out terminfo capabilities */ ! 2427: static int TIcount; ! 2428: /*ARGSUSED*/ ! 2429: ! 2430: int TIcost(c) ! 2431: char c; ! 2432: { ! 2433: ++TIcount; ! 2434: } ! 2435: #else ! 2436: #ifdef TERMCAP ! 2437: ! 2438: char PC; ! 2439: char *BC; ! 2440: char *TE; ! 2441: ! 2442: sttype(mp) ! 2443: register char *mp; ! 2444: { ! 2445: char tbuf[1024]; ! 2446: static char bufspace[512]; ! 2447: char *xp; ! 2448: char *pt = bufspace; ! 2449: char *tgetstr(); ! 2450: if (mp == NULL) mp = dumbterm; ! 2451: if (tgetent(tbuf, mp) < 1) { ! 2452: if (mp == dumbterm) { ! 2453: write(1,"\n\r\n\rI Can't understand your terminal type\n\r",43); ! 2454: quit(); ! 2455: } ! 2456: IGNORE(error(WARN,86,mp,em_dir)); ! 2457: return; ! 2458: } ! 2459: UP = tgetstr("up", &pt); ! 2460: DOWN = tgetstr("do", &pt); ! 2461: if (DOWN == NULL) ! 2462: DOWN = "\n"; ! 2463: BACK = tgetstr("bc", &pt); ! 2464: if (BACK == NULL && tgetflag("bs")) ! 2465: BACK = "\b"; ! 2466: BC = BACK; ! 2467: FORWARD = tgetstr("nd", &pt); ! 2468: CLEAR = tgetstr("cl", &pt); ! 2469: CLINE = tgetstr("ce", &pt); ! 2470: BELL = "\7"; ! 2471: CURAD = tgetstr("cm", &pt); ! 2472: NOP = tgetstr("pc", &pt); ! 2473: if(NOP != NULL) PC = *NOP; ! 2474: LOPEN = tgetstr("al", &pt); ! 2475: CLOPEN = tgetstr("AL", &pt); ! 2476: LDEL = tgetstr("dl", &pt); ! 2477: CLDEL = tgetstr("DL", &pt); ! 2478: INSERTC = tgetstr("ic", &pt); ! 2479: INSERTM = tgetstr("im", &pt); ! 2480: OSERTC = tgetstr("ei", &pt); ! 2481: INSERTP = tgetstr("ip", &pt); ! 2482: IN = tgetflag("in", &pt); ! 2483: DELMODE = (tgetstr("dm", &pt)==NULL); /* Note that DM is a flag in emacs */ ! 2484: DELC = tgetstr("dc", &pt); ! 2485: RSCROLL = tgetstr("sr", &pt); ! 2486: SSCROLL = tgetstr("nl", &pt); ! 2487: CLSCROLL = tgetstr("SF", &pt); ! 2488: if (SSCROLL == NULL) SSCROLL = tgetstr("sf",&pt); ! 2489: if ((SSCROLL == NULL) && (tgetflag("xn")== NULL)) SSCROLL = "\n"; ! 2490: SCREG = tgetstr("cs", &pt); ! 2491: ! 2492: /* UNDERLINING */ ! 2493: ! 2494: if (tgetflag("ul")) { ! 2495: ULINE = "%c_"; /* underline this way */ ! 2496: EOVER = tgetflag("eo"); ! 2497: } ! 2498: else if (xp = tgetstr("uc",&pt)) { ! 2499: /* underscore by magic word */ ! 2500: ULINE = pt; ! 2501: pt = mstrcpy(pt,"%c"); ! 2502: pt = mstrcpy(pt,xp); ! 2503: EOVER = (tgetflag("xs") == 0); ! 2504: pt++; ! 2505: } else if (xp = tgetstr("us",&pt)) { /* underscore mode */ ! 2506: ULINE=xp; ! 2507: UEND= tgetstr("ue",&pt); ! 2508: EOVER = (tgetflag("xs") == 0); ! 2509: } ! 2510: CR = tgetstr("cr", &pt); ! 2511: if (CR == NULL) { ! 2512: if (tgetflag("nc") == 0) CR = "\015"; ! 2513: } ! 2514: SCINIT = tgetstr("ti", &pt); ! 2515: TE = tgetstr("up", &pt); ! 2516: MI = tgetflag("mi", &pt); ! 2517: SCRWID = tgetnum("co") - 1; ! 2518: SCRNLIN = tgetnum("li"); ! 2519: SCRWRAP = tgetflag("am"); ! 2520: #ifdef JWINSIZE ! 2521: ! 2522: /* ! 2523: * Courtesy of Mark Horton - CDB ! 2524: * ! 2525: * ioctls for Blit - you may need to #include <jioctl.h> ! 2526: * This ioctl defines the window size and overrides what ! 2527: * it says in the terminal description file. ! 2528: */ ! 2529: { ! 2530: struct jwinsize w; ! 2531: ! 2532: if (ioctl(1, JWINSIZE, &w) != -1) { ! 2533: SCRNLIN = w.bytesy; ! 2534: SCRWID = w.bytesx - 1; ! 2535: } ! 2536: } ! 2537: if (getenv ("LINES")) ! 2538: IGNORE (nscan (getenv ("LINES"), &SCRNLIN)); ! 2539: if (getenv ("COLUMNS")) ! 2540: { ! 2541: IGNORE (nscan (getenv ("COLUMNS"), &SCRWID)); ! 2542: SCRWID--; ! 2543: } ! 2544: ! 2545: #endif ! 2546: REALWID=SCRWID; ! 2547: REALBOT=SCRNLIN; ! 2548: setsize(); ! 2549: if (VCOST == 0) VCOST = 1; ! 2550: if (IN) BLANK= 0; ! 2551: else BLANK= ' '; ! 2552: if (CURAD) { ! 2553: acost = dcost(CURAD); ! 2554: } else { ! 2555: acost = dcost(RELUP)+dcost(RELFORW); ! 2556: } ! 2557: dccost = dcost(DELC); ! 2558: if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC); ! 2559: else iccost = dcost (INSERTC); ! 2560: lUP = dcost(UP); ! 2561: lDOWN = dcost(DOWN); ! 2562: lBAK = dcost(BACK); ! 2563: lCR = dcost(CR); ! 2564: if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */ ! 2565: if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */ ! 2566: if (ULINE) BACKP = 1; /* Set backspace mode if terminal underscores */ ! 2567: vinit(); /* Initialize screen */ ! 2568: ! 2569: TERMIQ = 0; /* Compute terminal's IQ */ ! 2570: if (CURAD) TERMIQ += 1; ! 2571: if (CLINE) TERMIQ += 2; ! 2572: if (LOPEN || SCREG) TERMIQ += 4; ! 2573: if (INSERTC || INSERTM) TERMIQ += 8; ! 2574: clear(); ! 2575: } ! 2576: #else ! 2577: #ifndef PC ! 2578: ! 2579: /* terminal description file parser: */ ! 2580: ! 2581: /* terminal description file contains lines with ! 2582: ! 2583: parameter=data ! 2584: ! 2585: * where data is either a number of a string */ ! 2586: ! 2587: ! 2588: ttyparse(mp) ! 2589: char *mp; ! 2590: ! 2591: /* Keywords: conversions:20 terminal-parameters terminal-initialization reading */ ! 2592: ! 2593: { ! 2594: register FILE *file; ! 2595: char xbuf[128]; ! 2596: FILE ttyfile[1]; ! 2597: #define OPTSIZE 256 ! 2598: char optbuf[OPTSIZE]; ! 2599: register char *cp; ! 2600: register int c; ! 2601: #ifdef PORTEXT ! 2602: int parmp; ! 2603: #else ! 2604: int *parmp; ! 2605: #endif ! 2606: int parm; ! 2607: ! 2608: ! 2609: /* find the terminal file and open it */ ! 2610: ! 2611: if (mp) { ! 2612: seprintf(xbuf,"%s/terminals/%s",em_dir,mp); /* terminal file */ ! 2613: file = xopen(ttyfile,xbuf,"r"); ! 2614: if (file == NULL) { ! 2615: file = xopen(ttyfile,mp,"r"); /* Try full pathname */ ! 2616: } ! 2617: if (file == NULL) { ! 2618: badterm: error (WARN,43,mp,em_dir); ! 2619: return(0); ! 2620: } ! 2621: } else { ! 2622: ! 2623: /* This code restores the terminal to a "sane" default */ ! 2624: ! 2625: file = ttyfile; ! 2626: ttyfile[0]._frn = open("/dev/null",0); ! 2627: ttyfile[0]._cnt = lng(nulltty); ! 2628: ttyfile[0]._ptr = nulltty; ! 2629: } ! 2630: /* first find what option we are setting */ ! 2631: ! 2632: nextparm: cp = optbuf; ! 2633: while ((c = getc(file)) != '=') { ! 2634: if (c == '\n') goto nextparm; /* comment line */ ! 2635: if (c == EOF) { ! 2636: mclose(file); ! 2637: return(1); /* abort during option scan */ ! 2638: } ! 2639: if (cp-optbuf >= OPTSIZE) goto badterm; /* OOPS! */ ! 2640: *cp++=c; ! 2641: } ! 2642: *cp = 0; ! 2643: ! 2644: /* look up parameter in parameter table */ ! 2645: ! 2646: #ifdef PORTEXT ! 2647: for (parmp = 0, cp = ttydata; *cp; parmp++,cp+=2) { ! 2648: #else ! 2649: for (parmp = ((int * )&UP), cp = ttydata; *cp; parmp++,cp+=2) { ! 2650: #endif ! 2651: if ((optbuf[0]==cp[0])&& (optbuf[1]==cp[1])) { ! 2652: ! 2653: c = getc(file); ! 2654: if ((c >= '0') && (c <= '9')) { ! 2655: parm = 0; ! 2656: while ((c >= '0') && (c <= '9')) { ! 2657: parm = 10*parm + (c-'0'); ! 2658: c = getc(file); ! 2659: } ! 2660: #ifdef PORTEXT ! 2661: *(parmptr[parmp]) = parm; ! 2662: #else ! 2663: *parmp = parm; ! 2664: #endif ! 2665: if (c != EOF) goto nextparm; ! 2666: mclose(file); ! 2667: return(1); ! 2668: } ! 2669: #ifdef PORTEXT ! 2670: *(parmptr[parmp]) = ((int) &ttystrings[ttyptr]); ! 2671: #else ! 2672: *parmp = ((int) &ttystrings[ttyptr]); ! 2673: #endif ! 2674: while ((c != EOF) && (c != EOL)) { ! 2675: if (c == '\\') { ! 2676: c = getc(file); ! 2677: if (c == 'n') c = '\n'; ! 2678: } ! 2679: ! 2680: ttystrings[ttyptr++] = c; ! 2681: c = getc(file); ! 2682: } ! 2683: ttystrings[ttyptr++] = 0; ! 2684: if (c != EOF) goto nextparm; ! 2685: } ! 2686: } ! 2687: /* error(WARN,68,optbuf); Don't complain about non-existent capabilities */ ! 2688: ! 2689: goto nextparm; ! 2690: } ! 2691: #endif ! 2692: sttype(mp) ! 2693: register char *mp; ! 2694: ! 2695: /* Keywords: terminal-parameters terminal-initialization terminal-modes:20 string-handling:20 statistics:10 */ ! 2696: ! 2697: ! 2698: ! 2699: { ! 2700: #ifdef PORTEXT ! 2701: int parmp; ! 2702: #else ! 2703: int *parmp; ! 2704: #endif ! 2705: /* First, initialize the tty data */ ! 2706: ! 2707: ttyptr = 0; ! 2708: #ifdef PORTEXT ! 2709: for (parmp = 0; parmptr[parmp]; parmp++) { ! 2710: *(parmptr[parmp])=0; ! 2711: } ! 2712: #else ! 2713: for (parmp = ( (int *) &UP); parmp <= &DELMODE; parmp++) { ! 2714: *parmp=0; ! 2715: } ! 2716: #endif ! 2717: #ifdef PC ! 2718: ! 2719: SCRWID = 79; ! 2720: SCRNLIN = 24; ! 2721: ECHOL = 23; ! 2722: MODLN = 21; ! 2723: SCRLINES = 20; ! 2724: CLINE = ""; ! 2725: clear(); ! 2726: #else ! 2727: if (ttyparse(mp)) { ! 2728: ! 2729: #ifdef JWINSIZE ! 2730: ! 2731: /* ! 2732: * Courtesy of Mark Horton - CDB ! 2733: * ! 2734: * ioctls for Blit - you may need to #include <jioctl.h> ! 2735: * This ioctl defines the window size and overrides what ! 2736: * it says in the terminal description file. ! 2737: */ ! 2738: { ! 2739: struct jwinsize w; ! 2740: ! 2741: if (ioctl(1, JWINSIZE, &w) != -1) { ! 2742: SCRNLIN = w.bytesy; ! 2743: SCRWID = w.bytesx; ! 2744: } ! 2745: } ! 2746: /* ! 2747: if (getenv ("LINES")) ! 2748: IGNORE (nscan (getenv ("LINES"), &SCRNLIN)); ! 2749: if (getenv ("COLUMNS")) ! 2750: { ! 2751: IGNORE (nscan (getenv ("COLUMNS"), &SCRWID)); ! 2752: } ! 2753: */ ! 2754: #endif ! 2755: SCRWID--; ! 2756: REALWID=SCRWID; ! 2757: REALBOT=SCRNLIN; ! 2758: setsize(); ! 2759: if (IN) BLANK= 0; ! 2760: else BLANK= ' '; ! 2761: if (VCOST == 0) VCOST = 1; ! 2762: if (CURAD) { ! 2763: acost = dcost(CURAD); ! 2764: } else { ! 2765: acost = dcost(RELUP)+dcost(RELFORW); ! 2766: } ! 2767: dccost = dcost(DELC); ! 2768: if (INSERTM) iccost = dcost(INSERTM)+dcost(OSERTC); ! 2769: if (INSERTM) iccost = 1; ! 2770: else iccost = dcost (INSERTC); ! 2771: ! 2772: lUP = dcost(UP); ! 2773: lDOWN = dcost(DOWN); ! 2774: lBAK = dcost(BACK); ! 2775: lCR = dcost(CR); ! 2776: if (ULINE) BACKP = 1; /* Set backspace mode if terminal underscores */ ! 2777: if (OSERTC && (INSERTM == 0)) { ! 2778: INSERTM=INSERTC; /* old style insert modes */ ! 2779: INSERTC=0; ! 2780: } ! 2781: if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */ ! 2782: if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */ ! 2783: vinit(); ! 2784: TERMIQ = 0; /* Compute terminal's IQ */ ! 2785: if (CURAD) TERMIQ += 1; ! 2786: if (CLINE) TERMIQ += 2; ! 2787: if (LOPEN || SCREG) TERMIQ += 4; ! 2788: if (INSERTC || INSERTM) TERMIQ += 8; ! 2789: ! 2790: clear(); ! 2791: } ! 2792: #endif ! 2793: } ! 2794: #endif ! 2795: #endif ! 2796: #ifndef PC ! 2797: /* dcost -- calculate display cost of a string */ ! 2798: ! 2799: dcost(sp) ! 2800: register char *sp; ! 2801: { ! 2802: /* Keywords: terminal-parameters terminal-initialization */ ! 2803: register int dc; ! 2804: char dcbuf[512]; /* buffer for string */ ! 2805: ! 2806: if (sp == NULL) return(1000); /* infinite cost for missing capability */ ! 2807: #ifdef TERMINFO ! 2808: TIcount=0; ! 2809: tputs(tparm(sp,10,10),10,TIcost); ! 2810: return(TIcount); ! 2811: #else ! 2812: #ifdef TERMCAP ! 2813: dc = 0; ! 2814: while (*sp) { ! 2815: if (*sp++ != '%') dc++; ! 2816: } ! 2817: return(dc); ! 2818: #else ! 2819: seprintf(dcbuf,sp,10,10); /* expand a 'typical' example */ ! 2820: return(lng(dcbuf)); /* return its length */ ! 2821: #endif ! 2822: #endif ! 2823: } ! 2824: #endif ! 2825: /* yes or no question */ ! 2826: /*VARARGS1*/ ! 2827: int ! 2828: gyn(string,arg1) ! 2829: ! 2830: char *string; ! 2831: char *arg1; ! 2832: { ! 2833: /* Keywords: prompting user-interface yes-no-questions */ ! 2834: ! 2835: register char c; ! 2836: ! 2837: while (1) { ! 2838: prompt2(ECHOL,string,&arg1); ! 2839: sgo(mline,mcol); ! 2840: if (infrn < 0) { ! 2841: pushin(NULL); ! 2842: c = getchar(); ! 2843: inpop(); ! 2844: } else c = getchar(); ! 2845: donttime = 0; /* Re-enable time mode */ ! 2846: switch(c) { ! 2847: ! 2848: case 'y': ! 2849: case 'Y': ! 2850: case ' ': ! 2851: return(1); ! 2852: case CTRLZ: /* This is necessary to insure exit */ ! 2853: case 'n': ! 2854: case 'N': ! 2855: case RUBOUT: ! 2856: unprompt(); ! 2857: return(0); ! 2858: case CTRLG: ! 2859: unprompt(); ! 2860: return(-1); ! 2861: default: ! 2862: donttime = 1; /* Avoid time mode */ ! 2863: prompt3("y for yes, n for no, ^G to quit"); ! 2864: } ! 2865: } ! 2866: }; ! 2867: ! 2868: /* beep -- obvious */ ! 2869: ! 2870: beep() ! 2871: ! 2872: { ! 2873: ! 2874: /* Keywords: bell-ringing terminal-parameters:20 commands:20 error-messages:10 */ ! 2875: ! 2876: #ifdef PC ! 2877: ! 2878: if (!NOBEL) video(REG(WR_TTY,BELL),REG(PAGE_0,NORMATB),0,0); ! 2879: ! 2880: ! 2881: #else ! 2882: if (!NOBEL) PUTS(BELL); /* print a bell */ ! 2883: #endif ! 2884: } ! 2885: ! 2886: /* mtop -- move to top of display for message output */ ! 2887: ! 2888: mtop() ! 2889: { ! 2890: /* Keywords: the-screen-cursor informational-displays MORE-processing */ ! 2891: mgo(0,0); /* for messages */ ! 2892: } ! 2893: ! 2894: /* fclear -- declare the contents of the file invalid */ ! 2895: ! 2896: fclear() ! 2897: ! 2898: /* Keywords: screen-handling the-screen-map clearing terminal-initialization:20 */ ! 2899: ! 2900: { ! 2901: register int i; ! 2902: scrmap[MODLN] = 0; /* wipe out mode line */ ! 2903: for (i = 0; i < NSCRLIN; i++) fmap[i] = 0; ! 2904: } ! 2905: ! 2906: /* dclear-- cause screen to be cleared at next refresh */ ! 2907: ! 2908: dclear() ! 2909: { ! 2910: /* Keywords: screen-handling clearing break-handling:20 */ ! 2911: junked++; ! 2912: minln=0; ! 2913: } ! 2914: ! 2915: /* xclear -- declare the contents of the screen as junk */ ! 2916: ! 2917: ! 2918: xclear() ! 2919: { ! 2920: /* Keywords: screen-handling the-screen-map clearing terminal-initialization:20 */ ! 2921: register int i; ! 2922: ! 2923: for(i = 0; i < SCRNLIN; i++) scrmap[i]=0; ! 2924: } ! 2925: ! 2926: /* two window mode -- enter two window mode, prompt user for buffer */ ! 2927: ! 2928: twind() ! 2929: { ! 2930: /* Keywords: windows commands screen-handling:20 */ ! 2931: ! 2932: if (twowind) return; ! 2933: twowind = 1; ! 2934: wscrlines = SCRLINES; /* remember real size */ ! 2935: w1base = (wscrlines/2)-woff; /* Compute start of window 2 */ ! 2936: cwind = 0; ! 2937: owind(); /* enter second window */ ! 2938: cpbuf(1); /* and go to buffer */ ! 2939: } ! 2940: ! 2941: onewind() ! 2942: { ! 2943: /* Keywords: windows commands screen-handling:20 */ ! 2944: ! 2945: if (twowind) { ! 2946: fclear(); /* file map bad */ ! 2947: twowind = 0; ! 2948: cwind = 0; /* in window 0 */ ! 2949: wbase = 0; ! 2950: SCRLINES = wscrlines; ! 2951: } ! 2952: } ! 2953: ! 2954: /* Return buffer in other window or -1 */ ! 2955: ! 2956: windbuf() ! 2957: ! 2958: /* Keywords: windows commands buffers killing: */ ! 2959: { ! 2960: if (twind) return(windb[1-cwind]); ! 2961: else return(-1); ! 2962: } ! 2963: owind() /* switch windows */ ! 2964: /* returns -1 if not in two window mode, 0 if different buffer, ! 2965: and 1 if same buffer */ ! 2966: /* Keywords: windows commands screen-handling:20 */ ! 2967: { ! 2968: if (!twowind) return(-1); ! 2969: fclear(); ! 2970: windb[cwind] = curbf; ! 2971: wminln[cwind] = minln; ! 2972: wmaxln[cwind] = maxln; ! 2973: ! 2974: switch(cwind) { ! 2975: ! 2976: case 0: ! 2977: cwind = 1; ! 2978: wbase = w1base; ! 2979: SCRLINES = wscrlines; ! 2980: break; ! 2981: case 1: ! 2982: cwind = 0; ! 2983: wbase = 0; ! 2984: SCRLINES=w1base-1; ! 2985: break; ! 2986: } ! 2987: ! 2988: minln = wminln[cwind]; ! 2989: maxln = wmaxln[cwind]; ! 2990: lastln = SCRLINES-1; /* This is not accurate, but shouldn't matter much */ ! 2991: chbuf(windb[cwind]); ! 2992: if (windb[0]==windb[1]) return(1); ! 2993: return(0) ; ! 2994: } ! 2995: ! 2996: wgrow(arg) ! 2997: register int arg; ! 2998: /* Keywords: windows screen-lines commands insertion:50 screen-handling:20 */ ! 2999: { ! 3000: fclear(); /* file map bad */ ! 3001: if (twowind) { ! 3002: if (cwind) w1base -= arg; ! 3003: else w1base += arg; ! 3004: if (w1base < 2) w1base = 2; ! 3005: if (w1base > wscrlines-1) w1base = wscrlines-1; ! 3006: woff = (wscrlines/2)-w1base; ! 3007: if (cwind) { ! 3008: wbase = w1base; ! 3009: } else { ! 3010: SCRLINES = w1base-1; ! 3011: } ! 3012: } else { ! 3013: arg += SCRLINES; ! 3014: if ((arg > 0) && (arg < MODLN)) SCRLINES = arg; ! 3015: } ! 3016: } ! 3017: ! 3018: /* Mousing Specials */ ! 3019: ! 3020: /* Goto screen position at line x, collumn y. arg is decoded as: ! 3021: * x = arg mod 128. ! 3022: * y = arg /128. ! 3023: (128 is more lines than I can imagine on a screen.) ! 3024: ! 3025: * Will switch windows, but fails if x is an illegal position. */ ! 3026: ! 3027: go_xy(arg) ! 3028: int arg; ! 3029: /* Keywords: screen-positioning commands macro-programming:40 */ ! 3030: { ! 3031: register int x,y,c; ! 3032: int linpos; ! 3033: ! 3034: x = arg&127; ! 3035: y = ((unsigned) arg) >>7; ! 3036: if ((x <wbase) || (x>= SCRLINES)) { ! 3037: if (twowind) { ! 3038: if ((x >= 0) && (x < wscrlines)) { ! 3039: owind(); ! 3040: } else return(0); /* Can't mouse out of the display */ ! 3041: } else return(0); ! 3042: } ! 3043: linpos = scrmap[x]&SCRMSK; ! 3044: if (linpos== 0) { ! 3045: if (PICMODE && (maxln == nlines)) { ! 3046: linpos = maxln+x-lastln;/* If nothing there, punt to end of file */ ! 3047: move(linpos,0); ! 3048: } else if (x > lastln) { ! 3049: linpos = maxln; ! 3050: } else return(0); /* PUNT */ ! 3051: } ! 3052: ! 3053: if (findline(linpos)) mline = nln; ! 3054: else mline = x; ! 3055: ! 3056: column = 0; ! 3057: mcol = LNOMOD*LNOWID-hcol; ! 3058: if (y<mcol) y = mcol; ! 3059: clptr=mkline(linpos); ! 3060: while ((mline < x) || ((mline == x) && (mcol <= y))) { ! 3061: c = (clptr[column++]&0377); ! 3062: if (c == EOL) { ! 3063: if (PICMODE) { ! 3064: curln=linpos; ! 3065: column--; ! 3066: insertc(y-mcol+1,' '); ! 3067: } ! 3068: break; ! 3069: } ! 3070: if (c & META) mcol+= metal; ! 3071: switch(ctype[c& 0177]) { ! 3072: ! 3073: case PLAIN: ! 3074: case UL: ! 3075: mcol++; ! 3076: break; ! 3077: case BACKSP: ! 3078: if (mcol) mcol--; ! 3079: break; ! 3080: case CONTRL: ! 3081: mcol += 2; ! 3082: break; ! 3083: case TAB: ! 3084: mcol+= TABSTOP-((mcol-(LNOMOD*LNOWID))%TABSTOP); ! 3085: break; ! 3086: } ! 3087: if (mcol>SCRWID) { ! 3088: mline++; ! 3089: mcol = mcol-SCRWID; ! 3090: if (LNOMOD) mcol+= LNOWID; ! 3091: } ! 3092: } ! 3093: move(linpos,column-1); ! 3094: return(1); ! 3095: } ! 3096: ! 3097: vinit() ! 3098: /* Keywords: terminal-parameters terminal-initialization character-output */ ! 3099: { ! 3100: #ifndef PC ! 3101: #ifdef COMPRESS ! 3102: DOCOMP=CMPON; ! 3103: #endif ! 3104: ! 3105: #ifdef TERMINFO ! 3106: if (cur_term == NULL) return; /* Catch if called too soon */ ! 3107: if (enter_ca_mode) { ! 3108: putpad(enter_ca_mode); ! 3109: } ! 3110: if (keypad_xmit) { ! 3111: putpad(keypad_xmit); ! 3112: } ! 3113: #else ! 3114: if (SCINIT) PUTS(SCINIT); ! 3115: #endif ! 3116: #endif ! 3117: } ! 3118: ! 3119: vexit () ! 3120: { ! 3121: /* Keywords: terminal-parameters exit-processing character-output */ ! 3122: #ifndef PC ! 3123: #ifdef COMPRESS ! 3124: DOCOMP=0; ! 3125: #endif ! 3126: #ifdef TERMINFO ! 3127: if (exit_ca_mode) { ! 3128: putpad(exit_ca_mode); ! 3129: } ! 3130: if (keypad_local) { ! 3131: putpad(keypad_local); ! 3132: } ! 3133: #else ! 3134: if (VEXIT) PUTS(VEXIT); ! 3135: #endif ! 3136: #endif ! 3137: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.