/* "crs.c" interface to `curses' interactive terminal control library. * Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . */ /* Author: Aubrey Jaffer */ #include "scm.h" #ifdef __FreeBSD__ # include #else # ifdef __NetBSD__ # include # else # include # endif #endif #ifdef MWC # include #endif #ifndef STDC_HEADERS int wrefresh P((WINDOW *)); int wgetch P((WINDOW *)); #endif /* define WIN port type */ #define WIN(obj) ((WINDOW*)CDR(obj)) #define WINP(obj) (tc16_window==TYP16(obj)) int freewindow(win) WINDOW *win; { if (win==stdscr) return 0; delwin(win); return 0; } int bwaddch(c, win) int c; WINDOW *win; {waddch(win, c);return c;} int bwaddstr(str, win) char *str; WINDOW *win; {waddstr(win, str);return 0;} sizet bwwrite(str, siz, num, win) sizet siz, num; char *str; WINDOW *win; { sizet i = 0, prod = siz*num; for (;i < prod;i++) waddch(win, str[i]); return num; } int tc16_window; static ptobfuns winptob = { "window", mark0, freewindow, 0, equal0, bwaddch, bwaddstr, bwwrite, wrefresh, wgetch, freewindow}; SCM mkwindow(win) WINDOW *win; { SCM z; if (NULL==win) return BOOL_F; DEFER_INTS; z = scm_port_entry((FILE *)win, tc16_window, OPN | RDNG | WRTNG); ALLOW_INTS; return z; } SCM *loc_stdscr = 0; SCM linitscr() { WINDOW *win; if (NIMP(*loc_stdscr)) { refresh(); return *loc_stdscr; } win = initscr(); return *loc_stdscr = mkwindow(win); } SCM lendwin() { if (IMP(*loc_stdscr)) return BOOL_F; return ERR==endwin() ? BOOL_F : BOOL_T; } static char s_newwin[] = "newwin", s_subwin[] = "subwin", s_mvwin[] = "mvwin", s_overlay[] = "overlay", s_overwrite[] = "overwrite"; SCM lnewwin(lines, cols, args) SCM lines, cols, args; { SCM begin_y, begin_x; WINDOW *win; ASRTER(INUMP(lines), lines, ARG1, s_newwin); ASRTER(INUMP(cols), cols, ARG2, s_newwin); ASRTER(2==ilength(args), args, WNA, s_newwin); begin_y = CAR(args); begin_x = CAR(CDR(args)); ASRTER(INUMP(begin_y), begin_y, ARG3, s_newwin); ASRTER(INUMP(begin_x), begin_y, ARG4, s_newwin); win = newwin(INUM(lines), INUM(cols), INUM(begin_y), INUM(begin_x)); return mkwindow(win); } SCM lmvwin(win, y, x) SCM win, y, x; { ASRTER(NIMP(win) && WINP(win), win, ARG1, s_mvwin); ASRTER(INUMP(x), x, ARG2, s_mvwin); ASRTER(INUMP(y), y, ARG3, s_mvwin); return ERR==mvwin(WIN(win), INUM(y), INUM(x)) ? BOOL_F : BOOL_T; } SCM lsubwin(win, lines, args) SCM win, lines, args; { SCM cols, begin_y, begin_x; WINDOW *nwin; ASRTER(NIMP(win) && WINP(win), win, ARG1, s_subwin); ASRTER(INUMP(lines), lines, ARG2, s_subwin); ASRTER(3==ilength(args), args, WNA, s_subwin); cols = CAR(args); args = CDR(args); begin_y = CAR(args); begin_x = CAR(CDR(args)); ASRTER(INUMP(cols), cols, ARG3, s_subwin); ASRTER(INUMP(begin_y), begin_y, ARG3, s_subwin); ASRTER(INUMP(begin_x), begin_y, ARG4, s_subwin); nwin = subwin(WIN(win), INUM(lines), INUM(cols), INUM(begin_y), INUM(begin_x)); return mkwindow(nwin); } SCM loverlay(srcwin, dstwin) SCM srcwin, dstwin; { ASRTER(NIMP(srcwin) && WINP(srcwin), srcwin, ARG1, s_overlay); ASRTER(NIMP(dstwin) && WINP(dstwin), dstwin, ARG2, s_overlay); return ERR==overlay(WIN(srcwin), WIN(dstwin)) ? BOOL_F : BOOL_T; } SCM loverwrite(srcwin, dstwin) SCM srcwin, dstwin; { ASRTER(NIMP(srcwin) && WINP(srcwin), srcwin, ARG1, s_overwrite); ASRTER(NIMP(dstwin) && WINP(dstwin), dstwin, ARG2, s_overwrite); return ERR==overwrite(WIN(srcwin), WIN(dstwin)) ? BOOL_F : BOOL_T; } static char s_wmove[] = "wmove", s_wadd[] = "wadd", s_winsch[] = "winsch", s_box[] = "box"; SCM lwmove(win, y, x) SCM win, y, x; { ASRTER(NIMP(win) && WINP(win), win, ARG1, s_wmove); ASRTER(INUMP(x), x, ARG2, s_wmove); ASRTER(INUMP(y), y, ARG3, s_wmove); return ERR==wmove(WIN(win), INUM(y), INUM(x)) ? BOOL_F : BOOL_T; } SCM lwadd(win, obj) SCM win, obj; { ASRTER(NIMP(win) && WINP(win), win, ARG1, s_wadd); if (ICHRP(obj)) return ERR==waddch(WIN(win), ICHR(obj)) ? BOOL_F : BOOL_T; if (INUMP(obj)) return ERR==waddch(WIN(win), INUM(obj)) ? BOOL_F : BOOL_T; ASRTER(NIMP(obj) && STRINGP(obj), obj, ARG2, s_wadd); return ERR==waddstr(WIN(win), CHARS(obj)) ? BOOL_F : BOOL_T; } SCM lwinsch(win, obj) SCM win, obj; { ASRTER(NIMP(win) && WINP(win), win, ARG1, s_winsch); if (INUMP(obj)) return ERR==winsch(WIN(win), INUM(obj)) ? BOOL_F : BOOL_T; ASRTER(ICHRP(obj), obj, ARG2, s_winsch); return ERR==winsch(WIN(win), ICHR(obj)) ? BOOL_F : BOOL_T; } SCM lbox(win, vertch, horch) SCM win, vertch, horch; { int v, h; ASRTER(NIMP(win) && WINP(win), win, ARG1, s_box); if (INUMP(vertch)) v = INUM(vertch); else { ASRTER(ICHRP(vertch), vertch, ARG2, s_box); v = ICHR(vertch); } if (INUMP(horch)) h = INUM(horch); else { ASRTER(ICHRP(horch), horch, ARG3, s_box); h = ICHR(horch); } return ERR==box(WIN(win), v, h) ? BOOL_F : BOOL_T; } static char s_getyx[] = "getyx", s_winch[] = "winch", s_unctrl[] = "unctrl"; SCM lgetyx(win) SCM win; { int y, x; ASRTER(NIMP(win) && WINP(win), win, ARG1, s_getyx); getyx(WIN(win), y, x); return cons2(MAKINUM(y), MAKINUM(x), EOL); } SCM lwinch(win) SCM win; { ASRTER(NIMP(win) && WINP(win), win, ARG1, s_winch); return MAKICHR(winch(WIN(win))); } SCM lunctrl(c) SCM c; { ASRTER(ICHRP(c), c, ARG1, s_unctrl); { char *str = unctrl(ICHR(c)); return makfrom0str(str); } } static char s_owidth[] = "output-port-width"; static char s_oheight[] = "output-port-height"; SCM owidth(arg) SCM arg; { if (UNBNDP(arg)) arg = cur_outp; ASRTER(NIMP(arg) && OPOUTPORTP(arg), arg, ARG1, s_owidth); if (NIMP(*loc_stdscr)) { if (WINP(arg)) return MAKINUM(WIN(arg)->_maxx+1); else return MAKINUM(COLS); } return MAKINUM(80); } SCM oheight(arg) SCM arg; { if (UNBNDP(arg)) arg = cur_outp; ASRTER(NIMP(arg) && OPOUTPORTP(arg), arg, ARG1, s_owidth); if (NIMP(*loc_stdscr)) if (WINP(arg)) return MAKINUM(WIN(arg)->_maxy+1); else return MAKINUM(LINES); return MAKINUM(24); } SCM lrefresh() { return MAKINUM(wrefresh(curscr)); } #define SUBR0(lname, name) SCM lname(){name();return UNSPECIFIED;} SUBR0(lnl, nl) SUBR0(lnonl, nonl) SUBR0(lcbreak, cbreak) SUBR0(lnocbreak, nocbreak) SUBR0(lecho, echo) SUBR0(lnoecho, noecho) SUBR0(lraw, raw) SUBR0(lnoraw, noraw) SUBR0(lsavetty, savetty) SUBR0(lresetty, resetty) static char s_nonl[] = "nonl", s_nocbreak[] = "nocbreak", s_noecho[] = "noecho", s_noraw[] = "noraw"; static iproc subr0s[] = { {"initscr", linitscr}, {"endwin", lendwin}, {&s_nonl[2], lnl}, {s_nonl, lnonl}, {&s_nocbreak[2], lcbreak}, {s_nocbreak, lnocbreak}, {&s_noecho[2], lecho}, {s_noecho, lnoecho}, {&s_noraw[2], lraw}, {s_noraw, lnoraw}, {"resetty", lresetty}, {"savetty", lsavetty}, {"refresh", lrefresh}, {0, 0}}; #define SUBRW(ln, n, s_n, sn) static char s_n[]=sn;\ SCM ln(w)SCM w;\ {ASRTER(NIMP(w) && WINP(w), w, ARG1, sn);\ return ERR==n(WIN(w))?BOOL_F:BOOL_T;} SUBRW(lwerase, werase, s_werase, "werase") SUBRW(lwclear, wclear, s_wclear, "wclear") SUBRW(lwclrtobot, wclrtobot, s_wclrtobot, "wclrtobot") SUBRW(lwclrtoeol, wclrtoeol, s_wclrtoeol, "wclrtoeol") SUBRW(lwdelch, wdelch, s_wdelch, "wdelch") SUBRW(lwdeleteln, wdeleteln, s_wdeleteln, "wdeleteln") SUBRW(lwinsertln, winsertln, s_winsertln, "winsertln") SUBRW(lscroll, scroll, s_scroll, "scroll") SUBRW(ltouchwin, touchwin, s_touchwin, "touchwin") SUBRW(lwstandout, wstandout, s_wstandout, "wstandout") SUBRW(lwstandend, wstandend, s_wstandend, "wstandend") static iproc subr1s[] = { {s_werase, lwerase}, {s_wclear, lwclear}, {s_wclrtobot, lwclrtobot}, {s_wclrtoeol, lwclrtoeol}, {s_wdelch, lwdelch}, {s_wdeleteln, lwdeleteln}, {s_winsertln, lwinsertln}, {s_scroll, lscroll}, {s_touchwin, ltouchwin}, {s_wstandout, lwstandout}, {s_wstandend, lwstandend}, {s_getyx, lgetyx}, {s_winch, lwinch}, {s_unctrl, lunctrl}, {0, 0}}; #define SUBROPT(ln, n, s_n, sn) static char s_n[]=sn;\ SCM ln(w, b)SCM w, b;\ {ASRTER(NIMP(w) && WINP(w), w, ARG1, sn);\ return ERR==n(WIN(w), BOOL_F != b)?BOOL_F:BOOL_T;} SUBROPT(lidlok, idlok, s_idlok, "idlok") SUBROPT(lleaveok, leaveok, s_leaveok, "leaveok") SUBROPT(lscrollok, scrollok, s_scrollok, "scrollok") SUBROPT(lnodelay, nodelay, s_nodelay, "nodelay") /* SUBROPT(lclearok, clearok, s_clearok, "clearok") */ static char s_clearok[] = "clearok"; SCM lclearok(w, b) SCM w, b; { if (BOOL_T==w) return ERR==clearok(curscr, BOOL_F != b)?BOOL_F:BOOL_T; ASRTER(NIMP(w) && WINP(w), w, ARG1, s_clearok); return ERR==clearok(WIN(w), BOOL_F != b)?BOOL_F:BOOL_T; } static iproc subr2s[] = { {s_overlay, loverlay}, {s_overwrite, loverwrite}, {s_wadd, lwadd}, {s_winsch, lwinsch}, {s_clearok, lclearok}, {s_idlok, lidlok}, {s_leaveok, lleaveok}, {s_scrollok, lscrollok}, {s_nodelay, lnodelay}, {0, 0}}; void init_crs() { /* savetty(); */ /* "Stdscr" is a nearly inaccessible symbol used as a GC protect. */ loc_stdscr = &CDR(sysintern("Stdscr", UNDEFINED)); tc16_window = newptob(&winptob); init_iprocs(subr0s, tc7_subr_0); init_iprocs(subr1s, tc7_subr_1); init_iprocs(subr2s, tc7_subr_2); make_subr(s_owidth, tc7_subr_1o, owidth); make_subr(s_oheight, tc7_subr_1o, oheight); make_subr(s_newwin, tc7_lsubr_2, lnewwin); make_subr(s_subwin, tc7_lsubr_2, lsubwin); make_subr(s_wmove, tc7_subr_3, lwmove); make_subr(s_mvwin, tc7_subr_3, lmvwin); make_subr(s_box, tc7_subr_3, lbox); add_feature("curses"); add_final(lendwin); }