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