home *** CD-ROM | disk | FTP | other *** search
- #include "mint.h"
- #include "fasttext.h"
-
- #ifdef FASTTEXT
-
- #ifdef __GNUC__
- #define INLINE inline
- #define ITYPE long /* gcc's optimizer likes 32 bit integers */
- #else
- #define INLINE
- #define ITYPE int
- #endif
-
- #define CONDEV (2)
-
- static SCREEN *current;
-
- static void paint P_((SCREEN *, int, char *)),
- paint8c P_((SCREEN *, int, char *)),
- paint16m P_((SCREEN *, int, char *));
-
- INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *));
- INLINE static void flash P_((SCREEN *));
- static void normal_putch P_((SCREEN *, int));
- static void escy_putch P_((SCREEN *, int));
-
- static char *chartab[256];
-
- static long scrnsize;
-
- short hardscroll;
- static char *hardbase, *oldbase;
-
- typedef void (*Vfunc) P_((SCREEN *, int));
-
- #define base *((char **)0x44eL)
- #define escy1 *((short *)0x4acL)
-
- static Vfunc state;
-
- static short hardline;
- static void (*vpaint) P_((SCREEN *, int, char *));
-
- void init P_((void));
- void hardware_scroll P_((SCREEN *));
- INLINE static char *PLACE P_((SCREEN *, int, int));
- INLINE static void gotoxy P_((SCREEN *, int, int));
- INLINE static void clrline P_((SCREEN *, int));
- INLINE static void clear P_((SCREEN *));
- INLINE static void clrchar P_((SCREEN *, int, int));
- INLINE static void clrfrom P_((SCREEN *, int, int, int, int));
- INLINE static void delete_line P_((SCREEN *, int));
- INLINE static void insert_line P_((SCREEN *, int));
- static void setbgcol P_((SCREEN *, int));
- static void setfgcol P_((SCREEN *, int));
- static void putesc P_((SCREEN *, int));
- static void escy1_putch P_((SCREEN *, int));
- INLINE static void put_ch P_((SCREEN *, int));
-
- /* routines for flashing the cursor for screen v */
- /* flash(v): invert the character currently under the cursor */
-
- INLINE static void
- flash(v)
- SCREEN *v;
- {
- char *place, d;
- ITYPE i, j, vplanes;
-
- vplanes = v->planes + v->planes;
- place = v->cursaddr;
-
- for (j = v->cheight; j > 0; --j) {
- d = (*place) ^ 0xff;
- for (i = 0; i < vplanes; i+=2)
- place[i] = d;
-
- place += v->planesiz;
- }
- }
-
- /* make sure the cursor is off */
-
- INLINE
- static void
- curs_off(v)
- SCREEN *v;
- {
- if (v->flags & CURS_ON) {
- if (v->flags & CURS_FSTATE) {
- flash(v);
- v->flags &= ~CURS_FSTATE;
- }
- }
- }
-
- /* OK, show the cursor again (if appropriate) */
-
- INLINE static void
- curs_on(v)
- SCREEN *v;
- {
- if (v->hidecnt) return;
-
- if (v->flags & CURS_ON) {
- /* if the cursor is flashing, we cheat a little and leave it off
- * to be turned on again (if necessary) by the VBL routine
- */
- if (v->flags & CURS_FLASH) {
- v->curstimer = 2;
- return;
- }
- if (!(v->flags & CURS_FSTATE)) {
- v->flags |= CURS_FSTATE;
- flash(v);
- }
- }
- }
-
- void
- init()
- {
- SCREEN *v;
- int i, j;
- char *data, *foo;
- static char chardata[256*16];
-
- foo = lineA0();
- v = (SCREEN *)(foo - 346);
-
- /* Ehem... The screen might be bigger than 32767 bytes.
- Let's do some casting...
- Erling
- */
- scrnsize = (v->maxy+1)*(long)v->linelen;
- if (hardscroll > 0) {
- if (!hardbase)
- hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L)
- & 0xffffff00L);
-
- if (hardbase == 0) {
- ALERT("Insufficient memory for hardware scrolling!");
- } else {
- quickmove(hardbase, base, scrnsize);
- v->cursaddr = v->cursaddr + (hardbase - base);
- oldbase = base;
- base = hardbase;
- Setscreen(hardbase, hardbase, -1);
- }
- }
- hardline = 0;
- if (v->cheight == 8 && v->planes == 2) {
- foo = &chardata[0];
- vpaint = paint8c;
- for (i = 0; i < 256; i++) {
- chartab[i] = foo;
- data = v->fontdata + i;
- for (j = 0; j < 8; j++) {
- *foo++ = *data;
- data += v->form_width;
- }
- }
- } else if (v->cheight == 16 && v->planes == 1) {
- foo = &chardata[0];
- vpaint = paint16m;
- for (i = 0; i < 256; i++) {
- chartab[i] = foo;
- data = v->fontdata + i;
- for (j = 0; j < 16; j++) {
- *foo++ = *data;
- data += v->form_width;
- }
- }
- }
- else
- vpaint = paint;
-
- if (v->hidecnt == 0) {
- /*
- * make sure the cursor is set up correctly and turned on
- */
- (void)Cursconf(0,0); /* turn cursor off */
-
- v->flags &= ~(CURS_FLASH|CURS_FSTATE);
-
- /* now turn the cursor on the way we like it */
- v->hidecnt = 0;
- curs_on(v);
- } else {
- (void)Cursconf(0,0);
- v->flags &= ~CURS_ON;
- v->hidecnt = 1;
- }
-
- current = v;
- state = normal_putch;
- }
-
- /*
- * PLACE(v, x, y): the address corresponding to the upper left hand corner of
- * the character at position (x,y) on screen v
- */
- INLINE static
- char *PLACE(v, x, y)
- SCREEN *v;
- int x, y;
- {
- char *place;
- int i, j;
-
- place = base + x;
- if (y == v->maxy)
- place += scrnsize - v->linelen;
- else if (y) /* Yo, the screen might be bigger than 32767 bytes...
- Do a cast to long. Erling. */
- place += (long)y * v->linelen;
-
- if ((j = v->planes) > 1) {
- i = (x & 0xfffe);
- while (--j > 0)
- place += i;
- }
- return place;
- }
-
- /*
- * paint(v, c, place): put character 'c' at position 'place' on screen
- * v. It is assumed that x, y are proper coordinates!
- * Specialized versions (paint8c and paint16m) of this routine follow;
- * they assume 8 line high characters, medium res. and 16 line/mono,
- * respectively.
- */
-
- static void
- paint(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data, d, doinverse;
- ITYPE j, planecount;
- int vplanes;
- long vform_width, vplanesiz;
-
- vplanes = v->planes;
-
- data = v->fontdata + c;
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- vform_width = v->form_width;
- vplanesiz = v->planesiz;
-
- for (j = v->cheight; j > 0; --j) {
- d = *data ^ doinverse;
- *place = d;
- if (vplanes > 1) {
- /* This should work for an arbitrary number of planes. Erling */
- for(planecount=1;planecount<vplanes;planecount++)
- place[(planecount<<1)]=d;
- #if 0
- {
- place[2] = d;
- if (vplanes > 2) {
- place[4] = place[6] = d;
- }
- }
- #endif
- }
-
- place += vplanesiz;
- data += vform_width;
- }
-
- }
-
- static void
- paint8c(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data;
- char d, doinverse;
- long vplanesiz;
-
- data = chartab[c];
-
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- vplanesiz = v->planesiz;
-
- if (!doinverse) {
- /* line 1 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
- } else {
- /* line 1 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data++ ^ doinverse;
- *place = d;
- place[2] = d;
- place += vplanesiz;
- }
- }
-
- static void
- paint16m(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data;
- char d, doinverse;
- long vplanesiz;
-
- data = chartab[c];
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- vplanesiz = v->planesiz;
-
- if (!doinverse) {
- /* line 1 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 9 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 10 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 11 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 12 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 13 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 14 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 15 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 16 */
- d = *data++;
- *place = d;
- place += vplanesiz;
- } else {
- /* line 1 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 9 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 10 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 11 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 12 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 13 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 14 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 15 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
-
- /* line 16 */
- d = *data++ ^ doinverse;
- *place = d;
- place += vplanesiz;
- }
- }
-
- /*
- * gotoxy (v, x, y): move current cursor address of screen v to (x, y)
- * makes sure that (x, y) will be legal
- */
-
- INLINE static void
- gotoxy(v, x, y)
- SCREEN *v;
- int x, y;
- {
- if (x > v->maxx) x = v->maxx;
- else if (x < 0) x = 0;
- if (y > v->maxy) y = v->maxy;
- else if (y < 0) y = 0;
- curs_off(v);
-
- v->cx = x;
- v->cy = y;
- v->cursaddr = PLACE(v, x, y);
- }
-
- /*
- * clrline(v, r): clear line r of screen v
- */
-
- INLINE static void
- clrline(v, r)
- SCREEN *v;
- int r;
- {
- long *dst;
- long nbytes;
-
- nbytes = v->linelen;
- /* Hey, again the screen might be bigger than 32767 bytes.
- Do another cast... */
- dst = (long *)(base + ((long)r * v->linelen));
- zero((char *)dst, nbytes);
- }
-
- /*
- * clear(v): clear the whole screen v
- */
-
- INLINE static void
- clear(v)
- SCREEN *v;
- {
- zero(base, scrnsize);
- }
-
- /*
- * clrchar(v, x, y): clear the (x,y) position on screen v
- */
-
- INLINE static void
- clrchar(v, x, y)
- SCREEN *v;
- int x, y;
- {
- int i, j, vplanes;
- char *place;
-
- vplanes = v->planes + v->planes;
-
- place = PLACE(v, x, y);
-
- for (j = v->cheight; j > 0; --j) {
- for (i = 0; i < vplanes; i+=2)
- place[i] = 0;
- place += v->planesiz;
- }
- }
-
- /*
- * clrfrom(v, x1, y1, x2, y2): clear screen v from position (x1,y1) to
- * position (x2, y2) inclusive. It is assumed that y2 >= y1.
- */
-
- INLINE static void
- clrfrom(v, x1, y1, x2, y2)
- SCREEN *v;
- int x1,y1,x2,y2;
- {
- int i;
-
- for (i = x1; i <= v->maxx; i++)
- clrchar(v, i, y1);
- if (y2 > y1) {
- for (i = 0; i <= x2; i++)
- clrchar(v, i, y2);
- for (i = y1+1; i < y2; i++)
- clrline(v, i);
- }
- }
-
- /*
- * scroll a screen in hardware; if we still have hardware scrolling lines left,
- * just move the physical screen base, otherwise copy the screen back to the
- * hardware base and start over
- */
- void
- hardware_scroll(v)
- SCREEN *v;
- {
-
- ++hardline;
- if (hardline < hardscroll) { /* just move the screen */
- base += v->linelen;
- v->cursaddr = PLACE(v, v->cx, v->cy);
- Setscreen(base, base, -1);
- }
- else {
- hardline = 0;
- quickmove(hardbase, base + v->linelen, scrnsize - v->linelen);
- base = hardbase;
- v->cursaddr = PLACE(v, v->cx, v->cy);
- Setscreen(hardbase, hardbase, -1);
- }
- }
-
- /*
- * delete_line(v, r): delete line r of screen v. The screen below this
- * line is scrolled up, and the bottom line is cleared.
- */
-
- #define scroll(v) delete_line(v, 0)
-
- INLINE static void
- delete_line(v, r)
- SCREEN *v;
- int r;
- {
- long *src, *dst, nbytes;
-
- if (r == 0) {
- if (hardbase) {
- hardware_scroll(v);
- clrline(v, v->maxy);
- return;
- }
- nbytes = scrnsize - v->linelen;
- }
- else
- nbytes = (long)v->linelen * (v->maxy - r);
-
- /* Sheeze, how many times do we really have to cast...
- Erling.
- */
-
- dst = (long *)(base + ((long)r * v->linelen));
- src = (long *)( ((long)dst) + v->linelen);
-
- quickmove(dst, src, nbytes);
-
- /* clear the last line */
- clrline(v, v->maxy);
- }
-
- /*
- * insert_line(v, r): scroll all of the screen starting at line r down,
- * and then clear line r.
- */
-
- INLINE static void
- insert_line(v, r)
- SCREEN *v;
- int r;
- {
- long *src, *dst;
- int i, limit;
-
- limit = v->maxy;
- for (i = limit-1; i >= r ; --i) {
- /* move line i to line i+1 */
- /* AND do some casting to support big screens.
- Erling
- */
- src = (long *)(base + ((long)i * v->linelen));
- dst = (long *)(base + ((i+1)*(long)v->linelen));
- quickmove(dst, src, v->linelen);
- }
-
- /* clear line r */
- clrline(v, r);
- }
-
- /*
- * special states for handling ESC b x and ESC c x. Note that for now,
- * color is ignored.
- */
-
- static void
- setbgcol(v, c)
- SCREEN *v;
- int c;
- {
- v->bgcol = c & ((1 << v->planes)-1);
- state = normal_putch;
- }
-
- static void
- setfgcol(v, c)
- SCREEN *v;
- int c;
- {
- v->fgcol = c & ((1 << v->planes)-1);
- state = normal_putch;
- }
-
- /*
- * putesc(v, c): handle the control sequence ESC c
- */
-
- static void
- putesc(v, c)
- SCREEN *v;
- int c;
- {
- int cx, cy;
-
- cx = v->cx; cy = v->cy;
-
- switch (c) {
- case 'A': /* cursor up */
- gotoxy(v, cx, cy-1);
- break;
- case 'B': /* cursor down */
- gotoxy(v, cx, cy+1);
- break;
- case 'C': /* cursor right */
- gotoxy(v, cx+1, cy);
- break;
- case 'D': /* cursor left */
- gotoxy(v, cx-1, cy);
- break;
- case 'E': /* clear home */
- curs_off(v);
- clear(v);
- /* fall through... */
- case 'H': /* cursor home */
- gotoxy(v, 0, 0);
- break;
- case 'I': /* cursor up, insert line */
- if (cy == 0) {
- curs_off(v);
- insert_line(v, 0);
- }
- else
- gotoxy(v, cx, cy-1);
- break;
- case 'J': /* clear below cursor */
- curs_off(v);
- clrfrom(v, cx, cy, v->maxx, v->maxy);
- break;
- case 'K': /* clear remainder of line */
- curs_off(v);
- clrfrom(v, cx, cy, v->maxx, cy);
- break;
- case 'L': /* insert a line */
- gotoxy(v, 0, cy);
- insert_line(v, cy);
- break;
- case 'M': /* delete line */
- gotoxy(v, 0, cy);
- delete_line(v, cy);
- break;
- case 'Y':
- state = escy_putch;
- return; /* YES, this should be 'return' */
-
- case 'b':
- state = setfgcol;
- return;
- case 'c':
- state = setbgcol;
- return;
- case 'd': /* clear to cursor position */
- curs_off(v);
- clrfrom(v, 0, 0, cx, cy);
- break;
- case 'e': /* enable cursor */
- curs_off(v);
- v->flags |= CURS_ON;
- v->hidecnt = 1; /* so --v->hidecnt shows the cursor */
- break;
- case 'f': /* cursor off */
- curs_off(v);
- v->hidecnt++;
- v->flags &= ~CURS_ON;
- break;
- case 'j': /* save cursor position */
- v->savex = v->cx;
- v->savey = v->cy;
- break;
- case 'k': /* restore saved position */
- gotoxy(v, v->savex, v->savey);
- break;
- case 'l': /* clear line */
- gotoxy(v, 0, cy);
- clrline(v, cy);
- break;
- case 'o': /* clear from start of line to cursor */
- curs_off(v);
- clrfrom(v, 0, cy, cx, cy);
- break;
- case 'p': /* reverse video on */
- v->flags |= FINVERSE;
- break;
- case 'q': /* reverse video off */
- v->flags &= ~FINVERSE;
- break;
- case 'v': /* wrap on */
- v->flags |= FWRAP;
- break;
- case 'w':
- v->flags &= ~FWRAP;
- break;
- }
- state = normal_putch;
- }
-
- /*
- * escy1_putch(v, c): for when an ESC Y + char has been seen
- */
- static void
- escy1_putch(v, c)
- SCREEN *v;
- int c;
- {
- gotoxy(v, c - ' ', escy1 - ' ');
- state = normal_putch;
- }
-
- /*
- * escy_putch(v, c): for when an ESC Y has been seen
- */
- static void
- escy_putch(v, c)
- SCREEN *v;
- int c;
- {
- escy1 = c;
- state = escy1_putch;
- }
-
- /*
- * normal_putch(v, c): put character 'c' on screen 'v'. This is the default
- * for when no escape, etc. is active
- */
-
- static void
- normal_putch(v, c)
- SCREEN *v;
- int c;
- {
- /* control characters */
- if (c < ' ') {
- switch (c) {
- case '\r':
- gotoxy(v, 0, v->cy);
- return;
- case '\n':
- if (v->cy == v->maxy) {
- curs_off(v);
- scroll(v);
- }
- else
- gotoxy(v, v->cx, v->cy+1);
- return;
- case '\b':
- gotoxy(v, v->cx-1, v->cy);
- return;
- case '\007': /* BELL */
- (void)bconout(CONDEV, 7);
- return;
- case '\033': /* ESC */
- state = putesc;
- return;
- case '\t':
- gotoxy(v, (v->cx + 8) & ~7, v->cy);
- return;
- default:
- return;
- }
- }
-
- (*vpaint)(v, c, v->cursaddr);
- v->flags &= ~CURS_FSTATE; /* we just erased the cursor */
- v->cx++;
- if (v->cx > v->maxx) {
- if (v->flags & FWRAP) {
- v->cx = 0;
- normal_putch(v, '\n');
- v->cursaddr = PLACE(v, v->cx, v->cy);
- } else {
- v->cx = v->maxx;
- }
- } else {
- #if 0
- v->cursaddr = PLACE(v, v->cx, v->cy);
- #else
- v->cursaddr++;
- if ( (v->cx & 1) == 0 && v->planes > 1) { /* new word */
- short skipwords = v->planes - 1;
- v->cursaddr += skipwords+skipwords;
- }
- #endif
- }
- }
-
- INLINE static void
- put_ch(v, c)
- SCREEN *v;
- int c;
- {
- (*state)(v, c & 0x00ff);
- }
-
- static long screen_open P_((FILEPTR *f));
- static long screen_read P_((FILEPTR *f, char *buf, long nbytes));
- static long screen_write P_((FILEPTR *f, const char *buf, long nbytes));
- static long screen_lseek P_((FILEPTR *f, long where, int whence));
- static long screen_ioctl P_((FILEPTR *f, int mode, void *buf));
- static long screen_close P_((FILEPTR *f, int pid));
- static long screen_select P_((FILEPTR *f, long p, int mode));
- static void screen_unselect P_((FILEPTR *f, long p, int mode));
-
- extern long null_datime P_((FILEPTR *f, short *time, int rwflag));
-
- DEVDRV screen_device = {
- screen_open, screen_write, screen_read, screen_lseek, screen_ioctl,
- null_datime, screen_close, screen_select, screen_unselect
- };
-
- static long
- screen_open(f)
- FILEPTR *f;
- {
-
- if (!current) {
- init();
- } else
- return EACCDN; /* screen in use */
-
- f->flags |= O_TTY;
- return 0;
- }
-
- static long
- screen_close(f, pid)
- FILEPTR *f;
- int pid;
- {
- if (f->links <= 0) {
- if (hardbase) {
- quickmove(oldbase, base, scrnsize);
- base = oldbase;
- Setscreen(oldbase, oldbase, -1);
- }
- current = 0;
- }
- return 0;
- }
-
- static long
- screen_write(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- SCREEN *v = current;
- long *r;
- long ret = 0;
- int c;
-
- (void)checkkeys();
- v->hidecnt++;
- v->flags |= CURS_UPD; /* for TOS 1.0 */
- r = (long *)buf;
- while (bytes > 0) {
- c = *r++;
- put_ch(v, c);
- bytes -= 4; ret+= 4;
- }
- --v->hidecnt;
- v->flags &= ~CURS_UPD;
- curs_on(v);
- return ret;
- }
-
- static long
- screen_read(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- long *r, ret = 0;
-
- r = (long *)buf;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bconstat(CONDEV) )
- break;
- *r++ = bconin(CONDEV) & 0x7fffffff;
- bytes -= 4; ret += 4;
- }
- return ret;
- }
-
- static long
- screen_lseek(f, where, whence)
- FILEPTR *f;
- long where;
- int whence;
- {
- /* terminals always are at position 0 */
- return 0;
- }
-
- static long
- screen_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- {
- long *r = (long *)buf;
- struct winsize *w;
-
- if (mode == FIONREAD) {
- if (bconstat(CONDEV))
- *r = 1;
- else
- *r = 0;
- }
- else if (mode == FIONWRITE) {
- *r = 1;
- }
- else if (mode == TIOCFLUSH) {
- /* BUG: this should flush the input/output buffers */
- return 0;
- }
- else if (mode == TIOCGWINSZ) {
- w = (struct winsize *)buf;
- w->ws_row = current->maxy+1;
- w->ws_col = current->maxx+1;
- }
- else
- return tty_ioctl(f, mode, buf);
-
- return 0;
- }
-
- static long
- screen_select(f, p, mode)
- FILEPTR *f; long p; int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
- int dev = CONDEV;
-
- if (mode == O_RDONLY) {
- if (bconstat(dev)) {
- return 1;
- }
- if (tty) {
- /* avoid collisions with other processes */
- if (!tty->rsel)
- tty->rsel = p;
- }
- return 0;
- } else if (mode == O_WRONLY) {
- return 1;
- }
- /* default -- we don't know this mode, return 0 */
- return 0;
- }
-
- static void
- screen_unselect(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
-
- if (tty) {
- if (mode == O_RDONLY && tty->rsel == p)
- tty->rsel = 0;
- else if (mode == O_WRONLY && tty->wsel == p)
- tty->wsel = 0;
- }
- }
-
- #endif /* FASTTEXT */
-