#include "ufk.h" #include "uftcap.h" #define TERMCAP_FILE "/etc/termcap" #define ESCAPE 255 /* cursor control escape */ #define XY 1 /* bit for row or column, on->column */ #define BIAS 2 /* bit for bias */ #define SUB 4 /* subtract from maximum */ #define BCD 8 /* bit for BCD */ #define ASCII 16 /* bit to send position in ASCII */ #define NIL 0 /* Null pointer */ #define DIRSIZE 32 /* Terminal Directory Size */ #define NUMCAP 62 /* Number of capabilities */ #define DATABYTES 4 /* Number of bytes before pointers */ typedef int BOOLEAN; struct ttycap cap; /* Terminal capabilities */ int nrows; /* Number of rows on screen */ int ncols; /* Number of columns on screen */ int p_l_row; /* Physical last row */ int p_l_column; /* Physical last column */ int last_row; /* Last row number (0 origin) */ int last_column; /* Last column number (0 origin) */ int delay; /* Screen settle time in seconds */ int cu_size; /* Size of cursor up string */ int cd_size; /* Size of cursor down string */ int cl_size; /* Size of cursor left string */ int cr_size; /* Size of cursor right string */ int hm_size; /* Size of home up string */ int row; /* Current row number (0 origin) */ int column; /* Current column number (0 origin) */ clreol(x,y) int x; int y; { if (screen && !remote && !nooutput) { if (x >= 0) posit(x,y); fputs(cap.c_blank,stdout); } } clear_screen() /* Clear screen */ { if (screen && !remote && !nooutput) { fputs(cap.c_clear,stdout); if (delay != 0) sleep(delay); row = column = 0; } } curs_on() { if ((cap.c_curon != NIL) && !nooutput) fputs(cap.c_curon, stdout); } curs_off() { if ((cap.c_curoff != NIL) && !nooutput) fputs(cap.c_curoff, stdout); } background() { if ((cap.c_backg != NIL) && !nooutput) fputs(cap.c_backg, stdout); } foreground() { if ((cap.c_foreg != NIL) && !nooutput) fputs(cap.c_foreg, stdout); } posit(x,y) /* Move cursor to specified position */ int x; /* column */ int y; /* row */ { int v; char *c_ptr; char ch; if (((c_ptr = cap.c_pos) != NIL) && screen && !remote && !nooutput) { /* can position cursor */ if (x > last_column) x = last_column; /* truncate x */ if (y > last_row) y = last_row; /* truncate y */ while ((v = (*c_ptr++) & 0xff) != NULL) { if (v!=ESCAPE) putchar(v); else if((v = (*c_ptr++) & 0xff) != NULL) { ch = ((v & XY) == 0) ? ((v & SUB) == 0 ? y : p_l_row - y) : ((v & SUB) == 0 ? x : p_l_column - x); if ((v & BIAS) != 0) ch += (unsigned)*c_ptr++; if ((v & BCD) != 0) { ch = (unsigned)ch / 10 << 4 | (unsigned)ch % 10; putchar(ch); } else if ((v & ASCII) != 0) { putchar((unsigned)ch / 10 + '0'); putchar((unsigned)ch % 10 + '0'); } else putchar(ch); } } column = x; row = y; } } BOOLEAN terminit() /* Initialize terminal */ { if (!termcap(&cap)) return FALSE; if (cap.c_pos == NIL) return FALSE; /* Cursor positioning required */ nrows = (int)cap.c_rows; ncols = (int)cap.c_cols; p_l_row = last_row = nrows - 1; p_l_column = last_column = ncols - 1; delay = (int)cap.c_wait; cu_size = strlen(cap.c_up); cd_size = strlen(cap.c_down); cl_size = strlen(cap.c_left); cr_size = strlen(cap.c_right); hm_size = strlen(cap.c_home); if (cap.c_init != NIL) fputs(cap.c_init,stdout); clear_screen(); return TRUE; } BOOLEAN termcap(cp) /* Get terminal capabilities */ struct ttycap *cp; { char **cap_ptr; int i; int fd; int direc[DIRSIZE]; long lseek(); int open(), read(); if ((fd = open(TERMCAP_FILE,0)) == ERROR) return FALSE; if ((i = read(fd, (char *)direc, sizeof(int) * DIRSIZE)) == -1 || i != sizeof(int) * DIRSIZE || (i = direc[ttyslot()]) == 0 || lseek(fd, (long)i, 0) == -1L || (i = read(fd, (char *)cp, sizeof(struct ttycap))) == -1 || i != sizeof(struct ttycap)) { close(fd); return FALSE; } close(fd); cap_ptr = (char **)((char *)cp + DATABYTES); for (i = NUMCAP; i--; cap_ptr++) if (*cap_ptr != NIL) *cap_ptr += (unsigned)cp; return TRUE; }