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