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