/* $RCSfile: curses.mus,v $$Revision: 4.1 $$Date: 92/08/07 18:28:53 $ * * $Log: curses.mus,v $ * Revision 4.1 92/08/07 18:28:53 lwall * * Revision 4.0.1.2 92/06/08 16:06:12 lwall * patch20: function key support added to curses.mus * * Revision 4.0.1.1 91/11/05 19:06:19 lwall * patch11: usub/curses.mus now supports SysV curses * * Revision 4.0 91/03/20 01:56:13 lwall * 4.0 baseline. * * Revision 3.0.1.1 90/08/09 04:05:21 lwall * patch19: Initial revision * */ #include "EXTERN.h" #include "perl.h" char *savestr(); #undef bool #include #ifndef A_UNDERLINE #define NOSETATTR #define A_STANDOUT 0x0200 #define A_UNDERLINE 0x0100 #define A_REVERSE 0x0200 #define A_BLINK 0x0400 #define A_BOLD 0x0800 #define A_ALTCHARSET 0x1000 #define A_NORMAL 0 #endif #ifdef USG static char *tcbuf = NULL; #endif #ifdef NOSETATTR static unsigned curattr = NORMAL; #endif static enum uservars { UV_curscr, UV_stdscr, UV_ttytype, UV_LINES, UV_COLS, UV_ERR, UV_OK, #ifdef BSD UV_Def_term, UV_My_term, #endif UV_A_STANDOUT, UV_A_UNDERLINE, UV_A_REVERSE, UV_A_BLINK, UV_A_DIM, UV_A_BOLD, UV_A_NORMAL, }; static enum usersubs { US_addch, US_waddch, US_addstr, US_waddstr, US_box, US_clear, US_wclear, US_clearok, US_clrtobot, US_wclrtobot, US_clrtoeol, US_wclrtoeol, US_delch, US_wdelch, US_deleteln, US_wdeleteln, US_erase, US_werase, US_idlok, US_insch, US_winsch, US_insertln, US_winsertln, US_move, US_wmove, US_overlay, US_overwrite, US_refresh, US_wrefresh, US_standout, US_wstandout, US_standend, US_wstandend, US_cbreak, US_nocbreak, US_echo, US_noecho, US_getch, US_wgetch, US_getstr, US_wgetstr, US_raw, US_noraw, US_baudrate, US_delwin, US_endwin, US_erasechar, US_getyx, US_inch, US_winch, US_initscr, US_killchar, US_leaveok, US_longname, US_mvwin, US_newwin, US_nl, US_nonl, US_scrollok, US_subwin, US_touchline, US_touchwin, US_unctrl, US_gettmode, US_mvcur, US_scroll, US_savetty, US_resetty, US_setterm, US_attroff, US_wattroff, US_attron, US_wattron, US_attrset, US_wattrset, #ifdef CURSEFMT US_printw, /* remove */ US_wprintw, /* remove */ US_scanw, /* delete */ US_wscanw, /* delete */ #endif US_getcap, #ifdef BSD US_flushok, US_fullname, US_touchoverlap, US_tstp, US__putchar, #endif US_mysub, US_testcallback, }; static int usersub(); static int userset(); static int userval(); int init_curses() { struct ufuncs uf; char *filename = "curses.c"; uf.uf_set = userset; uf.uf_val = userval; #define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf) MAGICVAR("curscr", UV_curscr); MAGICVAR("stdscr", UV_stdscr); MAGICVAR("ttytype", UV_ttytype); MAGICVAR("LINES", UV_LINES); MAGICVAR("COLS", UV_COLS); MAGICVAR("ERR", UV_ERR); MAGICVAR("OK", UV_OK); #ifdef BSD MAGICVAR("Def_term",UV_Def_term); MAGICVAR("My_term", UV_My_term); #endif MAGICVAR("A_STANDOUT", UV_A_STANDOUT); MAGICVAR("A_UNDERLINE", UV_A_UNDERLINE); MAGICVAR("A_REVERSE", UV_A_REVERSE); MAGICVAR("A_BLINK", UV_A_BLINK); MAGICVAR("A_DIM", UV_A_DIM); MAGICVAR("A_BOLD", UV_A_BOLD); MAGICVAR("A_NORMAL", UV_A_NORMAL); make_usub("addch", US_addch, usersub, filename); make_usub("waddch", US_waddch, usersub, filename); make_usub("addstr", US_addstr, usersub, filename); make_usub("waddstr", US_waddstr, usersub, filename); make_usub("box", US_box, usersub, filename); make_usub("clear", US_clear, usersub, filename); make_usub("wclear", US_wclear, usersub, filename); make_usub("clearok", US_clearok, usersub, filename); make_usub("clrtobot", US_clrtobot, usersub, filename); make_usub("wclrtobot", US_wclrtobot, usersub, filename); make_usub("clrtoeol", US_clrtoeol, usersub, filename); make_usub("wclrtoeol", US_wclrtoeol, usersub, filename); make_usub("delch", US_delch, usersub, filename); make_usub("wdelch", US_wdelch, usersub, filename); make_usub("deleteln", US_deleteln, usersub, filename); make_usub("wdeleteln", US_wdeleteln, usersub, filename); make_usub("erase", US_erase, usersub, filename); make_usub("werase", US_werase, usersub, filename); make_usub("idlok", US_idlok, usersub, filename); make_usub("insch", US_insch, usersub, filename); make_usub("winsch", US_winsch, usersub, filename); make_usub("insertln", US_insertln, usersub, filename); make_usub("winsertln", US_winsertln, usersub, filename); make_usub("move", US_move, usersub, filename); make_usub("wmove", US_wmove, usersub, filename); make_usub("overlay", US_overlay, usersub, filename); make_usub("overwrite", US_overwrite, usersub, filename); make_usub("refresh", US_refresh, usersub, filename); make_usub("wrefresh", US_wrefresh, usersub, filename); make_usub("standout", US_standout, usersub, filename); make_usub("wstandout", US_wstandout, usersub, filename); make_usub("standend", US_standend, usersub, filename); make_usub("wstandend", US_wstandend, usersub, filename); make_usub("cbreak", US_cbreak, usersub, filename); make_usub("nocbreak", US_nocbreak, usersub, filename); make_usub("echo", US_echo, usersub, filename); make_usub("noecho", US_noecho, usersub, filename); make_usub("getch", US_getch, usersub, filename); make_usub("wgetch", US_wgetch, usersub, filename); make_usub("getstr", US_getstr, usersub, filename); make_usub("wgetstr", US_wgetstr, usersub, filename); make_usub("raw", US_raw, usersub, filename); make_usub("noraw", US_noraw, usersub, filename); make_usub("baudrate", US_baudrate, usersub, filename); make_usub("delwin", US_delwin, usersub, filename); make_usub("endwin", US_endwin, usersub, filename); make_usub("erasechar", US_erasechar, usersub, filename); make_usub("getyx", US_getyx, usersub, filename); make_usub("inch", US_inch, usersub, filename); make_usub("winch", US_winch, usersub, filename); make_usub("initscr", US_initscr, usersub, filename); make_usub("killchar", US_killchar, usersub, filename); make_usub("leaveok", US_leaveok, usersub, filename); make_usub("longname", US_longname, usersub, filename); make_usub("mvwin", US_mvwin, usersub, filename); make_usub("newwin", US_newwin, usersub, filename); make_usub("nl", US_nl, usersub, filename); make_usub("nonl", US_nonl, usersub, filename); make_usub("scrollok", US_scrollok, usersub, filename); make_usub("subwin", US_subwin, usersub, filename); make_usub("touchline", US_touchline, usersub, filename); make_usub("touchwin", US_touchwin, usersub, filename); make_usub("unctrl", US_unctrl, usersub, filename); make_usub("gettmode", US_gettmode, usersub, filename); make_usub("mvcur", US_mvcur, usersub, filename); make_usub("scroll", US_scroll, usersub, filename); make_usub("savetty", US_savetty, usersub, filename); make_usub("resetty", US_resetty, usersub, filename); make_usub("setterm", US_setterm, usersub, filename); make_usub("getcap", US_getcap, usersub, filename); make_usub("attroff", US_attroff, usersub, filename); make_usub("wattroff", US_wattroff, usersub, filename); make_usub("attron", US_attron, usersub, filename); make_usub("wattron", US_wattron, usersub, filename); make_usub("attrset", US_attrset, usersub, filename); make_usub("wattrset", US_wattrset, usersub, filename); #ifdef CURSEFMT make_usub("printw", US_printw, usersub, filename); make_usub("wprintw", US_wprintw, usersub, filename); make_usub("scanw", US_scanw, usersub, filename); make_usub("wscanw", US_wscanw, usersub, filename); #endif #ifdef BSD make_usub("flushok", US_flushok, usersub, filename); make_usub("fullname", US_fullname, usersub, filename); make_usub("touchoverlap", US_touchoverlap,usersub, filename); make_usub("tstp", US_tstp, usersub, filename); make_usub("_putchar", US__putchar, usersub, filename); #endif make_usub("testcallback", US_testcallback,usersub, filename); }; #ifdef USG static char *getcap(cap) register char *cap; { static char nocaperr[] = "Cannot read termcap entry."; extern char *tgetstr(); if (tcbuf == NULL) { if ((tcbuf = malloc(1024)) == NULL) { fatal(nocaperr); } if (tgetent(tcbuf, ttytype) == -1) { fatal(nocaperr); } } return (tgetstr(cap, NULL)); } #endif #ifdef NOSETATTR #define attron(attr) wattron(stdscr, attr) #define attroff(attr) wattroff(stdscr, attr) #define attset(attr) wattset(stdscr, attr) int wattron(win, attr) WINDOW *win; chtype attr; { curattr |= attr; if (curattr & A_STANDOUT) { return(wstandout(win)); } else { return(wstandend(win)); } } int wattroff(win, attr) WINDOW *win; chtype attr; { curattr &= (~attr); if (curattr & A_STANDOUT) { return(wstandout(win)); } else { return(wstandend(win)); } } int wattrset(win, attr) WINDOW *win; chtype attr; { curattr = attr; if (curattr & A_STANDOUT) { return(wstandout(win)); } else { return(wstandend(win)); } } #endif static int usersub(ix, sp, items) int ix; register int sp; register int items; { STR **st = stack->ary_array + sp; register int i; register char *tmps; register STR *Str; /* used in str_get and str_gnum macros */ switch (ix) { CASE int addch I char ch END CASE int waddch I WINDOW* win I char ch END CASE int addstr I char* str END CASE int waddstr I WINDOW* win I char* str END CASE int box I WINDOW* win I char vert I char hor END CASE int clear END CASE int wclear I WINDOW* win END CASE int clearok I WINDOW* win I bool boolf END CASE int clrtobot END CASE int wclrtobot I WINDOW* win END CASE int clrtoeol END CASE int wclrtoeol I WINDOW* win END CASE int delch END CASE int wdelch I WINDOW* win END CASE int deleteln END CASE int wdeleteln I WINDOW* win END CASE int erase END CASE int werase I WINDOW* win END CASE int idlok I WINDOW* win I bool boolf END CASE int insch I char c END CASE int winsch I WINDOW* win I char c END CASE int insertln END CASE int winsertln I WINDOW* win END CASE int move I int y I int x END CASE int wmove I WINDOW* win I int y I int x END CASE int overlay I WINDOW* win1 I WINDOW* win2 END CASE int overwrite I WINDOW* win1 I WINDOW* win2 END CASE int refresh END CASE int wrefresh I WINDOW* win END CASE int standout END CASE int wstandout I WINDOW* win END CASE int standend END CASE int wstandend I WINDOW* win END CASE int cbreak END CASE int nocbreak END CASE int echo END CASE int noecho END case US_getch: if (items != 0) fatal("Usage: &getch()"); else { int retval; char retch; retval = getch(); if (retval == EOF) st[0] = &str_undef; else { retch = retval; if (retval > 0377) str_numset(st[0], (double) retval); else str_nset(st[0], &retch, 1); } } return sp; case US_wgetch: if (items != 1) fatal("Usage: &wgetch($win)"); else { int retval; char retch; WINDOW* win = *(WINDOW**) str_get(st[1]); retval = wgetch(win); if (retval == EOF) st[0] = &str_undef; else { retch = retval; if (retval > 0377) str_numset(st[0], (double) retval); else str_nset(st[0], &retch, 1); } } return sp; CASE int getstr O char* str END CASE int wgetstr I WINDOW* win O char* str END CASE int raw END CASE int noraw END CASE int baudrate END CASE int delwin I WINDOW* win END CASE int endwin END CASE int erasechar END case US_getyx: if (items != 3) fatal("Usage: &getyx($win, $y, $x)"); else { int retval; STR* str = str_new(0); WINDOW* win = *(WINDOW**) str_get(st[1]); int y; int x; do_sprintf(str, items - 1, st + 1); retval = getyx(win, y, x); str_numset(st[2], (double)y); str_numset(st[3], (double)x); str_numset(st[0], (double) retval); str_free(str); } return sp; CASE int inch END CASE int winch I WINDOW* win END CASE WINDOW* initscr END CASE int killchar END CASE int leaveok I WINDOW* win I bool boolf END #ifdef BSD CASE char* longname I char* termbuf IO char* name END #else CASE char* longname I char* termbug I char* name END #endif CASE int mvwin I WINDOW* win I int y I int x END CASE WINDOW* newwin I int lines I int cols I int begin_y I int begin_x END CASE int nl END CASE int nonl END CASE int scrollok I WINDOW* win I bool boolf END CASE WINDOW* subwin I WINDOW* win I int lines I int cols I int begin_y I int begin_x END CASE int touchline I WINDOW* win I int y I int startx I int endx END CASE int touchwin I WINDOW* win END CASE char* unctrl I char ch END CASE int gettmode END CASE int mvcur I int lasty I int lastx I int newy I int newx END CASE int scroll I WINDOW* win END CASE int savetty END CASE void resetty END CASE int setterm I char* name END CASE int attroff I chtype str END CASE int wattroff I chtype str END CASE int wattron I chtype str END CASE int attron I chtype str END CASE int attrset I chtype str END CASE int wattrset I chtype str END #ifdef CURSEFMT case US_printw: if (items < 1) fatal("Usage: &printw($fmt, $arg1, $arg2, ... )"); else { int retval; STR* str = str_new(0); do_sprintf(str, items, st + 1); retval = addstr(str->str_ptr); str_numset(st[0], (double) retval); str_free(str); } return sp; case US_wprintw: if (items < 2) fatal("Usage: &wprintw($win, $fmt, $arg1, $arg2, ... )"); else { int retval; STR* str = str_new(0); WINDOW* win = *(WINDOW**) str_get(st[1]); do_sprintf(str, items - 1, st + 1); retval = waddstr(win, str->str_ptr); str_numset(st[0], (double) retval); str_free(str); } return sp; #endif CASE char* getcap I char* str END #ifdef BSD CASE int flushok I WINDOW* win I bool boolf END CASE int fullname I char* termbuf IO char* name END CASE int touchoverlap I WINDOW* win1 I WINDOW* win2 END CASE int tstp END CASE int _putchar I char ch END case US_testcallback: sp = callback("callback", sp + items, curcsv->wantarray, 1, items); break; #endif default: fatal("Unimplemented user-defined subroutine"); } return sp; } static int userval(ix, str) int ix; STR *str; { switch (ix) { case UV_COLS: str_numset(str, (double)COLS); break; case UV_ERR: str_numset(str, (double)ERR); break; case UV_LINES: str_numset(str, (double)LINES); break; case UV_OK: str_numset(str, (double)OK); break; case UV_curscr: str_nset(str, &curscr, sizeof(WINDOW*)); break; case UV_stdscr: str_nset(str, &stdscr, sizeof(WINDOW*)); break; case UV_ttytype: str_set(str, ttytype); break; #ifdef BSD case UV_Def_term: str_set(str, Def_term); break; case UV_My_term: str_numset(str, (double)My_term); break; #endif case UV_A_STANDOUT: str_numset(str, (double)A_STANDOUT); break; case UV_A_UNDERLINE: str_numset(str, (double)A_UNDERLINE); break; case UV_A_REVERSE: str_numset(str, (double)A_REVERSE); break; case UV_A_BLINK: str_numset(str, (double)A_BLINK); break; case UV_A_DIM: str_numset(str, (double)A_DIM); break; case UV_A_BOLD: str_numset(str, (double)A_BOLD); break; case UV_A_NORMAL: str_numset(str, (double)A_NORMAL); break; } return 0; } static int userset(ix, str) int ix; STR *str; { switch (ix) { case UV_COLS: COLS = (int)str_gnum(str); break; case UV_LINES: LINES = (int)str_gnum(str); break; case UV_ttytype: strcpy(ttytype, str_get(str)); /* hope it fits */ #ifdef USG if (tcbuf != NULL) { free(tcbuf); tcbuf = NULL; } #endif break; #ifdef BSD case UV_Def_term: Def_term = savestr(str_get(str)); /* never freed */ break; case UV_My_term: My_term = (bool)str_gnum(str); break; #endif } return 0; }