/* read GAP source header files with a combined header file */
#include"compiled.h"/* GAP headers */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> /* for getenv and co */ #ifdef WIDECHARS #define _XOPEN_SOURCE_EXTENDED #include <locale.h> #include <ncursesw/curses.h> #include <ncursesw/panel.h> #include <ncursesw/term.h> #else #include <ncurses.h> #include <panel.h> #include <term.h> #endif
/* remember attributes at init time XXX staticattr_tstartattr; staticshortstartcp;
*/
/* We store the living WINDOW and PANEL pointers in two strings. The pointertowindowi(zerobasedcounting)isstoredin ((WINDOW**)CHARS_STRING(winlist))[i].Ifthiswindowiswrappedin apanelthenthepointertothispanelisstoredinthesamepositionof panellist. Fordebuggingpurposesthestringswinlistandpanellistareavailablein GAPasrecordcomponentsofthesamenamein'NCurses'.
*/ static Obj winlist; static Obj panellist;
/* the functions */
/* get the win or panel from number (return NULL if no valid input) */
WINDOW* winnum(Obj num) { Int n; if (!IS_INTOBJ(num)) return (WINDOW*)0;
n = INT_INTOBJ(num); if (n < 0 || n * sizeof(Obj) >= GET_LEN_STRING(winlist)) return (WINDOW*)0; return ((WINDOW**)CHARS_STRING(winlist))[n];
}
PANEL* pannum(Obj num) { Int n; if (!IS_INTOBJ(num)) return (PANEL*)0;
n = INT_INTOBJ(num); /* no panel for stdscr */ if (n < 1 || n * sizeof(Obj) >= GET_LEN_STRING(panellist)) return (PANEL*)0; return ((PANEL**)CHARS_STRING(panellist))[n];
}
Obj IsStdinATty(Obj self) { if (isatty(0)) returnTrue; else returnFalse;
}
Obj IsStdoutATty(Obj self) { if (isatty(1)) returnTrue; else returnFalse;
}
/* interface to configure some basic behaviour of the ncurses screen */
Obj Cbreak(Obj self) { if (cbreak() != ERR) returnTrue; else returnFalse;
}
Obj Setupterm( Obj self, Obj tnam ) { int i; if (!IS_STRING_REP(tnam)) returnFalse; if (setupterm(CSTR_STRING(tnam), 1, &i) != ERR) returnTrue; else return INTOBJ_INT(i);
}
/* create, delete, move windows */
Obj Newwin( Obj self, Obj nlines, Obj ncols, Obj begin_y, Obj begin_x) { Int nl, nc, by, bx; int num;
WINDOW *win;
if (IS_INTOBJ(nlines))
nl = INT_INTOBJ(nlines); else
nl = 0; if (IS_INTOBJ(ncols))
nc = INT_INTOBJ(ncols); else
nc = 0; if (IS_INTOBJ(begin_y))
by = INT_INTOBJ(begin_y); else
by = 0; if (IS_INTOBJ(begin_x))
bx = INT_INTOBJ(begin_x); else
bx = 0;
win = newwin(nl, nc, by, bx); if (win) {
num = GET_LEN_STRING(winlist)/sizeof(Obj);
GROW_STRING(winlist, (num+1)*sizeof(Obj));
((WINDOW**)(CHARS_STRING(winlist)))[num] = win;
SET_LEN_STRING(winlist, (num+1)*sizeof(Obj));
CHANGED_BAG(winlist); return INTOBJ_INT(num);
} else returnFalse;
}
Obj Delwin( Obj self, Obj num ) {
WINDOW* win; Int i, n;
win = winnum(num); if (win) { if (delwin(win) != ERR) {
n = INT_INTOBJ(num);
((WINDOW**)(CHARS_STRING(winlist)))[n] = 0; if ((n+1)*sizeof(Obj) == GET_LEN_STRING(winlist)) { for (i = GET_LEN_STRING(winlist)/sizeof(Obj);
i > 0 && ((WINDOW**)(CHARS_STRING(winlist)))[i-1] == 0;
i--);
SET_LEN_STRING(winlist, i * sizeof(Obj));
}
CHANGED_BAG(winlist); returnTrue;
} else returnFalse;
} else returnFalse;
}
Obj Mvwin(Obj self, Obj num, Obj y, Obj x) { Int iy, ix;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(y))
iy = INT_INTOBJ(y); else
iy = 0; if (IS_INTOBJ(x))
ix = INT_INTOBJ(x); else
ix = 0; if (mvwin(win, iy, ix) != ERR) returnTrue; else returnFalse;
}
/* moving curser, writing characters and strings to terminal */
Obj WMove(Obj self, Obj num, Obj y, Obj x) {
WINDOW *win; Int iy, ix;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(y))
iy = INT_INTOBJ(y); else
iy = 0; if (IS_INTOBJ(x))
ix = INT_INTOBJ(x); else
ix = 0; if (wmove(win, iy, ix) != ERR) returnTrue; else returnFalse;
}
/* whole window, or to EOL or to bottom of window */
Obj WClear( Obj self, Obj num ) {
WINDOW* win;
win = winnum(num); if (win) { if (wclear(win) != ERR) returnTrue; else returnFalse;
} else returnFalse;
}
Obj WErase( Obj self, Obj num ) {
WINDOW* win;
win = winnum(num); if (win) { if (werase(win) != ERR) returnTrue; else returnFalse;
} else returnFalse;
}
Obj WClrtoeol( Obj self, Obj num ) {
WINDOW* win;
win = winnum(num); if (win) { if (wclrtoeol(win) != ERR) returnTrue; else returnFalse;
} else returnFalse;
}
Obj WClrtobot( Obj self, Obj num ) {
WINDOW* win;
win = winnum(num); if (win) { if (wclrtobot(win) != ERR) returnTrue; else returnFalse;
} else returnFalse;
}
Obj WAddnstr(Obj self, Obj num, Obj str, Obj n) {
WINDOW *win; Int len;
win = winnum(num); if (!win) returnFalse; if (!IS_STRING_REP(str)) returnFalse; if (!IS_INTOBJ(n))
len = GET_LEN_STRING(str); else
len = INT_INTOBJ(n); if (waddnstr(win, CSTR_STRING(str), len) != ERR) returnTrue; else returnFalse;
}
/* ch can be a GAP character or an INTOBJ (possibly containing
attribute info) */
Obj WAddch(Obj self, Obj num, Obj ch) {
WINDOW *win; Int ich;
win = winnum(num); if (!win) returnFalse; if (TNUM_OBJ(ch) == T_CHAR)
ich = *(UChar*)ADDR_OBJ(ch); elseif (IS_INTOBJ(ch))
ich = INT_INTOBJ(ch); else returnFalse; if (waddch(win, ich) != ERR) returnTrue; else returnFalse;
}
Obj WVline(Obj self, Obj num, Obj ch, Obj n) { Int x, y, ich;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (TNUM_OBJ(ch) == T_CHAR)
ich = *(UChar*)ADDR_OBJ(ch); elseif (IS_INTOBJ(ch))
ich = INT_INTOBJ(ch); else
ich = 0; if (!IS_INTOBJ(n))
getmaxyx(win, y, x); else
y = INT_INTOBJ(n);
x = wvline(win, ich, y); if (x != ERR) return INTOBJ_INT(x); else returnFalse;
}
Obj WHline(Obj self, Obj num, Obj ch, Obj n) { Int x, y, ich;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (TNUM_OBJ(ch) == T_CHAR)
ich = *(UChar*)ADDR_OBJ(ch); elseif (IS_INTOBJ(ch))
ich = INT_INTOBJ(ch); else
ich = 0; if (!IS_INTOBJ(n))
getmaxyx(win, y, x); else
x = INT_INTOBJ(n);
y = whline(win, ich, x); if (y != ERR) return INTOBJ_INT(y); else returnFalse;
}
/* returns integer which can be fed back in waddch */
Obj WInch(Obj self, Obj num) {
WINDOW *win;
win = winnum(num); if (!win) returnFalse; return INTOBJ_INT((Int) winch(win));
}
/* get size of window and cursor position */
Obj Getyx(Obj self, Obj num) {
WINDOW *win; int x, y;
Obj res;
win = winnum(num); if (!win) returnFalse;
res = NEW_PLIST(T_PLIST, 2);
SET_LEN_PLIST(res, 2);
getyx(win, y, x);
SET_ELM_PLIST(res, 1, INTOBJ_INT(y));
SET_ELM_PLIST(res, 2, INTOBJ_INT(x)); return res;
}
Obj Getbegyx(Obj self, Obj num) {
WINDOW *win; int x, y;
Obj res;
win = winnum(num); if (!win) returnFalse;
res = NEW_PLIST(T_PLIST, 2);
SET_LEN_PLIST(res, 2);
getbegyx(win, y, x);
SET_ELM_PLIST(res, 1, INTOBJ_INT(y));
SET_ELM_PLIST(res, 2, INTOBJ_INT(x)); return res;
}
Obj Getmaxyx(Obj self, Obj num) {
WINDOW *win; int x, y;
Obj res;
win = winnum(num); if (!win) returnFalse;
res = NEW_PLIST(T_PLIST, 2);
SET_LEN_PLIST(res, 2);
getmaxyx(win, y, x);
SET_ELM_PLIST(res, 1, INTOBJ_INT(y));
SET_ELM_PLIST(res, 2, INTOBJ_INT(x)); return res;
}
/* the win argument is used for possible echoing */
Obj WGetch(Obj self, Obj num) { int c;
WINDOW *win;
win = winnum(num); if (!win)
win = stdscr;
c = getch(); if (c != ERR) return INTOBJ_INT(c == 127 ? KEY_BACKSPACE : c); else returnFalse;
}
Obj Ungetch(Obj self, Obj ch) { int ich; if (!IS_INTOBJ(ch)) returnFalse;
ich = (int) INT_INTOBJ(ch); if (ungetch(ich) != ERR) returnTrue; else returnFalse;
}
Obj Has_key(Obj self, Obj ch) { int ich; if (!IS_INTOBJ(ch)) returnFalse;
ich = (int) INT_INTOBJ(ch); if (has_key(ich) == TRUE) returnTrue; else returnFalse;
}
/* Keys, we give symbols of standard special keys to GAP */
/* Attributes, we handle colors and standard attributes */
Obj InitAttrs() {
Obj tmp, cp;
UInt4 i, n;
tmp = NEW_PREC(0); if (has_colors()) {
start_color();
use_default_colors();
AssPRec(tmp, RNamName("has_colors"), True); /* initialize color pairs 1..64 */
cp = NEW_PLIST(T_PLIST, 64); for (i = 1; i <= 64 && i < COLOR_PAIRS; i++) { if (i < 64) if (i%8 == i/8) {
init_pair(i, i%8, -1);
} else {
init_pair(i, i % 8, i/8);
} else
init_pair(i, 0, -1);
n = COLOR_PAIR(i);
SET_ELM_PLIST(cp, i, INTOBJ_INT(n));
SET_LEN_PLIST(cp, (UInt)i);
}
AssPRec(tmp, RNamName("ColorPairs"), cp); /* fgcolor with default background */ if (72 < COLOR_PAIRS) {
cp = NEW_PLIST(T_PLIST, 8);
SET_LEN_PLIST(cp, 8); for (i = 0; i <= 7; i++) {
init_pair(65+i, i, -1);
n = COLOR_PAIR(65+i);
SET_ELM_PLIST(cp, i+1, INTOBJ_INT(n));
}
AssPRec(tmp, RNamName("ColorPairsFg"), cp);
} /* bgcolor with default foreground */ if (80 < COLOR_PAIRS) {
cp = NEW_PLIST(T_PLIST, 8);
SET_LEN_PLIST(cp, 8); for (i = 0; i <= 7; i++) {
init_pair(73+i, -1, i);
n = COLOR_PAIR(73+i);
SET_ELM_PLIST(cp, i+1, INTOBJ_INT(n));
}
AssPRec(tmp, RNamName("ColorPairsBg"), cp);
}
} else {
AssPRec(tmp, RNamName("has_colors"), False);
} /* the other attributes */
AssPRec(tmp, RNamName("NORMAL"), INTOBJ_INT(A_NORMAL));
AssPRec(tmp, RNamName("STANDOUT"), INTOBJ_INT(A_STANDOUT));
AssPRec(tmp, RNamName("UNDERLINE"), INTOBJ_INT(A_UNDERLINE));
AssPRec(tmp, RNamName("REVERSE"), INTOBJ_INT(A_REVERSE));
AssPRec(tmp, RNamName("BLINK"), INTOBJ_INT(A_BLINK));
AssPRec(tmp, RNamName("DIM"), INTOBJ_INT(A_DIM));
AssPRec(tmp, RNamName("BOLD"), INTOBJ_INT(A_BOLD));
return tmp;
}
Obj WAttrset(Obj self, Obj num, Obj attrs) { Int i;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(attrs))
i = INT_INTOBJ(attrs); else
i = 0; if (wattrset(win, i) != ERR) returnTrue; else returnFalse;
}
Obj WAttron(Obj self, Obj num, Obj attrs) { Int i;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(attrs))
i = INT_INTOBJ(attrs); else
i = 0; if (wattron(win, i) != ERR) returnTrue; else returnFalse;
}
Obj WAttroff(Obj self, Obj num, Obj attrs) { Int i;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(attrs))
i = INT_INTOBJ(attrs); else
i = 0; if (wattroff(win, i) != ERR) returnTrue; else returnFalse;
}
/* wattr_get is a macro and allows NULL pointers as arguments, this is checkedinthecode. IfwecallitwithargumentswhichareobviouslyneverNULL,then gcc>=4.6with-Wallor-Waddressissuesawarningthatapointer ischeckedfornotbeingNULLalthoughitisneverNULL.
We wrap that macro in a function to avoid the warning. */ int wattr_get_fun(WINDOW *win, attr_t * pa, short *ps, void *opts) { int ret;
ret = wattr_get(win, pa, ps, opts); return ret;
}
Obj WAttrCPGet(Obj self, Obj num) {
WINDOW *win;
attr_t a; short cp;
Obj res;
win = winnum(num); if (!win) returnFalse;
wattr_get_fun(win, &a, &cp, NULL);
res = NEW_PLIST(T_PLIST, 2);
SET_LEN_PLIST(res, 2);
SET_ELM_PLIST(res, 1, INTOBJ_INT((int)a));
SET_ELM_PLIST(res, 2, INTOBJ_INT((int)cp)); return res;
};
Obj WBkgdset(Obj self, Obj num, Obj attrs) { Int i;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(attrs))
i = INT_INTOBJ(attrs); else
i = 0;
wbkgdset(win, i); returnTrue;
}
Obj WBkgd(Obj self, Obj num, Obj attrs) { Int i;
WINDOW *win;
win = winnum(num); if (!win) returnFalse; if (IS_INTOBJ(attrs))
i = INT_INTOBJ(attrs); else
i = 0;
wbkgd(win, i); returnTrue;
}
/* Panels: create, delete, update, move, stack movements, hide, show */
Obj New_panel(Obj self, Obj num) {
WINDOW *win;
PANEL *pan; int n;
win = winnum(num); if (!win) returnFalse;
n = INT_INTOBJ(num); if (n == 0) /* no panel for stdscr */ returnFalse;
pan = new_panel(win); if (!pan) returnFalse;
GROW_STRING(panellist, (n+1)*sizeof(Obj));
((PANEL**)(CHARS_STRING(panellist)))[n] = pan; if ((n+1)*sizeof(Obj) > GET_LEN_STRING(panellist))
SET_LEN_STRING(panellist, (n+1)*sizeof(Obj));
CHANGED_BAG(panellist); return num;
}
Obj Del_panel(Obj self, Obj pnum) {
PANEL *pan; Int i, n;
pan = pannum(pnum); if (!pan) returnFalse; if (del_panel(pan) != ERR) {
n = INT_INTOBJ(pnum);
((PANEL**)(CHARS_STRING(panellist)))[n] = 0; if ((n+1)*sizeof(Obj) == GET_LEN_STRING(panellist)) { for (i = GET_LEN_STRING(panellist)/sizeof(Obj);
i > 0 && ((PANEL**)(CHARS_STRING(panellist)))[i-1] == 0;
i--);
SET_LEN_STRING(panellist, i * sizeof(Obj));
}
CHANGED_BAG(panellist); returnTrue;
} else returnFalse;
}
/* translate mmask_t to list of integers and vice versa */
Obj IntlistMmask_t(mmask_t mask) {
Obj res; Int l, i;
res = NEW_PLIST(T_PLIST, 1);
SET_LEN_PLIST(res, 0); for (l=1, i=0; i<LENmmaskbits; i++) { if (mask & mmaskbits[i]) {AssPlist(res, l, INTOBJ_INT(i)); l++;}
} return res;
}
mmask_t mmaskIntlist(Obj list) {
mmask_t res = (mmask_t)0; Int l, i, n; while (! IS_PLIST(list)) {
list = ErrorReturnObj("<list> must be a plain list of integers, not a %s)",
(Int)TNAM_OBJ(list), 0L, "you can replace <list> via 'return <list>;'" );
}
l = LEN_PLIST(list); for (i = 0; i<l; i++) {
n = INT_INTOBJ(ELM_PLIST(list, i+1)); if (n >= 0 && n < LENmmaskbits) {res += mmaskbits[n];}
} return res;
}
Obj Mousemask(Obj self, Obj list) {
mmask_t new, old;
Obj res; while (! IS_PLIST(list)) {
list = ErrorReturnObj("<list> must be a plain list of integers, not a %s)",
(Int)TNAM_OBJ(list), 0L, "you can replace <list> via 'return <list>;'" );
} new = mmaskIntlist(list); new = mousemask(new, &old);
res = NEW_PREC(0);
AssPRec(res, RNamName("new"), IntlistMmask_t(new));
AssPRec(res, RNamName("old"), IntlistMmask_t(old)); return res;
}
static MEVENT mev;
Obj GetMouse(Obj self) { int y, x;
Obj res, mask; if (getmouse(&mev) == ERR) return Fail;
mask = IntlistMmask_t(mev.bstate);
y = mev.y;
x = mev.x; /* find panels/windows from above under mouse event */
res = NEW_PLIST(T_PLIST, 3);
SET_LEN_PLIST(res, 3);
SET_ELM_PLIST(res, 1, INTOBJ_INT(y));
SET_ELM_PLIST(res, 2, INTOBJ_INT(x));
SET_ELM_PLIST(res, 3, mask); return res;
}
Obj Wenclose(Obj self, Obj wnum, Obj iy, Obj ix) {
WINDOW *win; int y, x;
win = winnum(wnum); if (win == NULL) returnFalse; if (! IS_INTOBJ(iy)) returnFalse; else y = INT_INTOBJ(iy); if (! IS_INTOBJ(ix)) returnFalse; else x = INT_INTOBJ(ix); if (wenclose(win, y, x) == TRUE) returnTrue; elsereturnFalse;
}
/* init filters and functions */
InitHdlrFuncsFromTable( GVarFuncs );
return0;
}
/**************************************************************************** ** *FPostRestore(<module>).............afterrestoreworkspace
*/ staticInt PostRestore (
StructInitInfo * module )
{ Int i, gvar; int ierr; char *tnam;
Obj tmp, vers;
/* setup and initialize the ncurses package */
winlist = NEW_STRING(sizeof(Obj));
SET_LEN_STRING(winlist, sizeof(Obj));
panellist = NEW_STRING(sizeof(Obj));
SET_LEN_STRING(panellist, sizeof(Obj));
#ifdef WIDECHARS /* set locale from environment */
setlocale(LC_ALL,""); #endif
/* make sure that TERM is set to avoid exit by initscr */
tnam = getenv("TERM"); if (tnam == NULL)
putenv("TERM=dumb"); if (setupterm(tnam, 1, &ierr) == ERR) {
putenv("TERM=xterm-16color");
tnam = getenv("TERM"); if (setupterm(tnam, 1, &ierr) == ERR) {
putenv("TERM=xterm");
tnam = getenv("TERM"); if (setupterm(tnam, 1, &ierr) == ERR) {
putenv("TERM=ansi");
tnam = getenv("TERM"); if (setupterm(tnam, 1, &ierr) == ERR) {
putenv("TERM=dumb");
tnam = getenv("TERM");
}
}
}
}
/* init filters and functions
we assign the functions to components of a record "NCurses" */ /* (re)build kernel part of NCurses */
gvar = GVarName("NCurses");
tmp = VAL_GVAR(gvar); if (!tmp) {
tmp = NEW_PREC(0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.