summaryrefslogtreecommitdiffstats
path: root/crs.c
diff options
context:
space:
mode:
Diffstat (limited to 'crs.c')
-rw-r--r--crs.c412
1 files changed, 412 insertions, 0 deletions
diff --git a/crs.c b/crs.c
new file mode 100644
index 0000000..5a4a5f1
--- /dev/null
+++ b/crs.c
@@ -0,0 +1,412 @@
+/* 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 General Public License as published by
+ * the Free Software Foundation; either version 2, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * As a special exception, the Free Software Foundation gives permission
+ * for additional uses of the text contained in its release of GUILE.
+ *
+ * The exception is that, if you link the GUILE library with other files
+ * to produce an executable, this does not by itself cause the
+ * resulting executable to be covered by the GNU General Public License.
+ * Your use of that executable is in no way restricted on account of
+ * linking the GUILE library code into it.
+ *
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ *
+ * This exception applies only to the code released by the
+ * Free Software Foundation under the name GUILE. If you copy
+ * code from other Free Software Foundation releases into a copy of
+ * GUILE, as the General Public License permits, the exception does
+ * not apply to the code that you add in this way. To avoid misleading
+ * anyone as to the status of such modified files, you must delete
+ * this exception notice from them.
+ *
+ * If you write modifications of your own for GUILE, it is your choice
+ * whether to permit this exception to apply to your modifications.
+ * If you do not wish that, delete this exception notice.
+ */
+
+/* "crs.c" interface to `curses' interactive terminal control library.
+ Author: Aubrey Jaffer */
+
+#include "scm.h"
+#include <curses.h>
+
+#ifdef MWC
+# include <unctrl.h>
+#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 prinwindow(exp, port, writing)
+ SCM exp; SCM port; int writing;
+{
+ prinport(exp, port, "window");
+ 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 = {
+ mark0,
+ freewindow,
+ prinwindow,
+ equal0,
+ bwaddch,
+ bwaddstr,
+ bwwrite,
+ wrefresh,
+ wgetch,
+ freewindow};
+
+SCM mkwindow(win)
+ WINDOW *win;
+{
+ SCM z;
+ if (NULL==win) return BOOL_F;
+ NEWCELL(z);
+ DEFER_INTS;
+ SETCHARS(z, win);
+ CAR(z) = 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;
+ ASSERT(INUMP(lines), lines, ARG1, s_newwin);
+ ASSERT(INUMP(cols), cols, ARG2, s_newwin);
+ ASSERT(2==ilength(args), args, WNA, s_newwin);
+ begin_y = CAR(args);
+ begin_x = CAR(CDR(args));
+ ASSERT(INUMP(begin_y), begin_y, ARG3, s_newwin);
+ ASSERT(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;
+{
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_mvwin);
+ ASSERT(INUMP(x), x, ARG2, s_mvwin);
+ ASSERT(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;
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_subwin);
+ ASSERT(INUMP(lines), lines, ARG2, s_subwin);
+ ASSERT(3==ilength(args), args, WNA, s_subwin);
+ cols = CAR(args);
+ args = CDR(args);
+ begin_y = CAR(args);
+ begin_x = CAR(CDR(args));
+ ASSERT(INUMP(cols), cols, ARG3, s_subwin);
+ ASSERT(INUMP(begin_y), begin_y, ARG3, s_subwin);
+ ASSERT(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;
+{
+ ASSERT(NIMP(srcwin) && WINP(srcwin), srcwin, ARG1, s_overlay);
+ ASSERT(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;
+{
+ ASSERT(NIMP(srcwin) && WINP(srcwin), srcwin, ARG1, s_overwrite);
+ ASSERT(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_winsert[] = "winsert",
+ s_box[] = "box";
+SCM lwmove(win, y, x)
+ SCM win, y, x;
+{
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_wmove);
+ ASSERT(INUMP(x), x, ARG2, s_wmove);
+ ASSERT(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;
+{
+ ASSERT(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;
+ ASSERT(NIMP(obj) && STRINGP(obj), obj, ARG2, s_wadd);
+ return ERR==waddstr(WIN(win), CHARS(obj)) ? BOOL_F : BOOL_T;
+}
+
+SCM lwinsert(win, obj)
+ SCM win, obj;
+{
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_winsert);
+ if INUMP(obj)
+ return ERR==winsch(WIN(win), INUM(obj)) ? BOOL_F : BOOL_T;
+ ASSERT(ICHRP(obj), obj, ARG2, s_winsert);
+ return ERR==winsch(WIN(win), ICHR(obj)) ? BOOL_F : BOOL_T;
+}
+
+SCM lbox(win, vertch, horch)
+ SCM win, vertch, horch;
+{
+ int v, h;
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_box);
+ if INUMP(vertch) v = INUM(vertch);
+ else {
+ ASSERT(ICHRP(vertch), vertch, ARG2, s_box);
+ v = ICHR(vertch);
+ }
+ if INUMP(horch) h = INUM(horch);
+ else {
+ ASSERT(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;
+ ASSERT(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;
+{
+ ASSERT(NIMP(win) && WINP(win), win, ARG1, s_winch);
+ return MAKICHR(winch(WIN(win)));
+}
+
+SCM lunctrl(c)
+ SCM c;
+{
+ ASSERT(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;
+ ASSERT(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;
+ ASSERT(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;\
+ {ASSERT(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;\
+ {ASSERT(NIMP(w) && WINP(w), w, ARG1, sn);\
+ return ERR==n(WIN(w), BOOL_F != b)?BOOL_F:BOOL_T;}
+
+/* SUBROPT(lclearok, clearok, s_clearok, "clearok") */
+/* SUBROPT(lidlok, idlok, s_idlok, "idlok") */
+SUBROPT(lleaveok, leaveok, s_leaveok, "leaveok")
+SUBROPT(lscrollok, scrollok, s_scrollok, "scrollok")
+/* SUBROPT(lnodelay, nodelay, s_nodelay, "nodelay") */
+
+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;
+ ASSERT(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_winsert, lwinsert},
+ {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);
+}