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