|
|
1.1.1.3 ! root 1: /* ! 2: ! 3: Copyright 1992,1992 Eric R. Smith. ! 4: ! 5: Copyright 1992 Atari Corporation. ! 6: ! 7: All rights reserved. ! 8: ! 9: */ ! 10: ! 11: ! 12: 1.1 root 13: #include "mint.h" 14: 15: #include "fasttext.h" 16: 17: 18: 19: #ifdef FASTTEXT 20: 21: 22: 23: #ifdef __GNUC__ 24: 25: #define INLINE inline 26: 27: #define ITYPE long /* gcc's optimizer likes 32 bit integers */ 28: 29: #else 30: 31: #define INLINE 32: 33: #define ITYPE int 34: 35: #endif 36: 37: 38: 39: #define CONDEV (2) 40: 41: 42: 43: static SCREEN *current; 44: 45: 46: 47: static void paint P_((SCREEN *, int, char *)), 48: 49: paint8c P_((SCREEN *, int, char *)), 50: 1.1.1.3 ! root 51: paint816m P_((SCREEN *, int, char *)); 1.1 root 52: 53: 54: 55: INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *)); 56: 57: INLINE static void flash P_((SCREEN *)); 58: 59: static void normal_putch P_((SCREEN *, int)); 60: 61: static void escy_putch P_((SCREEN *, int)); 62: 1.1.1.2 root 63: static void quote_putch P_((SCREEN *, int)); 64: 1.1 root 65: 66: 67: static char *chartab[256]; 68: 69: 70: 1.1.1.2 root 71: #define MAX_PLANES 8 72: 73: static int fgmask[MAX_PLANES], bgmask[MAX_PLANES]; 74: 75: 76: 1.1 root 77: static long scrnsize; 78: 79: 80: 81: short hardscroll; 82: 83: static char *hardbase, *oldbase; 84: 85: 86: 87: typedef void (*Vfunc) P_((SCREEN *, int)); 88: 89: 90: 91: #define base *((char **)0x44eL) 92: 93: #define escy1 *((short *)0x4acL) 94: 95: 96: 97: static Vfunc state; 98: 99: 100: 101: static short hardline; 102: 103: static void (*vpaint) P_((SCREEN *, int, char *)); 104: 1.1.1.3 ! root 105: static char *rowoff; ! 106: 1.1 root 107: 108: 109: void init P_((void)); 110: 111: void hardware_scroll P_((SCREEN *)); 112: 113: INLINE static char *PLACE P_((SCREEN *, int, int)); 114: 115: INLINE static void gotoxy P_((SCREEN *, int, int)); 116: 117: INLINE static void clrline P_((SCREEN *, int)); 118: 119: INLINE static void clear P_((SCREEN *)); 120: 121: INLINE static void clrchar P_((SCREEN *, int, int)); 122: 123: INLINE static void clrfrom P_((SCREEN *, int, int, int, int)); 124: 125: INLINE static void delete_line P_((SCREEN *, int)); 126: 127: INLINE static void insert_line P_((SCREEN *, int)); 128: 129: static void setbgcol P_((SCREEN *, int)); 130: 131: static void setfgcol P_((SCREEN *, int)); 132: 133: static void putesc P_((SCREEN *, int)); 134: 135: static void escy1_putch P_((SCREEN *, int)); 136: 137: INLINE static void put_ch P_((SCREEN *, int)); 138: 139: 140: 141: /* routines for flashing the cursor for screen v */ 142: 143: /* flash(v): invert the character currently under the cursor */ 144: 145: 146: 147: INLINE static void 148: 149: flash(v) 150: 151: SCREEN *v; 152: 153: { 154: 1.1.1.2 root 155: char *place; 1.1 root 156: 157: ITYPE i, j, vplanes; 158: 159: 160: 161: vplanes = v->planes + v->planes; 162: 163: place = v->cursaddr; 164: 165: 166: 167: for (j = v->cheight; j > 0; --j) { 168: 169: for (i = 0; i < vplanes; i+=2) 170: 1.1.1.2 root 171: place[i] = ~place[i]; 1.1 root 172: 173: 174: 175: place += v->planesiz; 176: 177: } 178: 1.1.1.2 root 179: v->curstimer = v->period; 180: 1.1 root 181: } 182: 183: 184: 185: /* make sure the cursor is off */ 186: 187: 188: 189: INLINE 190: 191: static void 192: 193: curs_off(v) 194: 195: SCREEN *v; 196: 197: { 198: 199: if (v->flags & CURS_ON) { 200: 201: if (v->flags & CURS_FSTATE) { 202: 203: flash(v); 204: 205: v->flags &= ~CURS_FSTATE; 206: 207: } 208: 209: } 210: 211: } 212: 213: 214: 215: /* OK, show the cursor again (if appropriate) */ 216: 217: 218: 219: INLINE static void 220: 221: curs_on(v) 222: 223: SCREEN *v; 224: 225: { 226: 227: if (v->hidecnt) return; 228: 229: 230: 231: if (v->flags & CURS_ON) { 232: 1.1.1.2 root 233: #if 0 234: 1.1 root 235: /* if the cursor is flashing, we cheat a little and leave it off 236: 237: * to be turned on again (if necessary) by the VBL routine 238: 239: */ 240: 241: if (v->flags & CURS_FLASH) { 242: 243: v->curstimer = 2; 244: 245: return; 246: 247: } 248: 1.1.1.2 root 249: #endif 250: 1.1 root 251: if (!(v->flags & CURS_FSTATE)) { 252: 253: v->flags |= CURS_FSTATE; 254: 255: flash(v); 256: 257: } 258: 259: } 260: 261: } 262: 263: 264: 265: void 266: 267: init() 268: 269: { 270: 271: SCREEN *v; 272: 273: int i, j; 274: 275: char *data, *foo; 276: 277: static char chardata[256*16]; 278: 1.1.1.3 ! root 279: register int linelen; ! 280: 1.1 root 281: 282: 283: foo = lineA0(); 284: 285: v = (SCREEN *)(foo - 346); 286: 287: 288: 289: /* Ehem... The screen might be bigger than 32767 bytes. 290: 291: Let's do some casting... 292: 293: Erling 294: 295: */ 296: 1.1.1.3 ! root 297: linelen = v->linelen; ! 298: ! 299: scrnsize = (v->maxy+1)*(long)linelen; ! 300: ! 301: rowoff = (char *)kmalloc((long)((v->maxy+1) * sizeof(long))); ! 302: ! 303: if (rowoff == 0) { ! 304: ! 305: FATAL("Insufficient memory for screen offset table!"); ! 306: ! 307: } else { ! 308: ! 309: long off, *lptr = (long *)rowoff; ! 310: ! 311: for (i=0, off=0; i<=v->maxy; i++) { ! 312: ! 313: *lptr++ = off; ! 314: ! 315: off += linelen; ! 316: ! 317: } ! 318: ! 319: } 1.1 root 320: 1.1.1.2 root 321: if (hardscroll == -1) { 322: 323: /* request for auto-setting */ 324: 325: hardscroll = v->maxy+1; 326: 327: } 328: 1.1 root 329: if (hardscroll > 0) { 330: 331: if (!hardbase) 332: 333: hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L) 334: 335: & 0xffffff00L); 336: 337: 338: 339: if (hardbase == 0) { 340: 341: ALERT("Insufficient memory for hardware scrolling!"); 342: 343: } else { 344: 345: quickmove(hardbase, base, scrnsize); 346: 347: v->cursaddr = v->cursaddr + (hardbase - base); 348: 349: oldbase = base; 350: 351: base = hardbase; 352: 353: Setscreen(hardbase, hardbase, -1); 354: 355: } 356: 357: } 358: 359: hardline = 0; 360: 361: if (v->cheight == 8 && v->planes == 2) { 362: 363: foo = &chardata[0]; 364: 365: vpaint = paint8c; 366: 367: for (i = 0; i < 256; i++) { 368: 369: chartab[i] = foo; 370: 371: data = v->fontdata + i; 372: 373: for (j = 0; j < 8; j++) { 374: 375: *foo++ = *data; 376: 377: data += v->form_width; 378: 379: } 380: 381: } 382: 1.1.1.3 ! root 383: } else if ((v->cheight == 16 || v->cheight == 8) && v->planes == 1) { 1.1 root 384: 385: foo = &chardata[0]; 386: 1.1.1.3 ! root 387: vpaint = paint816m; 1.1 root 388: 389: for (i = 0; i < 256; i++) { 390: 391: chartab[i] = foo; 392: 393: data = v->fontdata + i; 394: 1.1.1.3 ! root 395: for (j = 0; j < v->cheight; j++) { 1.1 root 396: 397: *foo++ = *data; 398: 399: data += v->form_width; 400: 401: } 402: 403: } 404: 405: } 406: 407: else 408: 409: vpaint = paint; 410: 411: 412: 413: if (v->hidecnt == 0) { 414: 415: /* 416: 417: * make sure the cursor is set up correctly and turned on 418: 419: */ 420: 421: (void)Cursconf(0,0); /* turn cursor off */ 422: 423: 424: 1.1.1.2 root 425: v->flags &= ~CURS_FSTATE; 1.1 root 426: 427: 428: 429: /* now turn the cursor on the way we like it */ 430: 431: v->hidecnt = 0; 432: 433: curs_on(v); 434: 435: } else { 436: 437: (void)Cursconf(0,0); 438: 439: v->flags &= ~CURS_ON; 440: 441: v->hidecnt = 1; 442: 443: } 444: 445: 446: 447: current = v; 448: 1.1.1.2 root 449: /* setup bgmask and fgmask */ 450: 451: setbgcol(v, v->bgcol); 452: 453: setfgcol(v, v->fgcol); 454: 1.1 root 455: state = normal_putch; 456: 457: } 458: 459: 460: 461: /* 462: 463: * PLACE(v, x, y): the address corresponding to the upper left hand corner of 464: 465: * the character at position (x,y) on screen v 466: 467: */ 468: 469: INLINE static 470: 471: char *PLACE(v, x, y) 472: 473: SCREEN *v; 474: 475: int x, y; 476: 477: { 478: 479: char *place; 480: 481: int i, j; 482: 483: 484: 485: place = base + x; 486: 487: if (y == v->maxy) 488: 489: place += scrnsize - v->linelen; 490: 1.1.1.3 ! root 491: else if (y) { 1.1 root 492: 1.1.1.3 ! root 493: y+=y; /* Make Y into index for longword array. */ 1.1 root 494: 1.1.1.3 ! root 495: y+=y; /* Two word-size adds are faster than a 2-bit shift. */ 1.1 root 496: 1.1.1.3 ! root 497: place += *(long *)(rowoff + y); 1.1 root 498: 1.1.1.3 ! root 499: } 1.1 root 500: 1.1.1.3 ! root 501: if ((j = v->planes-1)) { 1.1 root 502: 503: i = (x & 0xfffe); 504: 1.1.1.3 ! root 505: do place += i; 1.1 root 506: 1.1.1.3 ! root 507: while (--j); 1.1 root 508: 509: } 510: 511: return place; 512: 513: } 514: 515: 516: 517: /* 518: 519: * paint(v, c, place): put character 'c' at position 'place' on screen 520: 521: * v. It is assumed that x, y are proper coordinates! 522: 1.1.1.3 ! root 523: * Specialized versions (paint8c and paint816m) of this routine follow; 1.1 root 524: 1.1.1.3 ! root 525: * they assume 8 line high characters, medium res. and 8 or 16 line/mono, 1.1 root 526: 527: * respectively. 528: 529: */ 530: 531: 532: 533: static void 534: 535: paint(v, c, place) 536: 537: SCREEN *v; 538: 539: int c; 540: 541: char *place; 542: 543: { 544: 545: char *data, d, doinverse; 546: 547: ITYPE j, planecount; 548: 549: int vplanes; 550: 551: long vform_width, vplanesiz; 552: 553: 554: 555: vplanes = v->planes; 556: 557: 558: 559: data = v->fontdata + c; 560: 561: doinverse = (v->flags & FINVERSE) ? 0xff : 0; 562: 563: vform_width = v->form_width; 564: 565: vplanesiz = v->planesiz; 566: 567: 568: 569: for (j = v->cheight; j > 0; --j) { 570: 571: d = *data ^ doinverse; 572: 1.1.1.2 root 573: for (planecount = 0; planecount < vplanes; planecount++) 1.1 root 574: 1.1.1.2 root 575: place[planecount << 1] 1.1 root 576: 1.1.1.2 root 577: = ((d & (char) fgmask[planecount]) 1.1 root 578: 1.1.1.2 root 579: | (~d & (char) bgmask[planecount])); 1.1 root 580: 581: place += vplanesiz; 582: 583: data += vform_width; 584: 585: } 586: 587: } 588: 589: 590: 591: static void 592: 593: paint8c(v, c, place) 594: 595: SCREEN *v; 596: 597: int c; 598: 599: char *place; 600: 601: { 602: 603: char *data; 604: 605: char d, doinverse; 606: 1.1.1.2 root 607: char bg0, bg1, fg0, fg1; 608: 1.1 root 609: long vplanesiz; 610: 611: 612: 613: data = chartab[c]; 614: 615: 616: 617: doinverse = (v->flags & FINVERSE) ? 0xff : 0; 618: 619: vplanesiz = v->planesiz; 620: 1.1.1.2 root 621: bg0 = bgmask[0]; 622: 623: bg1 = bgmask[1]; 624: 625: fg0 = fgmask[0]; 626: 627: fg1 = fgmask[1]; 1.1 root 628: 629: 1.1.1.2 root 630: 631: if (!doinverse && !bg0 && !bg1 && fg0 && fg1) { 1.1 root 632: 633: /* line 1 */ 634: 635: d = *data++; 636: 637: *place = d; 638: 639: place[2] = d; 640: 641: place += vplanesiz; 642: 643: 644: 645: /* line 2 */ 646: 647: d = *data++; 648: 649: *place = d; 650: 651: place[2] = d; 652: 653: place += vplanesiz; 654: 655: 656: 657: /* line 3 */ 658: 659: d = *data++; 660: 661: *place = d; 662: 663: place[2] = d; 664: 665: place += vplanesiz; 666: 667: 668: 669: /* line 4 */ 670: 671: d = *data++; 672: 673: *place = d; 674: 675: place[2] = d; 676: 677: place += vplanesiz; 678: 679: 680: 681: /* line 5 */ 682: 683: d = *data++; 684: 685: *place = d; 686: 687: place[2] = d; 688: 689: place += vplanesiz; 690: 691: 692: 693: /* line 6 */ 694: 695: d = *data++; 696: 697: *place = d; 698: 699: place[2] = d; 700: 701: place += vplanesiz; 702: 703: 704: 705: /* line 7 */ 706: 707: d = *data++; 708: 709: *place = d; 710: 711: place[2] = d; 712: 713: place += vplanesiz; 714: 715: 716: 717: /* line 8 */ 718: 1.1.1.2 root 719: d = *data; 1.1 root 720: 721: *place = d; 722: 723: place[2] = d; 724: 725: } else { 726: 727: /* line 1 */ 728: 729: d = *data++ ^ doinverse; 730: 1.1.1.2 root 731: *place = ((d & fg0) | (~d & bg0)); 1.1 root 732: 1.1.1.2 root 733: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 734: 735: place += vplanesiz; 736: 737: 738: 739: /* line 2 */ 740: 741: d = *data++ ^ doinverse; 742: 1.1.1.2 root 743: *place = ((d & fg0) | (~d & bg0)); 1.1 root 744: 1.1.1.2 root 745: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 746: 747: place += vplanesiz; 748: 749: 750: 751: /* line 3 */ 752: 753: d = *data++ ^ doinverse; 754: 1.1.1.2 root 755: *place = ((d & fg0) | (~d & bg0)); 1.1 root 756: 1.1.1.2 root 757: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 758: 759: place += vplanesiz; 760: 761: 762: 763: /* line 4 */ 764: 765: d = *data++ ^ doinverse; 766: 1.1.1.2 root 767: *place = ((d & fg0) | (~d & bg0)); 1.1 root 768: 1.1.1.2 root 769: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 770: 771: place += vplanesiz; 772: 773: 774: 775: /* line 5 */ 776: 777: d = *data++ ^ doinverse; 778: 1.1.1.2 root 779: *place = ((d & fg0) | (~d & bg0)); 1.1 root 780: 1.1.1.2 root 781: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 782: 783: place += vplanesiz; 784: 785: 786: 787: /* line 6 */ 788: 789: d = *data++ ^ doinverse; 790: 1.1.1.2 root 791: *place = ((d & fg0) | (~d & bg0)); 1.1 root 792: 1.1.1.2 root 793: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 794: 795: place += vplanesiz; 796: 797: 798: 799: /* line 7 */ 800: 801: d = *data++ ^ doinverse; 802: 1.1.1.2 root 803: *place = ((d & fg0) | (~d & bg0)); 1.1 root 804: 1.1.1.2 root 805: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 806: 807: place += vplanesiz; 808: 809: 810: 811: /* line 8 */ 812: 1.1.1.2 root 813: d = *data ^ doinverse; 1.1 root 814: 1.1.1.2 root 815: *place = ((d & fg0) | (~d & bg0)); 1.1 root 816: 1.1.1.2 root 817: place[2] = ((d & fg1) | (~d & bg1)); 1.1 root 818: 819: } 820: 821: } 822: 823: 824: 825: static void 826: 1.1.1.3 ! root 827: paint816m(v, c, place) 1.1 root 828: 829: SCREEN *v; 830: 831: int c; 832: 833: char *place; 834: 835: { 836: 837: char *data; 838: 839: char d, doinverse; 840: 841: long vplanesiz; 842: 843: 844: 845: data = chartab[c]; 846: 847: doinverse = (v->flags & FINVERSE) ? 0xff : 0; 848: 1.1.1.2 root 849: doinverse ^= bgmask[0]; 850: 1.1 root 851: vplanesiz = v->planesiz; 852: 853: 854: 1.1.1.2 root 855: if (bgmask[0] == fgmask[0]) 856: 857: { 858: 859: /* fgcol and bgcol are the same -- easy */ 860: 861: d = (char) bgmask[0]; 862: 863: *place = d; 864: 865: place += vplanesiz; 866: 867: *place = d; 868: 869: place += vplanesiz; 870: 871: *place = d; 872: 873: place += vplanesiz; 874: 875: *place = d; 876: 877: place += vplanesiz; 878: 879: *place = d; 880: 881: place += vplanesiz; 882: 883: *place = d; 884: 885: place += vplanesiz; 886: 887: *place = d; 888: 889: place += vplanesiz; 890: 891: *place = d; 892: 1.1.1.3 ! root 893: if (v->cheight == 8) ! 894: ! 895: return; ! 896: 1.1.1.2 root 897: place += vplanesiz; 898: 899: *place = d; 900: 901: place += vplanesiz; 902: 903: *place = d; 904: 905: place += vplanesiz; 906: 907: *place = d; 908: 909: place += vplanesiz; 910: 911: *place = d; 912: 913: place += vplanesiz; 914: 915: *place = d; 916: 917: place += vplanesiz; 918: 919: *place = d; 920: 921: place += vplanesiz; 922: 923: *place = d; 924: 925: place += vplanesiz; 926: 927: *place = d; 928: 929: } 930: 931: else if (!doinverse) { 1.1 root 932: 933: /* line 1 */ 934: 935: d = *data++; 936: 937: *place = d; 938: 939: place += vplanesiz; 940: 941: 942: 943: /* line 2 */ 944: 945: d = *data++; 946: 947: *place = d; 948: 949: place += vplanesiz; 950: 951: 952: 953: /* line 3 */ 954: 955: d = *data++; 956: 957: *place = d; 958: 959: place += vplanesiz; 960: 961: 962: 963: /* line 4 */ 964: 965: d = *data++; 966: 967: *place = d; 968: 969: place += vplanesiz; 970: 971: 972: 973: /* line 5 */ 974: 975: d = *data++; 976: 977: *place = d; 978: 979: place += vplanesiz; 980: 981: 982: 983: /* line 6 */ 984: 985: d = *data++; 986: 987: *place = d; 988: 989: place += vplanesiz; 990: 991: 992: 993: /* line 7 */ 994: 995: d = *data++; 996: 997: *place = d; 998: 999: place += vplanesiz; 1000: 1001: 1002: 1003: /* line 8 */ 1004: 1005: d = *data++; 1006: 1007: *place = d; 1008: 1.1.1.3 ! root 1009: ! 1010: ! 1011: if (v->cheight == 8) ! 1012: ! 1013: return; ! 1014: ! 1015: ! 1016: 1.1 root 1017: place += vplanesiz; 1018: 1019: 1020: 1021: /* line 9 */ 1022: 1023: d = *data++; 1024: 1025: *place = d; 1026: 1027: place += vplanesiz; 1028: 1029: 1030: 1031: /* line 10 */ 1032: 1033: d = *data++; 1034: 1035: *place = d; 1036: 1037: place += vplanesiz; 1038: 1039: 1040: 1041: /* line 11 */ 1042: 1043: d = *data++; 1044: 1045: *place = d; 1046: 1047: place += vplanesiz; 1048: 1049: 1050: 1051: /* line 12 */ 1052: 1053: d = *data++; 1054: 1055: *place = d; 1056: 1057: place += vplanesiz; 1058: 1059: 1060: 1061: /* line 13 */ 1062: 1063: d = *data++; 1064: 1065: *place = d; 1066: 1067: place += vplanesiz; 1068: 1069: 1070: 1071: /* line 14 */ 1072: 1073: d = *data++; 1074: 1075: *place = d; 1076: 1077: place += vplanesiz; 1078: 1079: 1080: 1081: /* line 15 */ 1082: 1083: d = *data++; 1084: 1085: *place = d; 1086: 1087: place += vplanesiz; 1088: 1089: 1090: 1091: /* line 16 */ 1092: 1.1.1.2 root 1093: d = *data; 1.1 root 1094: 1095: *place = d; 1096: 1097: } else { 1098: 1099: /* line 1 */ 1100: 1.1.1.2 root 1101: d = ~*data++; 1.1 root 1102: 1103: *place = d; 1104: 1105: place += vplanesiz; 1106: 1107: 1108: 1109: /* line 2 */ 1110: 1.1.1.2 root 1111: d = ~*data++; 1.1 root 1112: 1113: *place = d; 1114: 1115: place += vplanesiz; 1116: 1117: 1118: 1119: /* line 3 */ 1120: 1.1.1.2 root 1121: d = ~*data++; 1.1 root 1122: 1123: *place = d; 1124: 1125: place += vplanesiz; 1126: 1127: 1128: 1129: /* line 4 */ 1130: 1.1.1.2 root 1131: d = ~*data++; 1.1 root 1132: 1133: *place = d; 1134: 1135: place += vplanesiz; 1136: 1137: 1138: 1139: /* line 5 */ 1140: 1.1.1.2 root 1141: d = ~*data++; 1.1 root 1142: 1143: *place = d; 1144: 1145: place += vplanesiz; 1146: 1147: 1148: 1149: /* line 6 */ 1150: 1.1.1.2 root 1151: d = ~*data++; 1.1 root 1152: 1153: *place = d; 1154: 1155: place += vplanesiz; 1156: 1157: 1158: 1159: /* line 7 */ 1160: 1.1.1.2 root 1161: d = ~*data++; 1.1 root 1162: 1163: *place = d; 1164: 1165: place += vplanesiz; 1166: 1167: 1168: 1169: /* line 8 */ 1170: 1.1.1.2 root 1171: d = ~*data++; 1.1 root 1172: 1173: *place = d; 1174: 1.1.1.3 ! root 1175: ! 1176: ! 1177: if (v->cheight == 8) ! 1178: ! 1179: return; ! 1180: ! 1181: ! 1182: 1.1 root 1183: place += vplanesiz; 1184: 1185: 1186: 1187: /* line 9 */ 1188: 1.1.1.2 root 1189: d = ~*data++; 1.1 root 1190: 1191: *place = d; 1192: 1193: place += vplanesiz; 1194: 1195: 1196: 1197: /* line 10 */ 1198: 1.1.1.2 root 1199: d = ~*data++; 1.1 root 1200: 1201: *place = d; 1202: 1203: place += vplanesiz; 1204: 1205: 1206: 1207: /* line 11 */ 1208: 1.1.1.2 root 1209: d = ~*data++; 1.1 root 1210: 1211: *place = d; 1212: 1213: place += vplanesiz; 1214: 1215: 1216: 1217: /* line 12 */ 1218: 1.1.1.2 root 1219: d = ~*data++; 1.1 root 1220: 1221: *place = d; 1222: 1223: place += vplanesiz; 1224: 1225: 1226: 1227: /* line 13 */ 1228: 1.1.1.2 root 1229: d = ~*data++; 1.1 root 1230: 1231: *place = d; 1232: 1233: place += vplanesiz; 1234: 1235: 1236: 1237: /* line 14 */ 1238: 1.1.1.2 root 1239: d = ~*data++; 1.1 root 1240: 1241: *place = d; 1242: 1243: place += vplanesiz; 1244: 1245: 1246: 1247: /* line 15 */ 1248: 1.1.1.2 root 1249: d = ~*data++; 1.1 root 1250: 1251: *place = d; 1252: 1253: place += vplanesiz; 1254: 1255: 1256: 1257: /* line 16 */ 1258: 1.1.1.2 root 1259: d = ~*data; 1.1 root 1260: 1261: *place = d; 1262: 1263: } 1264: 1265: } 1266: 1267: 1268: 1269: /* 1270: 1271: * gotoxy (v, x, y): move current cursor address of screen v to (x, y) 1272: 1273: * makes sure that (x, y) will be legal 1274: 1275: */ 1276: 1277: 1278: 1279: INLINE static void 1280: 1281: gotoxy(v, x, y) 1282: 1283: SCREEN *v; 1284: 1285: int x, y; 1286: 1287: { 1288: 1289: if (x > v->maxx) x = v->maxx; 1290: 1291: else if (x < 0) x = 0; 1292: 1293: if (y > v->maxy) y = v->maxy; 1294: 1295: else if (y < 0) y = 0; 1296: 1297: 1298: 1299: v->cx = x; 1300: 1301: v->cy = y; 1302: 1303: v->cursaddr = PLACE(v, x, y); 1304: 1305: } 1306: 1307: 1308: 1309: /* 1310: 1311: * clrline(v, r): clear line r of screen v 1312: 1313: */ 1314: 1315: 1316: 1317: INLINE static void 1318: 1319: clrline(v, r) 1320: 1321: SCREEN *v; 1322: 1323: int r; 1324: 1325: { 1326: 1.1.1.2 root 1327: int *dst, *m; 1.1 root 1328: 1.1.1.2 root 1329: long nwords; 1.1 root 1330: 1.1.1.2 root 1331: int i, vplanes; 1.1 root 1332: 1333: 1334: 1335: /* Hey, again the screen might be bigger than 32767 bytes. 1336: 1337: Do another cast... */ 1338: 1.1.1.3 ! root 1339: r += r; ! 1340: ! 1341: r += r; ! 1342: ! 1343: dst = (int *)(base + *(long *)(rowoff+r)); 1.1.1.2 root 1344: 1345: if (v->bgcol == 0) 1346: 1347: zero((char *)dst, v->linelen); 1348: 1349: else 1350: 1351: { 1352: 1353: /* do it the hard way */ 1354: 1355: vplanes = v->planes; 1.1 root 1356: 1.1.1.2 root 1357: for (nwords = v->linelen >> 1; nwords > 0; nwords -= vplanes) 1358: 1359: { 1360: 1361: m = bgmask; 1362: 1363: for (i = 0; i < vplanes; i++) 1364: 1365: *dst++ = *m++; 1366: 1367: } 1368: 1369: } 1.1 root 1370: 1371: } 1372: 1373: 1374: 1375: /* 1376: 1377: * clear(v): clear the whole screen v 1378: 1379: */ 1380: 1381: 1382: 1383: INLINE static void 1384: 1385: clear(v) 1386: 1387: SCREEN *v; 1388: 1389: { 1390: 1.1.1.2 root 1391: int i, vplanes; 1392: 1393: int *dst, *m; 1394: 1395: long nwords; 1396: 1397: 1398: 1399: if (v->bgcol == 0) 1400: 1401: zero(base, scrnsize); 1402: 1403: else 1404: 1405: { 1406: 1407: /* do it the hard way */ 1408: 1409: dst = (int *) base; 1410: 1411: vplanes = v->planes; 1412: 1413: for (nwords = scrnsize >> 1; nwords > 0; nwords -= vplanes) 1414: 1415: { 1416: 1417: m = bgmask; 1418: 1419: for (i = 0; i < vplanes; i++) 1420: 1421: *dst++ = *m++; 1422: 1423: } 1424: 1425: } 1.1 root 1426: 1427: } 1428: 1429: 1430: 1431: /* 1432: 1433: * clrchar(v, x, y): clear the (x,y) position on screen v 1434: 1435: */ 1436: 1437: 1438: 1439: INLINE static void 1440: 1441: clrchar(v, x, y) 1442: 1443: SCREEN *v; 1444: 1445: int x, y; 1446: 1447: { 1448: 1449: int i, j, vplanes; 1450: 1451: char *place; 1452: 1.1.1.2 root 1453: int *m; 1454: 1.1 root 1455: 1456: 1457: vplanes = v->planes + v->planes; 1458: 1459: 1460: 1461: place = PLACE(v, x, y); 1462: 1463: 1464: 1465: for (j = v->cheight; j > 0; --j) { 1466: 1.1.1.2 root 1467: m = bgmask; 1468: 1469: for (i = 0; i < vplanes; i += 2) 1.1 root 1470: 1.1.1.2 root 1471: place[i] = (char) *m++; 1.1 root 1472: 1473: place += v->planesiz; 1474: 1475: } 1476: 1477: } 1478: 1479: 1480: 1481: /* 1482: 1483: * clrfrom(v, x1, y1, x2, y2): clear screen v from position (x1,y1) to 1484: 1485: * position (x2, y2) inclusive. It is assumed that y2 >= y1. 1486: 1487: */ 1488: 1489: 1490: 1491: INLINE static void 1492: 1493: clrfrom(v, x1, y1, x2, y2) 1494: 1495: SCREEN *v; 1496: 1497: int x1,y1,x2,y2; 1498: 1499: { 1500: 1501: int i; 1502: 1503: 1504: 1505: for (i = x1; i <= v->maxx; i++) 1506: 1507: clrchar(v, i, y1); 1508: 1509: if (y2 > y1) { 1510: 1511: for (i = 0; i <= x2; i++) 1512: 1513: clrchar(v, i, y2); 1514: 1515: for (i = y1+1; i < y2; i++) 1516: 1517: clrline(v, i); 1518: 1519: } 1520: 1521: } 1522: 1523: 1524: 1525: /* 1526: 1527: * scroll a screen in hardware; if we still have hardware scrolling lines left, 1528: 1529: * just move the physical screen base, otherwise copy the screen back to the 1530: 1531: * hardware base and start over 1532: 1533: */ 1534: 1535: void 1536: 1537: hardware_scroll(v) 1538: 1539: SCREEN *v; 1540: 1541: { 1542: 1543: 1544: 1545: ++hardline; 1546: 1547: if (hardline < hardscroll) { /* just move the screen */ 1548: 1549: base += v->linelen; 1550: 1.1.1.3 ! root 1551: } else { 1.1 root 1552: 1553: hardline = 0; 1554: 1555: quickmove(hardbase, base + v->linelen, scrnsize - v->linelen); 1556: 1557: base = hardbase; 1558: 1.1.1.3 ! root 1559: } 1.1 root 1560: 1.1.1.3 ! root 1561: v->cursaddr = PLACE(v, v->cx, v->cy); 1.1 root 1562: 1.1.1.3 ! root 1563: Setscreen(base, base, -1); 1.1 root 1564: 1565: } 1566: 1567: 1568: 1569: /* 1570: 1571: * delete_line(v, r): delete line r of screen v. The screen below this 1572: 1573: * line is scrolled up, and the bottom line is cleared. 1574: 1575: */ 1576: 1577: 1578: 1579: #define scroll(v) delete_line(v, 0) 1580: 1581: 1582: 1583: INLINE static void 1584: 1585: delete_line(v, r) 1586: 1587: SCREEN *v; 1588: 1589: int r; 1590: 1591: { 1592: 1593: long *src, *dst, nbytes; 1594: 1595: 1596: 1597: if (r == 0) { 1598: 1599: if (hardbase) { 1600: 1601: hardware_scroll(v); 1602: 1603: clrline(v, v->maxy); 1604: 1605: return; 1606: 1607: } 1608: 1609: nbytes = scrnsize - v->linelen; 1610: 1.1.1.3 ! root 1611: } else { 1.1 root 1612: 1.1.1.3 ! root 1613: register int i = v->maxy - r; ! 1614: ! 1615: i += i; 1.1 root 1616: 1.1.1.3 ! root 1617: i += i; ! 1618: ! 1619: nbytes = *(long *)(rowoff+i); ! 1620: ! 1621: } 1.1 root 1622: 1623: 1624: 1625: /* Sheeze, how many times do we really have to cast... 1626: 1627: Erling. 1628: 1629: */ 1630: 1631: 1632: 1.1.1.3 ! root 1633: r += r; ! 1634: ! 1635: r += r; ! 1636: ! 1637: dst = (long *)(base + *(long *)(rowoff + r)); 1.1 root 1638: 1639: src = (long *)( ((long)dst) + v->linelen); 1640: 1641: 1642: 1643: quickmove(dst, src, nbytes); 1644: 1645: 1646: 1647: /* clear the last line */ 1648: 1649: clrline(v, v->maxy); 1650: 1651: } 1652: 1653: 1654: 1655: /* 1656: 1657: * insert_line(v, r): scroll all of the screen starting at line r down, 1658: 1659: * and then clear line r. 1660: 1661: */ 1662: 1663: 1664: 1665: INLINE static void 1666: 1667: insert_line(v, r) 1668: 1669: SCREEN *v; 1670: 1671: int r; 1672: 1673: { 1674: 1675: long *src, *dst; 1676: 1.1.1.3 ! root 1677: int i, j, linelen; 1.1 root 1678: 1679: 1680: 1.1.1.3 ! root 1681: i = v->maxy - 1; 1.1 root 1682: 1.1.1.3 ! root 1683: i += i; 1.1 root 1684: 1.1.1.3 ! root 1685: i += i; 1.1 root 1686: 1.1.1.3 ! root 1687: j = r+r; 1.1 root 1688: 1.1.1.3 ! root 1689: j += j; 1.1 root 1690: 1.1.1.3 ! root 1691: linelen = v->linelen; ! 1692: ! 1693: src = (long *)(base + *(long *)(rowoff + i)); 1.1 root 1694: 1.1.1.3 ! root 1695: dst = (long *)((long)src + linelen); 1.1 root 1696: 1.1.1.3 ! root 1697: for (; i >= j ; i -= 4) { 1.1 root 1698: 1.1.1.3 ! root 1699: /* move line i to line i+1 */ ! 1700: ! 1701: quickmove(dst, src, linelen); ! 1702: ! 1703: dst = src; ! 1704: ! 1705: src = (long *)((long) src - linelen); 1.1 root 1706: 1707: } 1708: 1709: 1710: 1711: /* clear line r */ 1712: 1713: clrline(v, r); 1714: 1715: } 1716: 1717: 1718: 1719: /* 1720: 1721: * special states for handling ESC b x and ESC c x. Note that for now, 1722: 1723: * color is ignored. 1724: 1725: */ 1726: 1727: 1728: 1729: static void 1730: 1731: setbgcol(v, c) 1732: 1733: SCREEN *v; 1734: 1735: int c; 1736: 1737: { 1738: 1.1.1.2 root 1739: int i; 1740: 1741: 1742: 1.1 root 1743: v->bgcol = c & ((1 << v->planes)-1); 1744: 1.1.1.2 root 1745: for (i = 0; i < v->planes; i++) 1746: 1747: bgmask[i] = (v->bgcol & (1 << i)) ? -1 : 0; 1748: 1.1 root 1749: state = normal_putch; 1750: 1751: } 1752: 1753: 1754: 1755: static void 1756: 1757: setfgcol(v, c) 1758: 1759: SCREEN *v; 1760: 1761: int c; 1762: 1763: { 1764: 1.1.1.2 root 1765: int i; 1766: 1767: 1768: 1.1 root 1769: v->fgcol = c & ((1 << v->planes)-1); 1770: 1.1.1.2 root 1771: for (i = 0; i < v->planes; i++) 1772: 1773: fgmask[i] = (v->fgcol & (1 << i)) ? -1 : 0; 1774: 1775: state = normal_putch; 1776: 1777: } 1778: 1779: 1780: 1781: static void 1782: 1783: quote_putch(v, c) 1784: 1785: SCREEN *v; 1786: 1787: int c; 1788: 1789: { 1790: 1791: (*vpaint)(v, c, v->cursaddr); 1792: 1.1 root 1793: state = normal_putch; 1794: 1795: } 1796: 1797: 1798: 1799: /* 1800: 1801: * putesc(v, c): handle the control sequence ESC c 1802: 1803: */ 1804: 1805: 1806: 1807: static void 1808: 1809: putesc(v, c) 1810: 1811: SCREEN *v; 1812: 1813: int c; 1814: 1815: { 1816: 1.1.1.3 ! root 1817: int i; ! 1818: 1.1 root 1819: int cx, cy; 1820: 1821: 1822: 1823: cx = v->cx; cy = v->cy; 1824: 1825: 1826: 1827: switch (c) { 1828: 1829: case 'A': /* cursor up */ 1830: 1.1.1.3 ! root 1831: if (cy) { ! 1832: ! 1833: moveup: v->cy = --cy; ! 1834: ! 1835: v->cursaddr -= v->linelen; ! 1836: ! 1837: } 1.1 root 1838: 1839: break; 1840: 1841: case 'B': /* cursor down */ 1842: 1.1.1.3 ! root 1843: if (cy < v->maxy) { ! 1844: ! 1845: v->cy = ++cy; ! 1846: ! 1847: v->cursaddr += v->linelen; ! 1848: ! 1849: } 1.1 root 1850: 1851: break; 1852: 1853: case 'C': /* cursor right */ 1854: 1.1.1.3 ! root 1855: if (cx < v->maxx) { ! 1856: ! 1857: if ((i = v->planes-1) && (cx & 1)) ! 1858: ! 1859: v->cursaddr += i + i; ! 1860: ! 1861: v->cx = ++cx; ! 1862: ! 1863: v->cursaddr++; ! 1864: ! 1865: } 1.1 root 1866: 1867: break; 1868: 1869: case 'D': /* cursor left */ 1870: 1.1.1.3 ! root 1871: if (cx) { ! 1872: ! 1873: v->cx = --cx; ! 1874: ! 1875: v->cursaddr--; ! 1876: ! 1877: if ((i = v->planes-1) && (cx & 1)) ! 1878: ! 1879: v->cursaddr -= i + i; ! 1880: ! 1881: } 1.1 root 1882: 1883: break; 1884: 1885: case 'E': /* clear home */ 1886: 1887: clear(v); 1888: 1889: /* fall through... */ 1890: 1891: case 'H': /* cursor home */ 1892: 1.1.1.3 ! root 1893: v->cx = 0; v->cy = 0; ! 1894: ! 1895: v->cursaddr = base; 1.1 root 1896: 1897: break; 1898: 1899: case 'I': /* cursor up, insert line */ 1900: 1901: if (cy == 0) { 1902: 1903: insert_line(v, 0); 1904: 1905: } 1906: 1907: else 1908: 1.1.1.3 ! root 1909: goto moveup; 1.1 root 1910: 1911: break; 1912: 1913: case 'J': /* clear below cursor */ 1914: 1915: clrfrom(v, cx, cy, v->maxx, v->maxy); 1916: 1917: break; 1918: 1919: case 'K': /* clear remainder of line */ 1920: 1921: clrfrom(v, cx, cy, v->maxx, cy); 1922: 1923: break; 1924: 1925: case 'L': /* insert a line */ 1926: 1.1.1.3 ! root 1927: v->cx = 0; ! 1928: ! 1929: i = cy + cy; ! 1930: ! 1931: i += i; ! 1932: ! 1933: v->cursaddr = base + *(long *)(rowoff + i); 1.1 root 1934: 1935: insert_line(v, cy); 1936: 1937: break; 1938: 1939: case 'M': /* delete line */ 1940: 1.1.1.3 ! root 1941: v->cx = 0; ! 1942: ! 1943: i = cy + cy; ! 1944: ! 1945: i += i; ! 1946: ! 1947: v->cursaddr = base + *(long *)(rowoff + i); 1.1 root 1948: 1949: delete_line(v, cy); 1950: 1951: break; 1952: 1.1.1.2 root 1953: case 'Q': /* quote-next-char */ 1954: 1955: state = quote_putch; 1956: 1957: return; 1958: 1.1 root 1959: case 'Y': 1960: 1961: state = escy_putch; 1962: 1963: return; /* YES, this should be 'return' */ 1964: 1965: 1966: 1967: case 'b': 1968: 1969: state = setfgcol; 1970: 1971: return; 1972: 1973: case 'c': 1974: 1975: state = setbgcol; 1976: 1977: return; 1978: 1979: case 'd': /* clear to cursor position */ 1980: 1981: clrfrom(v, 0, 0, cx, cy); 1982: 1983: break; 1984: 1985: case 'e': /* enable cursor */ 1986: 1987: v->flags |= CURS_ON; 1988: 1989: v->hidecnt = 1; /* so --v->hidecnt shows the cursor */ 1990: 1991: break; 1992: 1993: case 'f': /* cursor off */ 1994: 1995: v->hidecnt++; 1996: 1997: v->flags &= ~CURS_ON; 1998: 1999: break; 2000: 2001: case 'j': /* save cursor position */ 2002: 2003: v->savex = v->cx; 2004: 2005: v->savey = v->cy; 2006: 2007: break; 2008: 2009: case 'k': /* restore saved position */ 2010: 2011: gotoxy(v, v->savex, v->savey); 2012: 2013: break; 2014: 2015: case 'l': /* clear line */ 2016: 1.1.1.3 ! root 2017: v->cx = 0; ! 2018: ! 2019: i = cy + cy; ! 2020: ! 2021: i += i; ! 2022: ! 2023: v->cursaddr = base + *(long *)(rowoff + i); 1.1 root 2024: 2025: clrline(v, cy); 2026: 2027: break; 2028: 2029: case 'o': /* clear from start of line to cursor */ 2030: 2031: clrfrom(v, 0, cy, cx, cy); 2032: 2033: break; 2034: 2035: case 'p': /* reverse video on */ 2036: 2037: v->flags |= FINVERSE; 2038: 2039: break; 2040: 2041: case 'q': /* reverse video off */ 2042: 2043: v->flags &= ~FINVERSE; 2044: 2045: break; 2046: 2047: case 'v': /* wrap on */ 2048: 2049: v->flags |= FWRAP; 2050: 2051: break; 2052: 2053: case 'w': 2054: 2055: v->flags &= ~FWRAP; 2056: 2057: break; 2058: 2059: } 2060: 2061: state = normal_putch; 2062: 2063: } 2064: 2065: 2066: 2067: /* 2068: 2069: * escy1_putch(v, c): for when an ESC Y + char has been seen 2070: 2071: */ 2072: 2073: static void 2074: 2075: escy1_putch(v, c) 2076: 2077: SCREEN *v; 2078: 2079: int c; 2080: 2081: { 2082: 2083: gotoxy(v, c - ' ', escy1 - ' '); 2084: 2085: state = normal_putch; 2086: 2087: } 2088: 2089: 2090: 2091: /* 2092: 2093: * escy_putch(v, c): for when an ESC Y has been seen 2094: 2095: */ 2096: 2097: static void 2098: 2099: escy_putch(v, c) 2100: 2101: SCREEN *v; 2102: 2103: int c; 2104: 2105: { 2106: 1.1.1.2 root 2107: UNUSED(v); 2108: 1.1 root 2109: escy1 = c; 2110: 2111: state = escy1_putch; 2112: 2113: } 2114: 2115: 2116: 2117: /* 2118: 2119: * normal_putch(v, c): put character 'c' on screen 'v'. This is the default 2120: 2121: * for when no escape, etc. is active 2122: 2123: */ 2124: 2125: 2126: 2127: static void 2128: 2129: normal_putch(v, c) 2130: 2131: SCREEN *v; 2132: 2133: int c; 2134: 2135: { 2136: 1.1.1.3 ! root 2137: register int i; ! 2138: ! 2139: ! 2140: 1.1 root 2141: /* control characters */ 2142: 2143: if (c < ' ') { 2144: 2145: switch (c) { 2146: 2147: case '\r': 2148: 1.1.1.3 ! root 2149: col0: v->cx = 0; ! 2150: ! 2151: i = v->cy + v->cy; ! 2152: ! 2153: i += i; ! 2154: ! 2155: v->cursaddr = base + *(long *)(rowoff + i); 1.1 root 2156: 2157: return; 2158: 2159: case '\n': 2160: 2161: if (v->cy == v->maxy) { 2162: 2163: scroll(v); 2164: 1.1.1.3 ! root 2165: } else { ! 2166: ! 2167: v->cy++; 1.1 root 2168: 1.1.1.3 ! root 2169: v->cursaddr += v->linelen; 1.1 root 2170: 1.1.1.3 ! root 2171: } 1.1 root 2172: 2173: return; 2174: 2175: case '\b': 2176: 1.1.1.3 ! root 2177: if (v->cx) { ! 2178: ! 2179: v->cx--; ! 2180: ! 2181: v->cursaddr--; ! 2182: ! 2183: if ((i = v->planes-1) && (v->cx & 1)) ! 2184: ! 2185: v->cursaddr -= i+i; ! 2186: ! 2187: } 1.1 root 2188: 2189: return; 2190: 2191: case '\007': /* BELL */ 2192: 2193: (void)bconout(CONDEV, 7); 2194: 2195: return; 2196: 2197: case '\033': /* ESC */ 2198: 2199: state = putesc; 2200: 2201: return; 2202: 2203: case '\t': 2204: 1.1.1.3 ! root 2205: if (v->cx < v->maxx) { ! 2206: ! 2207: register union { ! 2208: ! 2209: long l; ! 2210: ! 2211: short i[2]; ! 2212: ! 2213: } j; ! 2214: ! 2215: j.l = 0; ! 2216: ! 2217: j.i[1] = 8 - (v->cx & 7); ! 2218: ! 2219: v->cx += j.i[1]; ! 2220: ! 2221: if (v->cx - v->maxx > 0) { ! 2222: ! 2223: j.i[1] = v->cx - v->maxx; ! 2224: ! 2225: v->cx = v->maxx; ! 2226: ! 2227: } ! 2228: ! 2229: v->cursaddr += j.l; ! 2230: ! 2231: if ((i = v->planes-1)) { ! 2232: ! 2233: if (j.l & 1) ! 2234: ! 2235: j.i[1]++; ! 2236: ! 2237: do v->cursaddr += j.l; ! 2238: ! 2239: while (--i); ! 2240: ! 2241: } ! 2242: ! 2243: } 1.1 root 2244: 2245: return; 2246: 2247: default: 2248: 2249: return; 2250: 2251: } 2252: 2253: } 2254: 2255: 2256: 2257: (*vpaint)(v, c, v->cursaddr); 2258: 2259: v->cx++; 2260: 2261: if (v->cx > v->maxx) { 2262: 2263: if (v->flags & FWRAP) { 2264: 2265: normal_putch(v, '\n'); 2266: 1.1.1.3 ! root 2267: goto col0; 1.1 root 2268: 2269: } else { 2270: 2271: v->cx = v->maxx; 2272: 2273: } 2274: 2275: } else { 2276: 2277: v->cursaddr++; 2278: 1.1.1.3 ! root 2279: if ((i = v->planes-1) && !(v->cx & 1)) /* new word */ 1.1 root 2280: 1.1.1.3 ! root 2281: v->cursaddr += i + i; 1.1 root 2282: 2283: } 2284: 2285: } 2286: 2287: 2288: 2289: INLINE static void 2290: 2291: put_ch(v, c) 2292: 2293: SCREEN *v; 2294: 2295: int c; 2296: 2297: { 2298: 2299: (*state)(v, c & 0x00ff); 2300: 2301: } 2302: 2303: 2304: 1.1.1.2 root 2305: static long ARGS_ON_STACK screen_open P_((FILEPTR *f)); 1.1 root 2306: 1.1.1.2 root 2307: static long ARGS_ON_STACK screen_read P_((FILEPTR *f, char *buf, long nbytes)); 1.1 root 2308: 1.1.1.2 root 2309: static long ARGS_ON_STACK screen_write P_((FILEPTR *f, const char *buf, long nbytes)); 1.1 root 2310: 1.1.1.2 root 2311: static long ARGS_ON_STACK screen_lseek P_((FILEPTR *f, long where, int whence)); 1.1 root 2312: 1.1.1.2 root 2313: static long ARGS_ON_STACK screen_ioctl P_((FILEPTR *f, int mode, void *buf)); 1.1 root 2314: 1.1.1.2 root 2315: static long ARGS_ON_STACK screen_close P_((FILEPTR *f, int pid)); 1.1 root 2316: 1.1.1.2 root 2317: static long ARGS_ON_STACK screen_select P_((FILEPTR *f, long p, int mode)); 1.1 root 2318: 1.1.1.2 root 2319: static void ARGS_ON_STACK screen_unselect P_((FILEPTR *f, long p, int mode)); 1.1 root 2320: 2321: 2322: 1.1.1.2 root 2323: extern long ARGS_ON_STACK null_datime P_((FILEPTR *f, short *time, int rwflag)); 1.1 root 2324: 2325: 2326: 2327: DEVDRV screen_device = { 2328: 2329: screen_open, screen_write, screen_read, screen_lseek, screen_ioctl, 2330: 2331: null_datime, screen_close, screen_select, screen_unselect 2332: 2333: }; 2334: 2335: 2336: 1.1.1.2 root 2337: static long ARGS_ON_STACK 1.1 root 2338: 2339: screen_open(f) 2340: 2341: FILEPTR *f; 2342: 2343: { 2344: 2345: 2346: 2347: if (!current) { 2348: 2349: init(); 2350: 2351: } else 2352: 2353: return EACCDN; /* screen in use */ 2354: 2355: 2356: 2357: f->flags |= O_TTY; 2358: 2359: return 0; 2360: 2361: } 2362: 2363: 2364: 1.1.1.2 root 2365: static long ARGS_ON_STACK 1.1 root 2366: 2367: screen_close(f, pid) 2368: 2369: FILEPTR *f; 2370: 2371: int pid; 2372: 2373: { 2374: 1.1.1.2 root 2375: UNUSED(pid); 2376: 2377: 2378: 1.1 root 2379: if (f->links <= 0) { 2380: 2381: if (hardbase) { 2382: 2383: quickmove(oldbase, base, scrnsize); 2384: 2385: base = oldbase; 2386: 2387: Setscreen(oldbase, oldbase, -1); 2388: 2389: } 2390: 2391: current = 0; 2392: 2393: } 2394: 2395: return 0; 2396: 2397: } 2398: 2399: 2400: 1.1.1.2 root 2401: static long ARGS_ON_STACK 1.1 root 2402: 2403: screen_write(f, buf, bytes) 2404: 2405: FILEPTR *f; const char *buf; long bytes; 2406: 2407: { 2408: 2409: SCREEN *v = current; 2410: 2411: long *r; 2412: 2413: long ret = 0; 2414: 2415: int c; 2416: 2417: 2418: 1.1.1.2 root 2419: UNUSED(f); 2420: 2421: 2422: 1.1 root 2423: (void)checkkeys(); 2424: 2425: v->hidecnt++; 2426: 2427: v->flags |= CURS_UPD; /* for TOS 1.0 */ 2428: 1.1.1.2 root 2429: curs_off(v); 2430: 1.1 root 2431: r = (long *)buf; 2432: 2433: while (bytes > 0) { 2434: 1.1.1.2 root 2435: c = (int) *r++; 1.1 root 2436: 2437: put_ch(v, c); 2438: 2439: bytes -= 4; ret+= 4; 2440: 2441: } 2442: 1.1.1.2 root 2443: if (v->hidecnt > 0) 1.1 root 2444: 1.1.1.2 root 2445: --v->hidecnt; 2446: 2447: else 2448: 2449: v->hidecnt = 0; 1.1 root 2450: 2451: curs_on(v); 2452: 1.1.1.2 root 2453: v->flags &= ~CURS_UPD; 2454: 1.1 root 2455: return ret; 2456: 2457: } 2458: 2459: 2460: 1.1.1.2 root 2461: static long ARGS_ON_STACK 1.1 root 2462: 2463: screen_read(f, buf, bytes) 2464: 2465: FILEPTR *f; char *buf; long bytes; 2466: 2467: { 2468: 2469: long *r, ret = 0; 2470: 2471: 2472: 2473: r = (long *)buf; 2474: 2475: 2476: 2477: while (bytes > 0) { 2478: 2479: if ( (f->flags & O_NDELAY) && !bconstat(CONDEV) ) 2480: 2481: break; 2482: 1.1.1.2 root 2483: *r++ = bconin(CONDEV) & 0x7fffffffL; 1.1 root 2484: 2485: bytes -= 4; ret += 4; 2486: 2487: } 2488: 2489: return ret; 2490: 2491: } 2492: 2493: 2494: 1.1.1.2 root 2495: static long ARGS_ON_STACK 1.1 root 2496: 2497: screen_lseek(f, where, whence) 2498: 2499: FILEPTR *f; 2500: 2501: long where; 2502: 2503: int whence; 2504: 2505: { 2506: 2507: /* terminals always are at position 0 */ 2508: 1.1.1.2 root 2509: UNUSED(f); UNUSED(where); 2510: 2511: UNUSED(whence); 2512: 1.1 root 2513: return 0; 2514: 2515: } 2516: 2517: 2518: 1.1.1.2 root 2519: static long ARGS_ON_STACK 1.1 root 2520: 2521: screen_ioctl(f, mode, buf) 2522: 2523: FILEPTR *f; int mode; void *buf; 2524: 2525: { 2526: 2527: long *r = (long *)buf; 2528: 2529: struct winsize *w; 2530: 2531: 2532: 1.1.1.2 root 2533: UNUSED(f); 2534: 2535: 2536: 1.1 root 2537: if (mode == FIONREAD) { 2538: 2539: if (bconstat(CONDEV)) 2540: 2541: *r = 1; 2542: 2543: else 2544: 2545: *r = 0; 2546: 2547: } 2548: 2549: else if (mode == FIONWRITE) { 2550: 2551: *r = 1; 2552: 2553: } 2554: 2555: else if (mode == TIOCFLUSH) { 2556: 2557: /* BUG: this should flush the input/output buffers */ 2558: 2559: return 0; 2560: 2561: } 2562: 2563: else if (mode == TIOCGWINSZ) { 2564: 2565: w = (struct winsize *)buf; 2566: 2567: w->ws_row = current->maxy+1; 2568: 2569: w->ws_col = current->maxx+1; 2570: 2571: } 2572: 1.1.1.2 root 2573: else if (mode >= TCURSOFF && mode <= TCURSGRATE) { 2574: 2575: SCREEN *v = current; 2576: 2577: switch(mode) { 2578: 2579: case TCURSOFF: 1.1 root 2580: 1.1.1.2 root 2581: curs_off(v); 2582: 2583: v->hidecnt++; 2584: 2585: v->flags &= ~CURS_ON; 2586: 2587: break; 2588: 2589: case TCURSON: 2590: 2591: v->flags |= CURS_ON; 2592: 2593: v->hidecnt = 0; 2594: 2595: curs_on(v); 2596: 2597: break; 2598: 2599: case TCURSBLINK: 2600: 2601: curs_off(v); 2602: 2603: v->flags |= CURS_FLASH; 2604: 2605: curs_on(v); 2606: 2607: break; 2608: 2609: case TCURSSTEADY: 2610: 2611: curs_off(v); 2612: 2613: v->flags &= ~CURS_FLASH; 2614: 2615: curs_on(v); 2616: 2617: break; 2618: 2619: case TCURSSRATE: 2620: 2621: v->period = *((short *)buf); 2622: 2623: break; 2624: 2625: case TCURSGRATE: 2626: 2627: return v->period; 2628: 2629: } 2630: 2631: } else 2632: 2633: return EINVFN; 1.1 root 2634: 2635: 2636: 2637: return 0; 2638: 2639: } 2640: 2641: 2642: 1.1.1.2 root 2643: static long ARGS_ON_STACK 1.1 root 2644: 2645: screen_select(f, p, mode) 2646: 2647: FILEPTR *f; long p; int mode; 2648: 2649: { 2650: 2651: struct tty *tty = (struct tty *)f->devinfo; 2652: 2653: int dev = CONDEV; 2654: 2655: 2656: 2657: if (mode == O_RDONLY) { 2658: 2659: if (bconstat(dev)) { 2660: 2661: return 1; 2662: 2663: } 2664: 2665: if (tty) { 2666: 2667: /* avoid collisions with other processes */ 2668: 2669: if (!tty->rsel) 2670: 2671: tty->rsel = p; 2672: 2673: } 2674: 2675: return 0; 2676: 2677: } else if (mode == O_WRONLY) { 2678: 2679: return 1; 2680: 2681: } 2682: 2683: /* default -- we don't know this mode, return 0 */ 2684: 2685: return 0; 2686: 2687: } 2688: 2689: 2690: 1.1.1.2 root 2691: static void ARGS_ON_STACK 1.1 root 2692: 2693: screen_unselect(f, p, mode) 2694: 2695: FILEPTR *f; 2696: 2697: long p; 2698: 2699: int mode; 2700: 2701: { 2702: 2703: struct tty *tty = (struct tty *)f->devinfo; 2704: 2705: 2706: 2707: if (tty) { 2708: 2709: if (mode == O_RDONLY && tty->rsel == p) 2710: 2711: tty->rsel = 0; 2712: 2713: else if (mode == O_WRONLY && tty->wsel == p) 2714: 2715: tty->wsel = 0; 2716: 2717: } 2718: 2719: } 2720: 2721: 2722: 2723: #endif /* FASTTEXT */ 2724:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.