From: Faisal Abbas <90.abbasfaisal@gmail.com> Date: Mon, 17 Aug 2015 12:35:01 +0000 (+0500) Subject: curses library for fuzix X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d91eed8bdb28c348aa0832593915e07228c0cc35;p=FUZIX.git curses library for fuzix Copied from minix-vmd project with a few minute changes. tparam.c file from uzix-libc. --- diff --git a/Library/libs/curses/charpick.c b/Library/libs/curses/charpick.c new file mode 100644 index 00000000..732506d3 --- /dev/null +++ b/Library/libs/curses/charpick.c @@ -0,0 +1,34 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Winch(win) returns the character at the current position in */ +/* Window 'win'. */ +/****************************************************************/ + +int winch(WINDOW *win) +{ + return((win->_line[win->_cury][win->_curx]) & 0xff); +} /* winch */ + +/****************************************************************/ +/* Mvinch() moves the stdscr cursor to a new position, then */ +/* Returns the character at that position. */ +/****************************************************************/ + +int mvinch(int y, int x) +{ + if (wmove(stdscr, y, x) == ERR) return(ERR); + return((stdscr->_line[stdscr->_cury][stdscr->_curx]) & 0xff); +} + +/****************************************************************/ +/* Mvwinch() moves the cursor of window 'win' to a new posi- */ +/* Tion, then returns the character at that position. */ +/****************************************************************/ + +int mvwinch(WINDOW *win, int y, int x) +{ + if (wmove(win, y, x) == ERR) return(ERR); + return((win->_line[win->_cury][win->_curx]) & 0xff); +} diff --git a/Library/libs/curses/curs_set.c b/Library/libs/curses/curs_set.c new file mode 100644 index 00000000..486aae03 --- /dev/null +++ b/Library/libs/curses/curs_set.c @@ -0,0 +1,21 @@ +#include +#include "curspriv.h" +#include + +extern char *vi, *ve, *vs; + +void curs_set(int visibility) +{ + switch (visibility) { + case 0: + if (vi) tputs(vi, 1, outc); + break; + case 1: + if (ve) tputs(ve, 1, outc); + case 2: + if (vs) + tputs(vs, 1, outc); + else if (ve) + tputs(ve, 1, outc); + } +} diff --git a/Library/libs/curses/cursesio.c b/Library/libs/curses/cursesio.c new file mode 100644 index 00000000..2b63e27d --- /dev/null +++ b/Library/libs/curses/cursesio.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include "curspriv.h" + +struct termios _orig_tty, _tty; +cursv _cursvar; + +WINDOW *stdscr, *curscr; +int LINES, COLS; +bool NONL; + +char termcap[1024]; /* termcap buffer */ +char tc[200]; /* area to hold string capabilities */ +char *ttytype; /* terminal type from env */ +static char *arp; /* pointer for use in tgetstr */ +char *cp; /* character pointer */ + +char *cl; /* clear screen capability */ +char *cm; /* cursor motion capability */ +char *so; /* start standout capability */ +char *se; /* end standout capability */ +char *mr; /* start of reverse */ +char *me; /* revert to normal */ +char *mb; /* start of blink */ +char *md; /* start of bold */ +char *us; /* start of underscore */ +char *ue; /* end of underscore */ +char *vi; /* cursor invisible */ +char *ve; /* cursor normal */ +char *vs; /* cursor good visible */ +char *as; /* alternative charset start */ +char *ae; /* alternative charset end */ +char *bl; /* ring the bell */ +char *vb; /* visual bell */ + +/* fatal - report error and die. Never returns */ +void fatal(char *s) +{ + (void) fprintf(stderr, "curses: %s\n", s); + exit(1); +} + +/* Outc - call putchar, necessary because putchar is a macro. */ +void outc(int c) +{ + putchar(c); +} + +/* Move cursor to r,c */ +void poscur(int r, int c) +{ + tputs(tgoto(cm, c, r), 1, outc); +} + +/* Clear the screen */ +void clrscr() +{ + tputs(cl, 1, outc); +} + +/* This are terminal independent characters which can be used in curses */ + +unsigned int ACS_ULCORNER; +unsigned int ACS_LLCORNER; +unsigned int ACS_URCORNER; +unsigned int ACS_LRCORNER; +unsigned int ACS_RTEE; +unsigned int ACS_LTEE; +unsigned int ACS_BTEE; +unsigned int ACS_TTEE; +unsigned int ACS_HLINE; +unsigned int ACS_VLINE; +unsigned int ACS_PLUS; +unsigned int ACS_S1; +unsigned int ACS_S9; +unsigned int ACS_DIAMOND; +unsigned int ACS_CKBOARD; +unsigned int ACS_DEGREE; +unsigned int ACS_PLMINUS; +unsigned int ACS_BULLET; +unsigned int ACS_LARROW; +unsigned int ACS_RARROW; +unsigned int ACS_DARROW; +unsigned int ACS_UARROW; +unsigned int ACS_BOARD; +unsigned int ACS_LANTERN; +unsigned int ACS_BLOCK; + +/* These defines describe the full set of grafic block characters which + * can be defined via termcap. + */ + +#define RIGHTARROW 0 +#define LEFTARROW 1 +#define DOWNARROW 2 +#define UPARROW 3 +#define FULLSQUARE 4 +#define GREYSQUARE 5 +#define EMPTYSQUARE 6 +#define LATERN 7 +#define DIAMOND 8 +#define DEGREE 9 +#define PLUSMINUS 10 +#define DOWNRIGHT 11 +#define UPRIGHT 12 +#define UPLEFT 13 +#define DOWNLEFT 14 +#define CROSS 15 +#define UPLINE 16 +#define UPMIDLINE 17 +#define MIDLINE 18 +#define DOMIDLINE 19 +#define DOWNLINE 20 +#define TEELEFT 21 +#define TEERIGHT 22 +#define TEEHEAD 23 +#define TEENORMAL 24 +#define VERTLINE 25 +#define PARAGRAPH 26 + +unsigned int _cursgraftable[27] = +{ + '>', '<', 'v', '^', '#', ':', ' ', '#', '+', '\'', '#', '+', '+', + '+', '+', '+', '-', ' ', '-', ' ', '_', '+', '+', '+', '+', '|' +}; +char _cursident[28] = "+,.-0ahI`fgjklmnopqrstuvwx~"; + +int setterm(char *type) +{ + unsigned char *ac; + int i; +#ifdef TIOCGWINSZ + struct winsize wsize; +#endif + + if (tgetent(termcap, type) != 1) return ERR; + +#ifdef TIOCGWINSZ + if (ioctl(0, TIOCGWINSZ, &wsize) == 0) { + LINES = wsize.ws_row != 0 ? wsize.ws_row : tgetnum("li"); + COLS = wsize.ws_col != 0 ? wsize.ws_col : tgetnum("co"); + } else { +#endif + LINES = tgetnum("li"); + COLS = tgetnum("co"); +#ifdef TIOCGWINSZ + } +#endif + + arp = tc; + cl = tgetstr("cl", &arp); + so = tgetstr("so", &arp); + se = tgetstr("se", &arp); + cm = tgetstr("cm", &arp); + mr = tgetstr("mr", &arp); + me = tgetstr("me", &arp); + mb = tgetstr("mb", &arp); + md = tgetstr("md", &arp); + us = tgetstr("us", &arp); + ue = tgetstr("ue", &arp); + vi = tgetstr("vi", &arp); + ve = tgetstr("ve", &arp); + vs = tgetstr("vs", &arp); + as = tgetstr("as", &arp); + ae = tgetstr("ae", &arp); + ac = (unsigned char *) tgetstr("ac", &arp); + bl = tgetstr("bl", &arp); + vb = tgetstr("vb", &arp); + + if (ac) { + while (*ac) { + i = 0; + while (*ac != _cursident[i]) i++; + _cursgraftable[i] = *++ac | A_ALTCHARSET; + ac++; + } + } + + ACS_ULCORNER = _cursgraftable[UPLEFT]; + ACS_LLCORNER = _cursgraftable[DOWNLEFT]; + ACS_URCORNER = _cursgraftable[UPRIGHT]; + ACS_LRCORNER = _cursgraftable[DOWNRIGHT]; + ACS_RTEE = _cursgraftable[TEERIGHT]; + ACS_LTEE = _cursgraftable[TEELEFT]; + ACS_BTEE = _cursgraftable[TEEHEAD]; + ACS_TTEE = _cursgraftable[TEENORMAL]; + ACS_HLINE = _cursgraftable[MIDLINE]; + ACS_VLINE = _cursgraftable[VERTLINE]; + ACS_PLUS = _cursgraftable[CROSS]; + ACS_S1 = _cursgraftable[UPLINE]; + ACS_S9 = _cursgraftable[DOWNLINE]; + ACS_DIAMOND = _cursgraftable[DIAMOND]; + ACS_CKBOARD = _cursgraftable[GREYSQUARE]; + ACS_DEGREE = _cursgraftable[DEGREE]; + ACS_PLMINUS = _cursgraftable[PLUSMINUS]; + ACS_BULLET = 'o'; /* where the hell is a bullet defined in + * termcap ??? */ + ACS_LARROW = _cursgraftable[LEFTARROW]; + ACS_RARROW = _cursgraftable[RIGHTARROW]; + ACS_DARROW = _cursgraftable[DOWNARROW]; + ACS_UARROW = _cursgraftable[UPARROW]; + ACS_BOARD = _cursgraftable[EMPTYSQUARE]; + ACS_LANTERN = _cursgraftable[LATERN]; + ACS_BLOCK = _cursgraftable[FULLSQUARE]; + /* Wow, I got it! */ + return OK; +} + +void gettmode() +{ + tcgetattr(0, &_orig_tty); + tcgetattr(0, &_tty); + _cursvar.echoit = (_tty.c_lflag & ECHO) != 0; + _cursvar.rawmode = (_tty.c_lflag & (ICANON|ISIG)) == 0; + _cursvar.cbrkmode = (_tty.c_lflag & (ICANON|ISIG)) == ISIG; + NONL = (_tty.c_iflag & ICRNL) != 0; +} diff --git a/Library/libs/curses/curspriv.h b/Library/libs/curses/curspriv.h new file mode 100644 index 00000000..f4b1a543 --- /dev/null +++ b/Library/libs/curses/curspriv.h @@ -0,0 +1,37 @@ +/* Constants */ +#define _SUBWIN 1 /* window is a subwindow */ +#define _ENDLINE 2 /* last winline is last screen line */ +#define _FULLWIN 4 /* window fills screen */ +#define _SCROLLWIN 8 /* window lwr rgt is screen lwr rgt */ + +#define _NO_CHANGE -1 /* flags line edge unchanged */ +#define _BREAKCHAR 0x03 /* ^C character */ +#define _DCCHAR 0x08 /* Delete Char char (BS) */ +#define _DLCHAR 0x1b /* Delete Line char (ESC) */ +#define _GOCHAR 0x11 /* ^Q character */ +#define _PRINTCHAR 0x10 /* ^P character */ +#define _STOPCHAR 0x13 /* ^S character */ +#define NUNGETCH 10 /* max # chars to ungetch() */ + +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +/* Character mask definitions. */ +#define CHR_MSK ((int) 0x00ff) /* ASCIIZ character mask */ +#define ATR_MSK ((int) 0xff00) /* attribute mask */ +#define ATR_NRM ((int) 0x0000) /* no special attributes */ + +/* Type declarations. */ + + +typedef struct { + WINDOW *tmpwin; /* window used for updates */ + int cursrow; /* position of physical cursor */ + int curscol; + int rawmode; + int cbrkmode; + int echoit; +} cursv; + +/* External variables */ +extern cursv _cursvar; /* curses variables */ diff --git a/Library/libs/curses/doupdt.c b/Library/libs/curses/doupdt.c new file mode 100644 index 00000000..08db7fc6 --- /dev/null +++ b/Library/libs/curses/doupdt.c @@ -0,0 +1,168 @@ +#include +#include "curspriv.h" +#include + +static WINDOW *twin; /* used by many routines */ + +/****************************************************************/ +/* Gotoxy() moves the physical cursor to the desired address on */ +/* The screen. We don't optimize here - on a PC, it takes more */ +/* Time to optimize than to do things directly. */ +/****************************************************************/ + +_PROTOTYPE(static void gotoxy, (int row, int col )); +_PROTOTYPE(static void newattr, (int ch )); +_PROTOTYPE(static void Putchar, (int ch )); +_PROTOTYPE(static void clrupdate, (WINDOW *scr )); +_PROTOTYPE(static void transformline, (int lineno )); + +static void gotoxy(int row, int col) +{ + poscur(row, col); + _cursvar.cursrow = row; + _cursvar.curscol = col; +} + +/* Update attributes */ +static void newattr(int ch) +{ + extern char *me, *as, *ae, *mb, *md, *mr, *so, *us; + static int lastattr = 0; + + if (lastattr != (ch &= ATR_MSK)) { + lastattr = ch; + + tputs(me, 1, outc); + if (ae) tputs(ae, 1, outc); + + if (ch & A_ALTCHARSET) + if (as) tputs(as, 1, outc); + if (ch & A_BLINK) tputs(mb, 1, outc); + if (ch & A_BOLD) tputs(md, 1, outc); + if (ch & A_REVERSE) tputs(mr, 1, outc); + if (ch & A_STANDOUT) tputs(so, 1, outc); + if (ch & A_UNDERLINE) tputs(us, 1, outc); + } +} + +/* Putchar() writes a character, with attributes, to the physical + screen, but avoids writing to the lower right screen position. + Should it care about am? +*/ + +/* Output char with attribute */ +static void Putchar(int ch) +{ + if ((_cursvar.cursrow < LINES) || (_cursvar.curscol < COLS)) { + newattr(ch); + putchar(ch); + } +} + +/****************************************************************/ +/* Clrupdate(scr) updates the screen by clearing it and then */ +/* Redraw it in it's entirety. */ +/****************************************************************/ + +static void clrupdate(WINDOW *scr) +{ + register int *src; + register int *dst; + register int i; + register int j; + WINDOW *w; + + w = curscr; + + if (scr != w) { /* copy scr to curscr */ + for (i = 0; i < LINES; i++) { + src = scr->_line[i]; + dst = w->_line[i]; + for (j = 0; j < COLS; j++) *dst++ = *src++; + } /* for */ + } /* if */ + newattr(scr->_attrs); + clrscr(); + scr->_clear = FALSE; + for (i = 0; i < LINES; i++) { /* update physical screen */ + src = w->_line[i]; + j = 0; + while (j < COLS) { + if (*src != (' ' | ATR_NRM)) { + gotoxy(i, j); + while (j < COLS && (*src != (' ' | ATR_NRM))) { + Putchar(*src++); + j++; + } + } else { + src++; + j++; + } + } /* for */ + } /* for */ + fflush(stdout); +} /* clrupdate */ + +/****************************************************************/ +/* Transformline() updates the given physical line to look */ +/* Like the corresponding line in _cursvar.tmpwin. */ +/****************************************************************/ + +static void transformline(register int lineno) +{ + register int *dstp; + register int *srcp; + register int dstc; + register int srcc; + int x; + int endx; + + x = twin->_minchng[lineno]; + endx = twin->_maxchng[lineno]; + dstp = curscr->_line[lineno] + x; + srcp = twin->_line[lineno] + x; + + while (x <= endx) { + if (*dstp != *srcp) { + gotoxy(lineno, x); + while (x <= endx && (*dstp != *srcp)) { + Putchar(*srcp); + *dstp++ = *srcp++; + x++; + } + } else { + *dstp++ = *srcp++; + x++; + } + } /* for */ + twin->_minchng[lineno] = _NO_CHANGE; + twin->_maxchng[lineno] = _NO_CHANGE; +} /* transformline */ + +/****************************************************************/ +/* Doupdate() updates the physical screen to look like _curs- */ +/* Var.tmpwin if curscr is not 'Clear-marked'. Otherwise it */ +/* Updates the screen to look like curscr. */ +/****************************************************************/ + +void doupdate() +{ + int i; + + twin = _cursvar.tmpwin; + if (curscr->_clear) + clrupdate(curscr); + else { + if (twin->_clear) + clrupdate(twin); + else { + for (i = 0; i < LINES; i++) + if (twin->_minchng[i] != _NO_CHANGE) + transformline(i); + } + } + curscr->_curx = twin->_curx; + curscr->_cury = twin->_cury; + gotoxy(curscr->_cury, curscr->_curx); + fflush(stdout); +} /* doupdate */ diff --git a/Library/libs/curses/endwin.c b/Library/libs/curses/endwin.c new file mode 100644 index 00000000..af167c29 --- /dev/null +++ b/Library/libs/curses/endwin.c @@ -0,0 +1,23 @@ +#include +#include "curspriv.h" +#include + +int endwin() +{ + extern char *me; + + //curs_set(1); + refresh(); + + poscur(LINES - 1, 0); + + tputs(me, 1, outc); + + delwin(stdscr); + delwin(curscr); + delwin(_cursvar.tmpwin); + + tcsetattr(1, TCSANOW, &_orig_tty); + + return (OK); +} diff --git a/Library/libs/curses/initscr.c b/Library/libs/curses/initscr.c new file mode 100644 index 00000000..84df5cef --- /dev/null +++ b/Library/libs/curses/initscr.c @@ -0,0 +1,22 @@ +/* initscr.c - initialize the curses library */ + +#include +#include +#include "curspriv.h" + +WINDOW *initscr() +{ + char *term; + + if ((term = getenv("TERM")) == NULL) return NULL; + setterm(term); + gettmode(); + if ((_cursvar.tmpwin = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) + return NULL; + if ((curscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) + return NULL; + if ((stdscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)ERR) + return NULL; + clearok(curscr, TRUE); + return(stdscr); +} diff --git a/Library/libs/curses/move.c b/Library/libs/curses/move.c new file mode 100644 index 00000000..16f1dab9 --- /dev/null +++ b/Library/libs/curses/move.c @@ -0,0 +1,12 @@ +#include +#include "curspriv.h" + +int wmove(WINDOW *win, int y, int x) +{ + if ((x < 0) || (x > win->_maxx) || (y < win->_regtop) || (y > win->_regbottom)) + return (ERR); + + win->_curx = x; + win->_cury = y; + return (OK); +} diff --git a/Library/libs/curses/mvcursor.c b/Library/libs/curses/mvcursor.c new file mode 100644 index 00000000..7fb9bb50 --- /dev/null +++ b/Library/libs/curses/mvcursor.c @@ -0,0 +1,16 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Mvcur(oldy,oldx,newy,newx) the display cursor to */ +/****************************************************************/ + +int mvcur(int oldx, int oldy, int newy, int newx) +{ + if ((newy >= LINES) || (newx >= COLS) || (newy < 0) || (newx < 0)) + return(ERR); + poscur(newy, newx); + _cursvar.cursrow = newy; + _cursvar.curscol = newx; + return(OK); +} diff --git a/Library/libs/curses/newwin.c b/Library/libs/curses/newwin.c new file mode 100644 index 00000000..918ee871 --- /dev/null +++ b/Library/libs/curses/newwin.c @@ -0,0 +1,140 @@ +#include +#include +#include "curspriv.h" + +/****************************************************************/ +/* Makenew() allocates all data for a new window except the */ +/* Actual lines themselves. */ +/****************************************************************/ + +_PROTOTYPE(static WINDOW *makenew, (int nlines, int ncols, int begy,int begx)); + +static WINDOW *makenew(int num_lines, int num_columns, int begy, int begx) +{ + int i; + WINDOW *win; + + /* Allocate the window structure itself */ + if ((win = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) + return((WINDOW *) ERR); + + /* Allocate the line pointer array */ + if ((win->_line = (int **) calloc(num_lines, sizeof(int *))) == NULL) { + free(win); + return((WINDOW *) ERR); + } + + /* Allocate the minchng and maxchng arrays */ + if ((win->_minchng = (int *) calloc(num_lines, sizeof(int))) == NULL) { + free(win); + free(win->_line); + return((WINDOW *) ERR); + } + if ((win->_maxchng = (int *) calloc(num_lines, sizeof(int))) == NULL) { + free(win); + free(win->_line); + free(win->_minchng); + return((WINDOW *) ERR); + } + + /* Initialize window variables */ + win->_curx = 0; + win->_cury = 0; + win->_maxy = num_lines - 1; + win->_maxx = num_columns - 1; + win->_begy = begy; + win->_begx = begx; + win->_flags = 0; + win->_attrs = ATR_NRM; + win->_tabsize = 8; + win->_clear = FALSE; + win->_leave = FALSE; + win->_scroll = FALSE; + win->_nodelay = FALSE; + win->_keypad = FALSE; + win->_regtop = 0; + win->_regbottom = num_lines - 1; + + /* Init to say window unchanged */ + for (i = 0; i < num_lines; i++) { + win->_minchng[i] = 0; + win->_maxchng[i] = num_columns - 1; + } + + /* Set flags for window properties */ + if ((begy + num_lines) == LINES) { + win->_flags |= _ENDLINE; + if ((begx == 0) && (num_columns == COLS) && (begy == 0)) + win->_flags |= _FULLWIN; + } /* if */ + if (((begy + num_lines) == LINES) && ((begx + num_columns) == COLS)) + win->_flags |= _SCROLLWIN; + return(win); +} + + +/****************************************************************/ +/* Newwin() creates a new window with size num_lines * num_co- */ +/* Lumns, and origin begx,begy relative to the SCREEN. Special */ +/* Case: if num_lines and/or num_columns is 0, the remainder of */ +/* The screen is used. */ +/****************************************************************/ +WINDOW *newwin(int num_lines, int num_columns, int begy, int begx) +{ + WINDOW *win; + int *ptr; + int i, j; + + if (num_lines == 0) num_lines = LINES - begy; + if (num_columns == 0) num_columns = COLS - begx; + if ((win = makenew(num_lines, num_columns, begy, begx)) == (WINDOW *) ERR) + return((WINDOW *) ERR); + for (i = 0; i < num_lines; i++) { /* make and clear the lines */ + if ((win->_line[i] = (int *)calloc(num_columns, sizeof(int))) == NULL){ + for (j = 0; j < i; j++) /* if error, free all the data */ + free(win->_line[j]); + free(win->_minchng); + free(win->_maxchng); + free(win->_line); + free(win); + return((WINDOW *) ERR); + } else { + for (ptr = win->_line[i]; ptr < win->_line[i] + num_columns;) + *ptr++ = ' ' | ATR_NRM; + } + } + return(win); +} + + +/****************************************************************/ +/* Subwin() creates a sub-window in the 'orig' window, with */ +/* Size num_lines * num_columns, and with origin begx, begy */ +/* Relative to the SCREEN. Special case: if num_lines and/or */ +/* Num_columns is 0, the remainder of the original window is */ +/* Used. The subwindow uses the original window's line buffers */ +/* To store it's own lines. */ +/****************************************************************/ +WINDOW *subwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) +{ + WINDOW *win; + int i, j, k; + + /* Make sure window fits inside the original one */ + if (begy < orig->_begy || begx < orig->_begx || + (begy + num_lines) > (orig->_begy + orig->_maxy) || + (begx + num_columns) > (orig->_begx + orig->_maxx) ) + return((WINDOW *) ERR); + + if (num_lines == 0) num_lines = orig->_maxy - (begy - orig->_begy); + if (num_columns == 0) num_columns = orig->_maxx - (begx - orig->_begx); + if ((win = makenew(num_lines, num_columns, begy, begx)) == (WINDOW *) ERR) + return((WINDOW *) ERR); + + /* Set line pointers the same as in the original window */ + j = begy - orig->_begy; + k = begx - orig->_begx; + for (i = 0; i < num_lines; i++) win->_line[i] = (orig->_line[j++]) + k; + win->_flags |= _SUBWIN; + return(win); +} diff --git a/Library/libs/curses/options.c b/Library/libs/curses/options.c new file mode 100644 index 00000000..23f6541f --- /dev/null +++ b/Library/libs/curses/options.c @@ -0,0 +1,71 @@ +#include +#include "curspriv.h" + +static bool hasold = FALSE; /* for remembering old cursor type */ +static int oldmode; + +/****************************************************************/ +/* Idlok() is used to set flag for using the terminal insert/ */ +/* Delete line capabilities. This is not relevant for the PC */ +/* Version of curses, and thus nothing is done. */ +/****************************************************************/ +void idlok(WINDOW *win, bool flag) +{ +} +/****************************************************************/ +/* Clearok() marks window 'win' to cause screen clearing and */ +/* Redraw the next time a refresh is done. */ +/****************************************************************/ +void clearok(WINDOW *win, bool flag) +{ + if (win == curscr) + _cursvar.tmpwin->_clear = flag; + else + win->_clear = flag; +} + +/****************************************************************/ +/* Leaveok() marks window 'win' to allow the update routines */ +/* To leave the hardware cursor where it happens to be at the */ +/* End of update. Usually used in combination with cursoff(). */ +/****************************************************************/ + +void leaveok(WINDOW *win, bool flag) +{ + win->_leave = flag; +} + +/****************************************************************/ +/* Scrollok() marks window 'win' to allow the scrolling region */ +/* Of it to actually scroll. */ +/****************************************************************/ +void scrollok(WINDOW *win, bool flag) +{ + win->_scroll = flag; +} + +/****************************************************************/ +/* Nodelay() marks the window to make character input non- */ +/* Waiting, i.e. if there is no character to get, -1 will be */ +/* Returned. */ +/****************************************************************/ +void nodelay(WINDOW *win, bool flag) +{ + win->_nodelay = flag; +} + +/****************************************************************/ +/* Keypad() marks window 'win' to use the special keypad mode. */ +/****************************************************************/ +void keypad(WINDOW *win, bool flag) +{ +} + +/****************************************************************/ +/* Meta() allows use of any alternate character set allowed by */ +/* The terminal. We always allow this on the PC, so this one */ +/* Does nothing. */ +/****************************************************************/ +void meta(WINDOW *win, int flag) +{ +} diff --git a/Library/libs/curses/overlay.c b/Library/libs/curses/overlay.c new file mode 100644 index 00000000..705db3e2 --- /dev/null +++ b/Library/libs/curses/overlay.c @@ -0,0 +1,122 @@ +/****************************************************************/ +/* Overlay() and overwrite() functions of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Overlay() overwrites 'win1' upon 'win2', with origins alig- */ +/* Ned. Overlay is transparent; blanks from 'win1' are not */ +/* Copied to 'win2'. */ +/****************************************************************/ +void overlay(WINDOW *win1, WINDOW *win2) +{ + int *minchng; + int *maxchng; + int *w1ptr; + int *w2ptr; + int attrs; + int col; + int line; + int last_line; + int last_col; + + last_col = min(win1->_maxx, win2->_maxx); + last_line = min(win1->_maxy, win2->_maxy); + attrs = win2->_attrs & ATR_MSK; + minchng = win2->_minchng; + maxchng = win2->_maxchng; + + for (line = 0; line <= last_line; line++) { + register short fc, lc = 0; + w1ptr = win1->_line[line]; + w2ptr = win2->_line[line]; + fc = _NO_CHANGE; + for (col = 0; col <= last_col; col++) { + if ((*w1ptr & CHR_MSK) != ' ') { + *w2ptr = (*w1ptr & CHR_MSK) | attrs; + if (fc == _NO_CHANGE) fc = col; + lc = col; + } + w1ptr++; + w2ptr++; + } + + if (*minchng == _NO_CHANGE) { + *minchng = fc; + *maxchng = lc; + } else if (fc != _NO_CHANGE) { + if (fc < *minchng) *minchng = fc; + if (lc > *maxchng) *maxchng = lc; + } + minchng++; + maxchng++; + } /* for */ +} /* overlay */ + +/****************************************************************/ +/* Overwrite() overwrites 'win1' upon 'win2', with origins */ +/* Aligned. Overwrite is non-transparent; blanks from 'win1' */ +/* Are copied to 'win2'. */ +/****************************************************************/ +void overwrite(WINDOW *win1, WINDOW *win2) +{ + int *minchng; + int *maxchng; + int *w1ptr; + int *w2ptr; + int attrs; + int col; + int line; + int last_line; + int last_col; + + last_col = min(win1->_maxx, win2->_maxx); + last_line = min(win1->_maxy, win2->_maxy); + attrs = win2->_attrs & ATR_MSK; + minchng = win2->_minchng; + maxchng = win2->_maxchng; + + for (line = 0; line <= last_line; line++) { + register short fc, lc = 0; + + w1ptr = win1->_line[line]; + w2ptr = win2->_line[line]; + fc = _NO_CHANGE; + + for (col = 0; col <= last_col; col++) { + if ((*w1ptr & CHR_MSK) != (*w2ptr & CHR_MSK)) { + *w2ptr = (*w1ptr & CHR_MSK) | attrs; + + if (fc == _NO_CHANGE) fc = col; + lc = col; + } + w1ptr++; + w2ptr++; + } /* for */ + + if (*minchng == _NO_CHANGE) { + *minchng = fc; + *maxchng = lc; + } else if (fc != _NO_CHANGE) { + if (fc < *minchng) *minchng = fc; + if (lc > *maxchng) *maxchng = lc; + } + minchng++; + maxchng++; + } +} diff --git a/Library/libs/curses/prntscan.c b/Library/libs/curses/prntscan.c new file mode 100644 index 00000000..80257f1b --- /dev/null +++ b/Library/libs/curses/prntscan.c @@ -0,0 +1,129 @@ +#include +#include +#include "curspriv.h" + +static char printscanbuf[513]; /* buffer used during I/O */ + +/****************************************************************/ +/* Wprintw(win,fmt,args) does a printf() in window 'win'. */ +/****************************************************************/ +int wprintw(WINDOW *win, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsprintf(printscanbuf, fmt, args); + if (waddstr(win, printscanbuf) == ERR) return(ERR); + return(strlen(printscanbuf)); +} + +/****************************************************************/ +/* Printw(fmt,args) does a printf() in stdscr. */ +/****************************************************************/ +int printw(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsprintf(printscanbuf, fmt, args); + if (waddstr(stdscr, printscanbuf) == ERR) return(ERR); + return(strlen(printscanbuf)); +} /* printw */ + +/****************************************************************/ +/* Mvprintw(fmt,args) moves the stdscr cursor to a new posi- */ +/* tion, then does a printf() in stdscr. */ +/****************************************************************/ +int mvprintw(int y, int x, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (wmove(stdscr, y, x) == ERR) return(ERR); + vsprintf(printscanbuf, fmt, args); + if (waddstr(stdscr, printscanbuf) == ERR) return(ERR); + return(strlen(printscanbuf)); +} + +/****************************************************************/ +/* Mvwprintw(win,fmt,args) moves the window 'win's cursor to */ +/* A new position, then does a printf() in window 'win'. */ +/****************************************************************/ +int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (wmove(win, y, x) == ERR) return(ERR); + vsprintf(printscanbuf, fmt, args); + if (waddstr(win, printscanbuf) == ERR) return(ERR); + return(strlen(printscanbuf)); +} /* mvwprintw */ + +/****************************************************************/ +/* Wscanw(win,fmt,args) gets a string via window 'win', then */ +/* Scans the string using format 'fmt' to extract the values */ +/* And put them in the variables pointed to the arguments. */ +/****************************************************************/ +int wscanw(WINDOW *win, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + wrefresh(win); /* set cursor */ + if (wgetstr(win, printscanbuf) == ERR) /* get string */ + return(ERR); + return(vsscanf(printscanbuf, fmt, args)); +} /* wscanw */ + +/****************************************************************/ +/* Scanw(fmt,args) gets a string via stdscr, then scans the */ +/* String using format 'fmt' to extract the values and put them */ +/* In the variables pointed to the arguments. */ +/****************************************************************/ +int scanw(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + wrefresh(stdscr); /* set cursor */ + if (wgetstr(stdscr, printscanbuf) == ERR) /* get string */ + return(ERR); + return(vsscanf(printscanbuf, fmt, args)); +} /* scanw */ + +/****************************************************************/ +/* Mvscanw(y,x,fmt,args) moves stdscr's cursor to a new posi- */ +/* Tion, then gets a string via stdscr and scans the string */ +/* Using format 'fmt' to extract the values and put them in the */ +/* Variables pointed to the arguments. */ +/****************************************************************/ +int mvscanw(int y, int x, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (wmove(stdscr, y, x) == ERR) return(ERR); + wrefresh(stdscr); /* set cursor */ + if (wgetstr(stdscr, printscanbuf) == ERR) /* get string */ + return(ERR); + return(vsscanf(printscanbuf, fmt, args)); +} /* mvscanw */ + +/****************************************************************/ +/* Mvwscanw(win,y,x,fmt,args) moves window 'win's cursor to a */ +/* New position, then gets a string via 'win' and scans the */ +/* String using format 'fmt' to extract the values and put them */ +/* In the variables pointed to the arguments. */ +/****************************************************************/ +int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (wmove(win, y, x) == ERR) return(ERR); + wrefresh(win); /* set cursor */ + if (wgetstr(win, printscanbuf) == ERR) /* get string */ + return(ERR); + return(vsscanf(printscanbuf, fmt, args)); +} /* mvwscanw */ diff --git a/Library/libs/curses/refresh.c b/Library/libs/curses/refresh.c new file mode 100644 index 00000000..8e9bc632 --- /dev/null +++ b/Library/libs/curses/refresh.c @@ -0,0 +1,70 @@ +/* refresh.c */ + +#include +#include "curspriv.h" + +/* Wrefresh() updates window win's area of the physical screen. */ +void wrefresh(WINDOW *win) +{ + if (win == curscr) + curscr->_clear = TRUE; + else + wnoutrefresh(win); + doupdate(); +} + +/****************************************************************/ +/* Wnoutrefresh() updates the image of the desired screen, */ +/* Without doing physical update (copies window win's image to */ +/* The _cursvar.tmpwin window, which is hidden from the user). */ +/****************************************************************/ + +void wnoutrefresh(register WINDOW *win) +{ + register int *dst; /* start destination in temp window */ + register int *end; /* end destination in temp window */ + register int *src; /* source in user window */ + register int first; /* first changed char on line */ + register int last; /* last changed char on line */ + WINDOW *nscr; + int begy; /* window's place on screen */ + int begx; + int i; + int j; + + nscr = _cursvar.tmpwin; + begy = win->_begy; + begx = win->_begx; + + for (i = 0, j = begy; i <= win->_maxy; i++, j++) { + if (win->_minchng[i] != _NO_CHANGE) { + first = win->_minchng[i]; + last = win->_maxchng[i]; + dst = &(nscr->_line[j][begx + first]); + end = &(nscr->_line[j][begx + last]); + src = &(win->_line[i][first]); + + while (dst <= end) /* copy user line to temp window */ + *dst++ = *src++; + + first += begx; /* nscr's min/max change positions */ + last += begx; + + if ((nscr->_minchng[j] == _NO_CHANGE) || (nscr->_minchng[j] > first)) + nscr->_minchng[j] = first; + if (last > nscr->_maxchng[j]) nscr->_maxchng[j] = last; + + win->_minchng[i] = _NO_CHANGE; /* updated now */ + } /* if */ + win->_maxchng[i] = _NO_CHANGE; /* updated now */ + } /* for */ + + if (win->_clear) { + win->_clear = FALSE; + nscr->_clear = TRUE; + } /* if */ + if (!win->_leave) { + nscr->_cury = win->_cury + begy; + nscr->_curx = win->_curx + begx; + } /* if */ +} /* wnoutrefresh */ diff --git a/Library/libs/curses/scrreg.c b/Library/libs/curses/scrreg.c new file mode 100644 index 00000000..c9bf3434 --- /dev/null +++ b/Library/libs/curses/scrreg.c @@ -0,0 +1,53 @@ +/****************************************************************/ +/* Wsetscrreg() routine of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wsetscrreg() set the scrolling region of window 'win' to in- */ +/* Clude all lines between 'top' and 'bottom'. */ +/****************************************************************/ + +int wsetscrreg(WINDOW *win, int top, int bottom) +{ + if ((0 <= top) && + (top <= win->_cury) + && + (win->_cury <= bottom) + && + (bottom <= win->_maxy) + ) { + win->_regtop = top; + win->_regbottom = bottom; + return(OK); + } + + /* If */ + else + return(ERR); +} /* wsetscrreg */ + +/****************************************************************/ +/* Setscrreg() set the scrolling region of stdscr to include */ +/* All lines between 'top' and 'bottom'. */ +/****************************************************************/ + +int setscrreg(int top, int bottom) +{ + return(wsetscrreg(stdscr, top, bottom)); +} /* setscrreg */ diff --git a/Library/libs/curses/setterm.c b/Library/libs/curses/setterm.c new file mode 100644 index 00000000..ac3c3092 --- /dev/null +++ b/Library/libs/curses/setterm.c @@ -0,0 +1,76 @@ +#include +#include "curspriv.h" + +_PROTOTYPE( static void ttysetflags, (void) ); + +static void ttysetflags() +{ + _tty.c_iflag |= ICRNL | IXON; + _tty.c_oflag |= OPOST | ONLCR; + _tty.c_lflag |= ECHO | ICANON | IEXTEN | ISIG; + + if (_cursvar.rawmode) { + _tty.c_iflag &= ~(ICRNL | IXON); + _tty.c_oflag &= ~(OPOST); + _tty.c_lflag &= ~(ICANON | IEXTEN | ISIG); + } + if (_cursvar.cbrkmode) { + _tty.c_lflag &= ~(ICANON); + } + if (!_cursvar.echoit) { + _tty.c_lflag &= ~(ECHO | ECHONL); + } + if (NONL) { + _tty.c_iflag &= ~(ICRNL); + _tty.c_oflag &= ~(ONLCR); + } + tcsetattr(0, TCSANOW, &_tty); +} /* ttysetflags */ + +void raw() +{ + _cursvar.rawmode = TRUE; + ttysetflags(); +} /* raw */ + +void noraw() +{ + _cursvar.rawmode = FALSE; + ttysetflags(); +} /* noraw */ + +void echo() +{ + _cursvar.echoit = TRUE; + ttysetflags(); +} + +void noecho() +{ + _cursvar.echoit = FALSE; + ttysetflags(); +} + +void nl() +{ + NONL = FALSE; + ttysetflags(); +} /* nl */ + +void nonl() +{ + NONL = TRUE; + ttysetflags(); +} /* nonl */ + +void cbreak() +{ + _cursvar.cbrkmode = TRUE; + ttysetflags(); +} /* cbreak */ + +void nocbreak() +{ + _cursvar.cbrkmode = FALSE; + ttysetflags(); +} /* nocbreak */ diff --git a/Library/libs/curses/tabsize.c b/Library/libs/curses/tabsize.c new file mode 100644 index 00000000..b2e12fa9 --- /dev/null +++ b/Library/libs/curses/tabsize.c @@ -0,0 +1,47 @@ +/****************************************************************/ +/* Tabsize() routines of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wtabsize(win,ts) sets the tabsize of window 'win' to 'ts', */ +/* And returns the original value. */ +/****************************************************************/ + +int wtabsize(WINDOW *win, int ts) +{ + int origval; + + origval = win->_tabsize; + win->_tabsize = ts; + return(origval); +} /* wtabsize */ + +/****************************************************************/ +/* Tabsize(ts) sets the tabsize of stdscr to 'ts', and returns */ +/* The original value. */ +/****************************************************************/ + +int tabsize(int ts) +{ + int origval; + + origval = stdscr->_tabsize; + stdscr->_tabsize = ts; + return(origval); +} /* tabsize */ diff --git a/Library/libs/curses/tparam.c b/Library/libs/curses/tparam.c new file mode 100644 index 00000000..66f91b5b --- /dev/null +++ b/Library/libs/curses/tparam.c @@ -0,0 +1,270 @@ +/* tparam.c + * Merge parameters into a termcap entry string. + * Copyright (C) 1985, 1987, 1993 Free Software Foundation, Inc. + */ +#include +#include +#include +#include +#include + +static void memory_out __P((void)); +static char *xmalloc __P((unsigned size)); +static char *xrealloc __P((char *ptr, unsigned size)); +static char *tparam1 __P((char *string, char *outstring, int len, char *up, char *left, int *argp)); + +static void memory_out() { + write(2, "virtual memory exhausted\n", 25); + exit(1); +} + +static char *xmalloc(unsigned size) +{ + register char *tem = malloc(size); + + if (!tem) + memory_out(); + return tem; +} + +static char *xrealloc(char *ptr, unsigned size) +{ + register char *tem = realloc(ptr, size); + + if (!tem) + memory_out(); + return tem; +} + +/* Assuming STRING is the value of a termcap string entry + containing `%' constructs to expand parameters, + merge in parameter values and store result in block OUTSTRING points to. + LEN is the length of OUTSTRING. If more space is needed, + a block is allocated with `malloc'. + + The value returned is the address of the resulting string. + This may be OUTSTRING or may be the address of a block got with `malloc'. + In the latter case, the caller must free the block. + + The fourth and following args to tparam serve as the parameter values. + */ +/* VARARGS 2 */ +char * tparam(char *string, char *outstring, int len, int arg0, int arg1, int arg2,int arg3) +{ +#ifdef NO_ARG_ARRAY + int arg[4]; + arg[0] = arg0; + arg[1] = arg1; + arg[2] = arg2; + arg[3] = arg3; + return tparam1(string, outstring, len, NULL, NULL, arg); +#else + (void)arg1; (void)arg2; (void)arg3; + return tparam1(string, outstring, len, NULL, NULL, &arg0); +#endif +} + +char *BC; +char *UP; + +static char tgoto_buf[50]; + +char *tgoto(char *cm, int hpos, int vpos) +{ + int args[2]; + + if (!cm) + return NULL; + args[0] = vpos; + args[1] = hpos; + return tparam1(cm, tgoto_buf, 50, UP, BC, args); +} + +static char *tparam1(char *string, char *outstring, int len, char *up, char *left, register int *argp) +{ + register int c, tem; + register char *p = string; + register char *op = outstring; + int *old_argp = argp; + int outlen = 0; + int doleft = 0; + int doup = 0; + char *outend = outstring + len; + + while (1) { + /* If the buffer might be too short, make it bigger. */ + if (op + 5 >= outend) { + register char *new; + if (outlen == 0) { + outlen = len + 40; + new = (char *) xmalloc(outlen); + outend += 40; + memcpy(new, outstring, op - outstring); + } + else { + outend += outlen; + outlen *= 2; + new = (char *) xrealloc(outstring, outlen); + } + op += new -outstring; + outend += new -outstring; + outstring = new; + } + c = *p++; + if (!c) + break; + if (c == '%') { + c = *p++; + tem = *argp; + switch (c) { + case 'd': /* %d means output in decimal. */ + if (tem < 10) + goto onedigit; + if (tem < 100) + goto twodigit; + case '3': /* %3 means output in decimal, 3 digits. */ + if (tem > 999) { + *op++ = tem / 1000 + '0'; + tem %= 1000; + } + *op++ = tem / 100 + '0'; + case '2': /* %2 means output in decimal, 2 digits. */ +twodigit: + tem %= 100; + *op++ = tem / 10 + '0'; +onedigit: + *op++ = tem % 10 + '0'; + argp++; + break; + + case 'C': + /* For c-100: print quotient of value by 96, if + * nonzero, then do like %+. */ + if (tem >= 96) { + *op++ = tem / 96; + tem %= 96; + } + case '+': /* %+x means add character code of char x. */ + tem += *p++; + case '.': /* %. means output as character. */ + if (left) { + /* If want to forbid output of 0 and \n and + * \t, and this is one of them, increment + * it. */ + while (tem == 0 || tem == '\n' || tem == '\t') { + tem++; + if (argp == old_argp) + doup++, outend -= strlen(up); + else + doleft++, outend -= strlen(left); + } + } + *op++ = tem ? tem : 0200; + case 'f': /* %f means discard next arg. */ + argp++; + break; + + case 'b': /* %b means back up one arg (and re-use + * it). */ + argp--; + break; + + case 'r': /* %r means interchange following two args. */ + argp[0] = argp[1]; + argp[1] = tem; + old_argp++; + break; + + case '>': /* %>xy means if arg is > char code of x, */ + if (argp[0] > *p++) /* then add char code of y + * to the arg, */ + argp[0] += *p; /* and in any case don't + * output. */ + p++; /* Leave the arg to be output later. */ + break; + + case 'a': /* %a means arithmetic. */ + /* Next character says what operation. Add or + * subtract either a constant or some other arg. */ + /* First following character is + to add or - to + * subtract or = to assign. */ + /* Next following char is 'p' and an arg spec (0100 + * plus position of that arg relative to this one) + * or 'c' and a constant stored in a character. */ + tem = p[2] & 0177; + if (p[1] == 'p') + tem = argp[tem - 0100]; + if (p[0] == '-') + argp[0] -= tem; + else if (p[0] == '+') + argp[0] += tem; + else if (p[0] == '*') + argp[0] *= tem; + else if (p[0] == '/') + argp[0] /= tem; + else + argp[0] = tem; + + p += 3; + break; + + case 'i': /* %i means add one to arg, */ + argp[0]++; /* and leave it to be output later. */ + argp[1]++; /* Increment the following arg, + * too! */ + break; + + case '%': /* %% means output %; no arg. */ + goto ordinary; + + case 'n': /* %n means xor each of next two args with + * 140. */ + argp[0] ^= 0140; + argp[1] ^= 0140; + break; + + case 'm': /* %m means xor each of next two args with + * 177. */ + argp[0] ^= 0177; + argp[1] ^= 0177; + break; + + case 'B': /* %B means express arg as BCD char code. */ + argp[0] += 6 * (tem / 10); + break; + + case 'D': /* %D means weird Delta Data + * transformation. */ + argp[0] -= 2 * (tem % 16); + break; + } + } + else + /* Ordinary character in the argument string. */ +ordinary: + *op++ = c; + } + *op = 0; + while (doup-- > 0) + strcat(op, up); + while (doleft-- > 0) + strcat(op, left); + return outstring; +} + +#ifdef TEST + +int main(int argc, char **argv) +{ + char buf[50]; + int args[3]; + + args[0] = atoi(argv[2]); + args[1] = atoi(argv[3]); + args[2] = atoi(argv[4]); + tparam1(argv[1], buf, 50, "LEFT", "UP", args); + printf("%s\n", buf); + return 0; +} +#endif /* DEBUG */ + diff --git a/Library/libs/curses/unctrl.c b/Library/libs/curses/unctrl.c new file mode 100644 index 00000000..45fc95fa --- /dev/null +++ b/Library/libs/curses/unctrl.c @@ -0,0 +1,44 @@ +/****************************************************************/ +/* Unctrl() routines of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +static char strbuf[3] = {0, 0, 0}; + +/****************************************************************/ +/* Unctrl() returns a char pointer to a string corresponding to */ +/* Argument character 'c'. */ +/****************************************************************/ + +char *unctrl(char c) +{ + int ic = c; + ic &= 0xff; + + if ((ic >= ' ') && (ic != 0x7f)) { /* normal characters */ + strbuf[0] = ic; + strbuf[1] = '\0'; + return(strbuf); + } /* if */ + strbuf[0] = '^'; /* '^' prefix */ + if (c == 0x7f) /* DEL */ + strbuf[1] = '?'; + else /* other control */ + strbuf[1] = ic + '@'; + return(strbuf); +} /* unctrl */ diff --git a/Library/libs/curses/waddch.c b/Library/libs/curses/waddch.c new file mode 100644 index 00000000..97a95dc3 --- /dev/null +++ b/Library/libs/curses/waddch.c @@ -0,0 +1,92 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Newline() does line advance and returns the new cursor line. */ +/* If error, return -1. */ +/****************************************************************/ + +_PROTOTYPE( static short newline, (WINDOW *win, int lin)); + +static short newline(WINDOW *win, int lin) +{ + if (++lin > win->_regbottom) { + lin--; + if (win->_scroll) + scroll(win); + else + return(-1); + } /* if */ + return(lin); +} /* newline */ + +/****************************************************************/ +/* Waddch() inserts character 'c' at the current cursor posi- */ +/* Tion in window 'win', and takes any actions as dictated by */ +/* The character. */ +/****************************************************************/ + +int waddch(WINDOW *win, int c) +{ + int x = win->_curx; + int y = win->_cury; + int newx; + int ch = c; + int ts = win->_tabsize; + + ch &= (A_ALTCHARSET | 0xff); + if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0) return(ERR); + switch (ch) { + case '\t': + for (newx = ((x / ts) + 1) * ts; x < newx; x++) { + if (waddch(win, ' ') == ERR) return(ERR); + if (win->_curx == 0) /* if tab to next line */ + return(OK); /* exit the loop */ + } + return(OK); + + case '\n': + if (NONL) x = 0; + if ((y = newline(win, y)) < 0) return (ERR); + break; + + case '\r': x = 0; break; + + case '\b': + if (--x < 0) /* no back over left margin */ + x = 0; + break; + + case 0x7f: + { + if (waddch(win, '^') == ERR) return(ERR); + return(waddch(win, '?')); + } + + default: + if (ch < ' ') { /* handle control chars */ + if (waddch(win, '^') == ERR) return(ERR); + return(waddch(win, c + '@')); + } + ch |= (win->_attrs & ATR_MSK); + if (win->_line[y][x] != ch) { /* only if data change */ + if (win->_minchng[y] == _NO_CHANGE) + win->_minchng[y] = win->_maxchng[y] = x; + else if (x < win->_minchng[y]) + win->_minchng[y] = x; + else if (x > win->_maxchng[y]) + win->_maxchng[y] = x; + } /* if */ + *(*(win->_line + y) + x++) = ch; + if (x > win->_maxx) { /* wrap around test */ + x = 0; + if ((y = newline(win, y)) < 0) return(ERR); + } + break; + + } /* switch */ + win->_curx = x; + win->_cury = y; + + return(OK); +} diff --git a/Library/libs/curses/waddstr.c b/Library/libs/curses/waddstr.c new file mode 100644 index 00000000..8f9590d9 --- /dev/null +++ b/Library/libs/curses/waddstr.c @@ -0,0 +1,16 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Waddstr() inserts string 'str' at the current cursor posi- */ +/* Tion in window 'win', and takes any actions as dictated by */ +/* The characters. */ +/****************************************************************/ + +int waddstr(WINDOW *win, char *str) +{ + while (*str) { + if (waddch(win, *str++) == ERR) return(ERR); + } + return(OK); +} diff --git a/Library/libs/curses/wbox.c b/Library/libs/curses/wbox.c new file mode 100644 index 00000000..ff8e2778 --- /dev/null +++ b/Library/libs/curses/wbox.c @@ -0,0 +1,62 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wbox(win,ymin,xmin,ymax,xmax,v,h) draws a box in window */ +/* 'win', enclosing the area xmin-xmax and ymin-xmax. If */ +/* Xmax and/or ymax is 0, the window max value is used. 'v' and */ +/* 'h' are the vertical and horizontal characters to use. If */ +/* 'v' and 'h' are 0, wbox will use the alternate character set */ +/* In a pretty way. */ +/****************************************************************/ + +int wbox(WINDOW *win, int ymin, int xmin, int ymax, int xmax, unsigned int v, unsigned int h) +{ + unsigned int vc, hc, ulc, urc, llc, lrc; /* corner chars */ + int i; + + if (ymax == 0) ymax = win->_maxy; + if (xmax == 0) xmax = win->_maxx; + + if (ymin >= win->_maxy || ymax > win->_maxy || + xmin >= win->_maxx || xmax > win->_maxx || + ymin >= ymax || xmin >= xmax) + return(ERR); + + vc = v; + hc = h; + ulc = urc = llc = lrc = vc; /* default same as vertical */ + + if (v == 0 && h == 0) { + ulc = ACS_ULCORNER; + urc = ACS_URCORNER; + llc = ACS_LLCORNER; + lrc = ACS_LRCORNER; + hc = ACS_HLINE; + vc = ACS_VLINE; + } + for (i = xmin + 1; i <= xmax - 1; i++) { + *(*(win->_line + ymin) + i) = hc | win->_attrs; + *(*(win->_line + ymax) + i) = hc | win->_attrs; + } + + for (i = ymin + 1; i <= ymax - 1; i++) { + *(*(win->_line + i) + xmin) = vc | win->_attrs; + *(*(win->_line + i) + xmax) = vc | win->_attrs; + } + *(*(win->_line + ymin) + xmin) = ulc | win->_attrs; + *(*(win->_line + ymin) + xmax) = urc | win->_attrs; + *(*(win->_line + ymax) + xmin) = llc | win->_attrs; + *(*(win->_line + ymax) + xmax) = lrc | win->_attrs; + + for (i = ymin; i <= ymax; i++) { + if (win->_minchng[i] == _NO_CHANGE) { + win->_minchng[i] = xmin; + win->_maxchng[i] = xmax; + } else { + win->_minchng[i] = min(win->_minchng[i], xmin); + win->_maxchng[i] = max(win->_maxchng[i], xmax); + } + } + return(OK); +} diff --git a/Library/libs/curses/wclear.c b/Library/libs/curses/wclear.c new file mode 100644 index 00000000..68648551 --- /dev/null +++ b/Library/libs/curses/wclear.c @@ -0,0 +1,13 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wclear() fills all lines of window 'win' with blanks, and */ +/* Marks the window to be cleared at next refresh operation. */ +/****************************************************************/ + +void wclear(WINDOW *win) +{ + werase(win); + win->_clear = TRUE; +} /* wclear */ diff --git a/Library/libs/curses/wclrtobot.c b/Library/libs/curses/wclrtobot.c new file mode 100644 index 00000000..f374558b --- /dev/null +++ b/Library/libs/curses/wclrtobot.c @@ -0,0 +1,34 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wclrtobot() fills the right half of the cursor line of */ +/* Window 'win', and all lines below it with blanks. */ +/****************************************************************/ + +int wclrtobot(WINDOW *win) +{ + int y, minx, startx, *ptr, *end, *maxx, blank; + + blank = ' ' | (win->_attrs & ATR_MSK); + startx = win->_curx; + for (y = win->_cury; y <= win->_regbottom; y++) { + minx = _NO_CHANGE; + end = &win->_line[y][win->_maxx]; + for (ptr = &win->_line[y][startx]; ptr <= end; ptr++) { + if (*ptr != blank) { + maxx = ptr; + if (minx == _NO_CHANGE) minx = ptr - win->_line[y]; + *ptr = blank; + } /* if */ + } /* for */ + if (minx != _NO_CHANGE) { + if ((win->_minchng[y] > minx) || (win->_minchng[y] == _NO_CHANGE)) + win->_minchng[y] = minx; + if (win->_maxchng[y] < maxx - win->_line[y]) + win->_maxchng[y] = maxx - win->_line[y]; + } /* if */ + startx = 0; + } + return(OK); +} diff --git a/Library/libs/curses/wclrtoeol.c b/Library/libs/curses/wclrtoeol.c new file mode 100644 index 00000000..b2c72908 --- /dev/null +++ b/Library/libs/curses/wclrtoeol.c @@ -0,0 +1,35 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wclrtoeol() fills the half of the cursor line to the right */ +/* Of the cursor in window 'win' with blanks. */ +/****************************************************************/ + +int wclrtoeol(WINDOW *win) +{ + int *maxx, *ptr, *end, y, x, minx, blank; + + y = win->_cury; + x = win->_curx; + blank = ' ' | (win->_attrs & ATR_MSK); + + end = &win->_line[y][win->_maxx]; + minx = _NO_CHANGE; + maxx = &win->_line[y][x]; + for (ptr = maxx; ptr <= end; ptr++) { + if (*ptr != blank) { + maxx = ptr; + if (minx == _NO_CHANGE) minx = ptr - win->_line[y]; + *ptr = blank; + } /* if */ + } /* for */ + + if (minx != _NO_CHANGE) { + if (win->_minchng[y] > minx || win->_minchng[y] == _NO_CHANGE) + win->_minchng[y] = minx; + if (win->_maxchng[y] < maxx - win->_line[y]) + win->_maxchng[y] = maxx - win->_line[y]; + } + return(OK); +} diff --git a/Library/libs/curses/wdelch.c b/Library/libs/curses/wdelch.c new file mode 100644 index 00000000..b8999179 --- /dev/null +++ b/Library/libs/curses/wdelch.c @@ -0,0 +1,27 @@ +#include +#include "curspriv.h" + +/* Wdelch() deletes the character at the window cursor, and the + characters to the right of it are shifted left, inserting a + space at the last position of the line. +*/ + +int wdelch(WINDOW *win) +{ + int *temp1; + int *temp2; + int *end; + int y = win->_cury; + int x = win->_curx; + int maxx = win->_maxx; + + end = &win->_line[y][maxx]; + temp1 = &win->_line[y][x]; + temp2 = temp1 + 1; + while (temp1 < end) *temp1++ = *temp2++; + *temp1 = ' ' | (win->_attrs & ATR_MSK); + win->_maxchng[y] = maxx; + if (win->_minchng[y] == _NO_CHANGE || win->_minchng[y] > x) + win->_minchng[y] = x; + return(OK); +} diff --git a/Library/libs/curses/wdeleteln.c b/Library/libs/curses/wdeleteln.c new file mode 100644 index 00000000..be28b0a5 --- /dev/null +++ b/Library/libs/curses/wdeleteln.c @@ -0,0 +1,27 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wdeleteln() deletes the line at the window cursor, and the */ +/* Lines below it are shifted up, inserting a blank line at */ +/* The bottom of the window. */ +/****************************************************************/ + +int wdeleteln(WINDOW *win) +{ + int *end, *temp, y, blank; + + blank = ' ' | (win->_attrs & ATR_MSK); + + temp = win->_line[win->_cury]; + for (y = win->_cury; y < win->_regbottom; y++) { + win->_line[y] = win->_line[y + 1]; + win->_minchng[y] = 0; + win->_maxchng[y] = win->_maxx; + } + win->_minchng[y] = 0; + win->_maxchng[y] = win->_maxx; + win->_line[win->_regbottom] = temp; + for (end = &(temp[win->_maxx]); temp <= end;) *temp++ = blank; + return(OK); +} diff --git a/Library/libs/curses/werase.c b/Library/libs/curses/werase.c new file mode 100644 index 00000000..c95d7aaa --- /dev/null +++ b/Library/libs/curses/werase.c @@ -0,0 +1,25 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Werase() fills all lines of window 'win' with blanks and po- */ +/* Sitions the cursor at home in the scroll region. */ +/****************************************************************/ + +void werase(WINDOW *win) +{ + int *end, *start, y, blank; + + blank = ' ' | (win->_attrs & ATR_MSK); + + for (y = win->_regtop; y <= win->_regbottom; y++) { /* clear all lines */ + start = win->_line[y]; + end = &start[win->_maxx]; + while (start <= end) /* clear all line */ + *start++ = blank; + win->_minchng[y] = 0; + win->_maxchng[y] = win->_maxx; + } + win->_cury = win->_regtop; /* cursor home */ + win->_curx = 0; +} diff --git a/Library/libs/curses/wgetch.c b/Library/libs/curses/wgetch.c new file mode 100644 index 00000000..bfb6c592 --- /dev/null +++ b/Library/libs/curses/wgetch.c @@ -0,0 +1,27 @@ +#include +#include +#include "curspriv.h" + +int wgetch(WINDOW *win) +{ + bool weset = FALSE; + char inp; + + if (!win->_scroll && (win->_flags & _FULLWIN) + && win->_curx == win->_maxx - 1 && win->_cury == win->_maxy - 1) + return ERR; + + //if (_cursvar.echoit && !_cursvar.rawmode) { + //cbreak(); + // weset++; + //} + + inp = getchar(); + if (_cursvar.echoit) { + mvwaddch(curscr, win->_cury + win->_begy, + win->_curx + win->_begx, inp); + waddch(win, inp); + } + //if (weset) nocbreak(); + return inp; +} diff --git a/Library/libs/curses/wgetstr.c b/Library/libs/curses/wgetstr.c new file mode 100644 index 00000000..980697b5 --- /dev/null +++ b/Library/libs/curses/wgetstr.c @@ -0,0 +1,20 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Wgetstr(win,str) reads in a string (terminated by \n or \r) */ +/* To the buffer pointed to by 'str', and displays the input */ +/* In window 'win'. The user's erase and kill characters are */ +/* Active. */ +/****************************************************************/ + +int wgetstr(WINDOW *win, char *str) +{ + while ((*str = wgetch(win)) != ERR && *str != '\n') str++; + if (*str == ERR) { + *str = '\0'; + return ERR; + } + *str = '\0'; + return OK; +} diff --git a/Library/libs/curses/windel.c b/Library/libs/curses/windel.c new file mode 100644 index 00000000..f029308a --- /dev/null +++ b/Library/libs/curses/windel.c @@ -0,0 +1,40 @@ +/****************************************************************/ +/* Delwin() routine of the PCcurses package. */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include +#include "curspriv.h" + +/****************************************************************/ +/* Delwin() deallocates all data allocated by 'win'. If 'win' */ +/* Is a subwindow, it uses the original window's lines for sto- */ +/* Rage, and thus the line arrays are not deallocated. */ +/****************************************************************/ + +void delwin(WINDOW *win) +{ + int i; + + if (!(win->_flags & _SUBWIN)) { /* subwindow uses 'parent's' lines */ + for (i = 0; i <= win->_maxy && win->_line[i]; i++) + free(win->_line[i]); + } + free(win->_minchng); + free(win->_maxchng); + free(win->_line); + free(win); +} /* delwin */ diff --git a/Library/libs/curses/winmove.c b/Library/libs/curses/winmove.c new file mode 100644 index 00000000..a5b6d82b --- /dev/null +++ b/Library/libs/curses/winmove.c @@ -0,0 +1,34 @@ +/****************************************************************/ +/* Mvwin() routine of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Mvwin() moves window 'win' to position (begx, begy) on the */ +/* Screen. */ +/****************************************************************/ + +int mvwin(WINDOW *win, int begy, int begx) +{ + if ((begy + win->_maxy) > (LINES - 1) || (begx + win->_maxx) > (COLS - 1)) + return(ERR); + win->_begy = begy; + win->_begx = begx; + touchwin(win); + return(OK); +} /* mvwin */ diff --git a/Library/libs/curses/winsch.c b/Library/libs/curses/winsch.c new file mode 100644 index 00000000..5ec48d32 --- /dev/null +++ b/Library/libs/curses/winsch.c @@ -0,0 +1,29 @@ +#include +#include "curspriv.h" + +/* Winsch() inserts character 'c' at the cursor position in + window 'win'. The cursor is advanced. +*/ + +int winsch(WINDOW *win, char c) +{ + int *temp1; + int *temp2; + int *end; + int x = win->_curx; + int y = win->_cury; + int maxx = win->_maxx; + + if ((c < ' ') && (c == '\n' || c == '\r' || c == '\t' || c == '\b')) + return(waddch(win, c)); + end = &win->_line[y][x]; + temp1 = &win->_line[y][maxx]; + temp2 = temp1 - 1; + if (c < ' ') /* if CTRL-char make space for 2 */ + temp2--; + while (temp1 > end) *temp1-- = *temp2--; + win->_maxchng[y] = maxx; + if ((win->_minchng[y] == _NO_CHANGE) || (win->_minchng[y] > x)) + win->_minchng[y] = x; + return(waddch(win, c)); /* fixes CTRL-chars too */ +} /* winsch */ diff --git a/Library/libs/curses/winscrol.c b/Library/libs/curses/winscrol.c new file mode 100644 index 00000000..0447189e --- /dev/null +++ b/Library/libs/curses/winscrol.c @@ -0,0 +1,54 @@ +/****************************************************************/ +/* Scroll() routine of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Scroll() scrolls the scrolling region of 'win', but only if */ +/* Scrolling is allowed and if the cursor is inside the scrol- */ +/* Ling region. */ +/****************************************************************/ + +void scroll(WINDOW *win) +{ + int i; + int *ptr; + int *temp; + static int blank; + + blank = ' ' | (win->_attrs & ATR_MSK); + if ((!win->_scroll) /* check if window scrolls */ + ||(win->_cury < win->_regtop) /* and cursor in region */ + ||(win->_cury > win->_regbottom) + ) + return; + + temp = win->_line[win->_regtop]; + for (i = win->_regtop; i < win->_regbottom; i++) { + win->_line[i] = win->_line[i + 1]; /* re-arrange line pointers */ + win->_minchng[i] = 0; + win->_maxchng[i] = win->_maxx; + } + for (ptr = temp; ptr - temp <= win->_maxx; ptr++) + *ptr = blank; /* make a blank line */ + win->_line[win->_regbottom] = temp; + if (win->_cury > win->_regtop)/* if not on top line */ + win->_cury--; /* cursor scrolls too */ + win->_minchng[win->_regbottom] = 0; + win->_maxchng[win->_regbottom] = win->_maxx; +} /* scroll */ diff --git a/Library/libs/curses/winsertln.c b/Library/libs/curses/winsertln.c new file mode 100644 index 00000000..c048cdfe --- /dev/null +++ b/Library/libs/curses/winsertln.c @@ -0,0 +1,25 @@ +#include +#include "curspriv.h" + +/****************************************************************/ +/* Winsertln() inserts a blank line instead of the cursor line */ +/* In window 'win' and pushes other lines down. */ +/****************************************************************/ + +int winsertln(WINDOW *win) +{ + int *temp, *end, y, blank; + + blank = ' ' | (win->_attrs & ATR_MSK); + temp = win->_line[win->_regbottom]; + for (y = win->_regbottom; y > win->_cury; y--) { + win->_line[y] = win->_line[y - 1]; + win->_minchng[y] = 0; + win->_maxchng[y] = win->_maxx; + } + win->_line[win->_cury] = temp; + for (end = &temp[win->_maxx]; temp <= end; temp++) *temp = blank; + win->_minchng[win->_cury] = 0; + win->_maxchng[win->_cury] = win->_maxx; + return(OK); +} diff --git a/Library/libs/curses/wintouch.c b/Library/libs/curses/wintouch.c new file mode 100644 index 00000000..14ad3f99 --- /dev/null +++ b/Library/libs/curses/wintouch.c @@ -0,0 +1,39 @@ +/****************************************************************/ +/* Touchwin() routine of the PCcurses package */ +/* */ +/****************************************************************/ +/* This version of curses is based on ncurses, a curses version */ +/* Originally written by Pavel Curtis at Cornell University. */ +/* I have made substantial changes to make it run on IBM PC's, */ +/* And therefore consider myself free to make it public domain. */ +/* Bjorn Larsson (...mcvax!enea!infovax!bl) */ +/****************************************************************/ +/* 1.0: Release: 870515 */ +/****************************************************************/ +/* Modified to run under the MINIX operating system by Don Cope */ +/* These changes are also released into the public domain. */ +/* 900906 */ +/****************************************************************/ + +#include +#include "curspriv.h" + +/****************************************************************/ +/* Touchwin() marks all lines of window 'win' as changed, from */ +/* The first to the last character on the line. */ +/****************************************************************/ + +void touchwin(WINDOW *win) +{ + int y; + int maxy; + int maxx; + + maxy = win->_maxy; + maxx = win->_maxx; + + for (y = 0; y <= maxy; y++) { + win->_minchng[y] = 0; + win->_maxchng[y] = maxx; + } /* for */ +} /* touchwin */