/************************************************************************* * Library: lcurses - Lua 5.1 interface to the curses library * * * * (c) Reuben Thomas <rrt@sc3d.org> 2009-2012 * * (c) Tiago Dionizio <tiago.dionizio AT gmail.com> 2004-2007 * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ************************************************************************/ #include <config.h> #include <stdlib.h> #include <string.h> #include <lua.h> #include <lauxlib.h> #include "lua52compat.h" #if HAVE_NCURSESW_CURSES_H # include <ncursesw/curses.h> #elif HAVE_NCURSESW_H # include <ncursesw.h> #elif HAVE_NCURSES_CURSES_H # include <ncurses/curses.h> #elif HAVE_NCURSES_H # include <ncurses.h> #elif HAVE_CURSES_H # include <curses.h> #else # error "SysV or X/Open-compatible Curses header file required" #endif #include <term.h> /* The extra indirection to these macros is required so that if the arguments are themselves macros, they will get expanded too. */ #define LCURSES__SPLICE(_s, _t) _s##_t #define LCURSES_SPLICE(_s, _t) LCURSES__SPLICE(_s, _t) #define LCURSES__STR(_s) #_s #define LCURSES_STR(_s) LCURSES__STR(_s) /* The +1 is to step over the leading '_' that is required to prevent premature expansion of MENTRY arguments if we didn't add it. */ #define LCURSES__STR_1(_s) (#_s + 1) #define LCURSES_STR_1(_s) LCURSES__STR_1(_s) /* strlcpy() implementation for non-BSD based Unices. strlcpy() is a safer less error-prone replacement for strncpy(). */ #include "strlcpy.c" /* ** ======================================================= ** defines ** ======================================================= */ static const char *STDSCR_REGISTRY = "curses:stdscr"; static const char *WINDOWMETA = "curses:window"; static const char *CHSTRMETA = "curses:chstr"; static const char *RIPOFF_TABLE = "curses:ripoffline"; #define B(v) ((((int) (v)) == OK)) /* ======================================================= */ #define LC_NUMBER(v) \ static int C ## v(lua_State *L) \ { \ lua_pushinteger(L, v()); \ return 1; \ } #define LC_NUMBER2(n,v) \ static int n(lua_State *L) \ { \ lua_pushinteger(L, v); \ return 1; \ } /* ======================================================= */ #define LC_STRING(v) \ static int C ## v(lua_State *L) \ { \ lua_pushstring(L, v()); \ return 1; \ } #define LC_STRING2(n,v) \ static int n(lua_State *L) \ { \ lua_pushstring(L, v); \ return 1; \ } /* ======================================================= */ #define LC_BOOL(v) \ static int C ## v(lua_State *L) \ { \ lua_pushboolean(L, v()); \ return 1; \ } /* ======================================================= */ #define LC_BOOLOK(v) \ static int C ## v(lua_State *L) \ { \ lua_pushboolean(L, B(v())); \ return 1; \ } /* ======================================================= */ #define LCW_BOOLOK(n) \ static int W ## n(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ lua_pushboolean(L, B(n(w))); \ return 1; \ } #define LCW_BOOLOK2(n,v) \ static int n(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ lua_pushboolean(L, B(v(w))); \ return 1; \ } /* ** ======================================================= ** privates ** ======================================================= */ static void lc_newwin(lua_State *L, WINDOW *nw) { if (nw) { WINDOW **w = lua_newuserdata(L, sizeof(WINDOW*)); luaL_getmetatable(L, WINDOWMETA); lua_setmetatable(L, -2); *w = nw; } else { lua_pushliteral(L, "failed to create window"); lua_error(L); } } static WINDOW **lc_getwin(lua_State *L, int offset) { WINDOW **w = (WINDOW**)luaL_checkudata(L, offset, WINDOWMETA); if (w == NULL) luaL_argerror(L, offset, "bad curses window"); return w; } static WINDOW *checkwin(lua_State *L, int offset) { WINDOW **w = lc_getwin(L, offset); if (*w == NULL) luaL_argerror(L, offset, "attempt to use closed curses window"); return *w; } static int W__tostring(lua_State *L) { WINDOW **w = lc_getwin(L, 1); char buff[34]; if (*w == NULL) strcpy(buff, "closed"); else sprintf(buff, "%p", lua_touserdata(L, 1)); lua_pushfstring(L, "curses window (%s)", buff); return 1; } /* ** ======================================================= ** chtype handling ** ======================================================= */ static chtype checkch(lua_State *L, int offset) { if (lua_type(L, offset) == LUA_TNUMBER) return luaL_checknumber(L, offset); if (lua_type(L, offset) == LUA_TSTRING) return *lua_tostring(L, offset); luaL_typerror(L, offset, "chtype"); /* never executes */ return 0; } static chtype optch(lua_State *L, int offset, chtype def) { if (lua_isnoneornil(L, offset)) return def; return checkch(L, offset); } /****c* classes/chstr * FUNCTION * Line drawing buffer. * * SEE ALSO * curses.new_chstr ****/ typedef struct { unsigned int len; chtype str[1]; } chstr; #define CHSTR_SIZE(len) (sizeof(chstr) + len * sizeof(chtype)) /* create new chstr object and leave it in the lua stack */ static chstr* chstr_new(lua_State *L, int len) { if (len < 1) { lua_pushliteral(L, "invalid chstr length"); lua_error(L); } { chstr *cs = lua_newuserdata(L, CHSTR_SIZE(len)); luaL_getmetatable(L, CHSTRMETA); lua_setmetatable(L, -2); cs->len = len; return cs; } } /* get chstr from lua (convert if needed) */ static chstr* checkchstr(lua_State *L, int offset) { chstr *cs = (chstr*)luaL_checkudata(L, offset, CHSTRMETA); if (cs) return cs; luaL_argerror(L, offset, "bad curses chstr"); return NULL; } /****f* curses/curses.new_chstr * FUNCTION * Create a new line drawing buffer instance. * * SEE ALSO * chstr ****/ static int Cnew_chstr(lua_State *L) { int len = luaL_checkint(L, 1); chstr* ncs = chstr_new(L, len); memset(ncs->str, ' ', len*sizeof(chtype)); return 1; } /* change the contents of the chstr */ static int chstr_set_str(lua_State *L) { chstr *cs = checkchstr(L, 1); int offset = luaL_checkint(L, 2); const char *str = luaL_checkstring(L, 3); int len = lua_strlen(L, 3); int attr = luaL_optnumber(L, 4, A_NORMAL); int rep = luaL_optint(L, 5, 1); int i; if (offset < 0) return 0; while (rep-- > 0 && offset <= (int)cs->len) { if (offset + len - 1 > (int)cs->len) len = cs->len - offset + 1; for (i = 0; i < len; ++i) cs->str[offset + i] = str[i] | attr; offset += len; } return 0; } /****m* chstr/set_ch * FUNCTION * Set a character in the buffer. * * SYNOPSIS * chstr:set_ch(offset, char, attribute [, repeat]) * * EXAMPLE * Set the buffer with 'a's where the first one is capitalized * and has bold. * size = 10 * str = curses.new_chstr(10) * str:set_ch(0, 'A', curses.A_BOLD) * str:set_ch(1, 'a', curses.A_NORMAL, size - 1) ****/ static int chstr_set_ch(lua_State *L) { chstr* cs = checkchstr(L, 1); int offset = luaL_checkint(L, 2); chtype ch = checkch(L, 3); int attr = luaL_optnumber(L, 4, A_NORMAL); int rep = luaL_optint(L, 5, 1); while (rep-- > 0) { if (offset < 0 || offset >= (int) cs->len) return 0; cs->str[offset] = ch | attr; ++offset; } return 0; } /* get information from the chstr */ static int chstr_get(lua_State *L) { chstr* cs = checkchstr(L, 1); int offset = luaL_checkint(L, 2); chtype ch; if (offset < 0 || offset >= (int) cs->len) return 0; ch = cs->str[offset]; lua_pushinteger(L, ch & A_CHARTEXT); lua_pushinteger(L, ch & A_ATTRIBUTES); lua_pushinteger(L, ch & A_COLOR); return 3; } /* retrieve chstr length */ static int chstr_len(lua_State *L) { chstr *cs = checkchstr(L, 1); lua_pushinteger(L, cs->len); return 1; } /* duplicate chstr */ static int chstr_dup(lua_State *L) { chstr *cs = checkchstr(L, 1); chstr *ncs = chstr_new(L, cs->len); memcpy(ncs->str, cs->str, CHSTR_SIZE(cs->len)); return 1; } /* ** ======================================================= ** initscr ** ======================================================= */ #define CCR(n, v) \ lua_pushstring(L, n); \ lua_pushinteger(L, v); \ lua_settable(L, lua_upvalueindex(1)); #define CC(s) CCR(#s, s) #define CF(i) CCR(LCURSES_STR(LCURSES_SPLICE(KEY_F, i)), KEY_F(i)) /* ** these values may be fixed only after initialization, so this is ** called from Cinitscr, after the curses driver is initialized ** ** curses table is kept at upvalue position 1, in case the global ** name is changed by the user or even in the registration phase by ** the developer ** ** some of these values are not constant so need to register ** them directly instead of using a table */ static void register_curses_constants(lua_State *L) { /* colors */ CC(COLOR_BLACK) CC(COLOR_RED) CC(COLOR_GREEN) CC(COLOR_YELLOW) CC(COLOR_BLUE) CC(COLOR_MAGENTA) CC(COLOR_CYAN) CC(COLOR_WHITE) /* alternate character set */ CC(ACS_BLOCK) CC(ACS_BOARD) CC(ACS_BTEE) CC(ACS_TTEE) CC(ACS_LTEE) CC(ACS_RTEE) CC(ACS_LLCORNER) CC(ACS_LRCORNER) CC(ACS_URCORNER) CC(ACS_ULCORNER) CC(ACS_LARROW) CC(ACS_RARROW) CC(ACS_UARROW) CC(ACS_DARROW) CC(ACS_HLINE) CC(ACS_VLINE) CC(ACS_BULLET) CC(ACS_CKBOARD) CC(ACS_LANTERN) CC(ACS_DEGREE) CC(ACS_DIAMOND) CC(ACS_PLMINUS) CC(ACS_PLUS) CC(ACS_S1) CC(ACS_S9) /* attributes */ CC(A_NORMAL) CC(A_STANDOUT) CC(A_UNDERLINE) CC(A_REVERSE) CC(A_BLINK) CC(A_DIM) CC(A_BOLD) CC(A_PROTECT) CC(A_INVIS) CC(A_ALTCHARSET) CC(A_CHARTEXT) CC(A_ATTRIBUTES) /* key functions */ CC(KEY_BREAK) CC(KEY_DOWN) CC(KEY_UP) CC(KEY_LEFT) CC(KEY_RIGHT) CC(KEY_HOME) CC(KEY_BACKSPACE) CC(KEY_DL) CC(KEY_IL) CC(KEY_DC) CC(KEY_IC) CC(KEY_EIC) CC(KEY_CLEAR) CC(KEY_EOS) CC(KEY_EOL) CC(KEY_SF) CC(KEY_SR) CC(KEY_NPAGE) CC(KEY_PPAGE) CC(KEY_STAB) CC(KEY_CTAB) CC(KEY_CATAB) CC(KEY_ENTER) CC(KEY_SRESET) CC(KEY_RESET) CC(KEY_PRINT) CC(KEY_LL) CC(KEY_A1) CC(KEY_A3) CC(KEY_B2) CC(KEY_C1) CC(KEY_C3) CC(KEY_BTAB) CC(KEY_BEG) CC(KEY_CANCEL) CC(KEY_CLOSE) CC(KEY_COMMAND) CC(KEY_COPY) CC(KEY_CREATE) CC(KEY_END) CC(KEY_EXIT) CC(KEY_FIND) CC(KEY_HELP) CC(KEY_MARK) CC(KEY_MESSAGE) CC(KEY_MOUSE) CC(KEY_MOVE) CC(KEY_NEXT) CC(KEY_OPEN) CC(KEY_OPTIONS) CC(KEY_PREVIOUS) CC(KEY_REDO) CC(KEY_REFERENCE) CC(KEY_REFRESH) CC(KEY_REPLACE) CC(KEY_RESIZE) CC(KEY_RESTART) CC(KEY_RESUME) CC(KEY_SAVE) CC(KEY_SBEG) CC(KEY_SCANCEL) CC(KEY_SCOMMAND) CC(KEY_SCOPY) CC(KEY_SCREATE) CC(KEY_SDC) CC(KEY_SDL) CC(KEY_SELECT) CC(KEY_SEND) CC(KEY_SEOL) CC(KEY_SEXIT) CC(KEY_SFIND) CC(KEY_SHELP) CC(KEY_SHOME) CC(KEY_SIC) CC(KEY_SLEFT) CC(KEY_SMESSAGE) CC(KEY_SMOVE) CC(KEY_SNEXT) CC(KEY_SOPTIONS) CC(KEY_SPREVIOUS) CC(KEY_SPRINT) CC(KEY_SREDO) CC(KEY_SREPLACE) CC(KEY_SRIGHT) CC(KEY_SRSUME) CC(KEY_SSAVE) CC(KEY_SSUSPEND) CC(KEY_SUNDO) CC(KEY_SUSPEND) CC(KEY_UNDO) /* KEY_Fx 0 <= x <= 63 */ CC(KEY_F0) CF(1) CF(2) CF(3) CF(4) CF(5) CF(6) CF(7) CF(8) CF(9) CF(10) CF(11) CF(12) CF(13) CF(14) CF(15) CF(16) CF(17) CF(18) CF(19) CF(20) CF(21) CF(22) CF(23) CF(24) CF(25) CF(26) CF(27) CF(28) CF(29) CF(30) CF(21) CF(32) CF(33) CF(34) CF(35) CF(36) CF(37) CF(38) CF(39) CF(40) CF(41) CF(42) CF(43) CF(44) CF(45) CF(46) CF(47) CF(48) CF(49) CF(50) CF(51) CF(52) CF(53) CF(54) CF(55) CF(56) CF(57) CF(58) CF(59) CF(60) CF(61) CF(62) CF(63) } /* ** make sure screen is restored (and cleared) at exit ** (for the situations where program is aborted without a ** proper cleanup) */ static void cleanup(void) { if (!isendwin()) { wclear(stdscr); wrefresh(stdscr); endwin(); } } static int Cinitscr(lua_State *L) { WINDOW *w; /* initialize curses */ w = initscr(); /* no longer used, so clean it up */ lua_pushstring(L, RIPOFF_TABLE); lua_pushnil(L); lua_settable(L, LUA_REGISTRYINDEX); /* failed to initialize */ if (w == NULL) return 0; /* return stdscr - main window */ lc_newwin(L, w); /* save main window on registry */ lua_pushstring(L, STDSCR_REGISTRY); lua_pushvalue(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); /* setup curses constants - curses.xxx numbers */ register_curses_constants(L); /* install cleanup handler to help in debugging and screen trashing */ atexit(cleanup); return 1; } /* FIXME: Avoid cast to void. */ static int Cendwin(lua_State *L) { (void) L; endwin(); return 0; } LC_BOOL(isendwin) static int Cstdscr(lua_State *L) { lua_pushstring(L, STDSCR_REGISTRY); lua_rawget(L, LUA_REGISTRYINDEX); return 1; } LC_NUMBER2(Ccols, COLS) LC_NUMBER2(Clines, LINES) /* ** ======================================================= ** color ** ======================================================= */ LC_BOOLOK(start_color) LC_BOOL(has_colors) LC_BOOLOK(use_default_colors) static int Cinit_pair(lua_State *L) { short pair = luaL_checkint(L, 1); short f = luaL_checkint(L, 2); short b = luaL_checkint(L, 3); lua_pushboolean(L, B(init_pair(pair, f, b))); return 1; } static int Cpair_content(lua_State *L) { short pair = luaL_checkint(L, 1); short f; short b; int ret = pair_content(pair, &f, &b); if (ret == ERR) return 0; lua_pushinteger(L, f); lua_pushinteger(L, b); return 2; } LC_NUMBER2(Ccolors, COLORS) LC_NUMBER2(Ccolor_pairs, COLOR_PAIRS) static int Ccolor_pair(lua_State *L) { int n = luaL_checkint(L, 1); lua_pushinteger(L, COLOR_PAIR(n)); return 1; } /* ** ======================================================= ** termattrs ** ======================================================= */ LC_NUMBER(baudrate) LC_NUMBER(erasechar) LC_BOOL(has_ic) LC_BOOL(has_il) LC_NUMBER(killchar) static int Ctermattrs(lua_State *L) { if (lua_gettop(L) < 1) lua_pushinteger(L, termattrs()); else { int a = luaL_checkint(L, 1); lua_pushboolean(L, termattrs() & a); } return 1; } LC_STRING(termname) LC_STRING(longname) /* ** ======================================================= ** kernel ** ======================================================= */ /* there is no easy way to implement this... */ static lua_State *rip_L = NULL; static int ripoffline_cb(WINDOW* w, int cols) { static int line = 0; int top = lua_gettop(rip_L); /* better be safe */ if (!lua_checkstack(rip_L, 5)) return 0; /* get the table from the registry */ lua_pushstring(rip_L, RIPOFF_TABLE); lua_gettable(rip_L, LUA_REGISTRYINDEX); /* get user callback function */ if (lua_isnil(rip_L, -1)) { lua_pop(rip_L, 1); return 0; } lua_rawgeti(rip_L, -1, ++line); /* function to be called */ lc_newwin(rip_L, w); /* create window object */ lua_pushinteger(rip_L, cols); /* push number of columns */ lua_pcall(rip_L, 2, 0, 0); /* call the lua function */ lua_settop(rip_L, top); return 1; } static int Cripoffline(lua_State *L) { static int rip = 0; int top_line = lua_toboolean(L, 1); if (!lua_isfunction(L, 2)) { lua_pushliteral(L, "invalid callback passed as second parameter"); lua_error(L); } /* need to save the lua state somewhere... */ rip_L = L; /* get the table where we are going to save the callbacks */ lua_pushstring(L, RIPOFF_TABLE); lua_gettable(L, LUA_REGISTRYINDEX); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushstring(L, RIPOFF_TABLE); lua_pushvalue(L, -2); lua_settable(L, LUA_REGISTRYINDEX); } /* save function callback in registry table */ lua_pushvalue(L, 2); lua_rawseti(L, -2, ++rip); /* and tell curses we are going to take the line */ lua_pushboolean(L, B(ripoffline(top_line ? 1 : -1, ripoffline_cb))); return 1; } static int Ccurs_set(lua_State *L) { int vis = luaL_checkint(L, 1); int state = curs_set(vis); if (state == ERR) return 0; lua_pushinteger(L, state); return 1; } static int Cnapms(lua_State *L) { int ms = luaL_checkint(L, 1); lua_pushboolean(L, B(napms(ms))); return 1; } /* ** ======================================================= ** resizeterm ** ======================================================= */ static int Cresizeterm(lua_State *L) { int nlines = luaL_checkint(L, 1); int ncols = luaL_checkint(L, 2); #if HAVE_RESIZETERM lua_pushboolean(L, B(resizeterm (nlines, ncols))); return 1; #else return luaL_error (L, "`resizeterm' is not implemented by your curses library"); #endif } /* ** ======================================================= ** beep ** ======================================================= */ LC_BOOLOK(beep) LC_BOOLOK(flash) /* ** ======================================================= ** window ** ======================================================= */ static int Cnewwin(lua_State *L) { int nlines = luaL_checkint(L, 1); int ncols = luaL_checkint(L, 2); int begin_y = luaL_checkint(L, 3); int begin_x = luaL_checkint(L, 4); lc_newwin(L, newwin(nlines, ncols, begin_y, begin_x)); return 1; } static int Wclose(lua_State *L) { WINDOW **w = lc_getwin(L, 1); if (*w != NULL && *w != stdscr) { delwin(*w); *w = NULL; } return 0; } static int Wmove_window(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); lua_pushboolean(L, B(mvwin(w, y, x))); return 1; } static int Wsub(lua_State *L) { WINDOW *orig = checkwin(L, 1); int nlines = luaL_checkint(L, 2); int ncols = luaL_checkint(L, 3); int begin_y = luaL_checkint(L, 4); int begin_x = luaL_checkint(L, 5); lc_newwin(L, subwin(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int Wderive(lua_State *L) { WINDOW *orig = checkwin(L, 1); int nlines = luaL_checkint(L, 2); int ncols = luaL_checkint(L, 3); int begin_y = luaL_checkint(L, 4); int begin_x = luaL_checkint(L, 5); lc_newwin(L, derwin(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int Wmove_derived(lua_State *L) { WINDOW *w = checkwin(L, 1); int par_y = luaL_checkint(L, 2); int par_x = luaL_checkint(L, 3); lua_pushboolean(L, B(mvderwin(w, par_y, par_x))); return 1; } static int Wresize(lua_State *L) { WINDOW *w = checkwin(L, 1); int height = luaL_checkint(L, 2); int width = luaL_checkint(L, 3); int c = wresize(w, height, width); if (c == ERR) return 0; lua_pushboolean(L, B(true)); return 1; } #define LCW_WIN2(n, v) \ static int n(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ v(w); \ return 0; \ } static int Wclone(lua_State *L) { WINDOW *w = checkwin(L, 1); lc_newwin(L, dupwin(w)); return 1; } LCW_WIN2(Wsyncup, wsyncup) static int Wsyncok(lua_State *L) { WINDOW *w = checkwin(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(syncok(w, bf))); return 1; } LCW_WIN2(Wcursyncup, wcursyncup) LCW_WIN2(Wsyncdown, wsyncdown) /* ** ======================================================= ** refresh ** ======================================================= */ LCW_BOOLOK2(Wrefresh, wrefresh) LCW_BOOLOK2(Wnoutrefresh, wnoutrefresh) LCW_BOOLOK(redrawwin) static int Wredrawln(lua_State *L) { WINDOW *w = checkwin(L, 1); int beg_line = luaL_checkint(L, 2); int num_lines = luaL_checkint(L, 3); lua_pushboolean(L, B(wredrawln(w, beg_line, num_lines))); return 1; } LC_BOOLOK(doupdate) /* ** ======================================================= ** move ** ======================================================= */ static int Wmove(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); lua_pushboolean(L, B(wmove(w, y, x))); return 1; } /* ** ======================================================= ** scroll ** ======================================================= */ static int Wscrl(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_checkint(L, 2); lua_pushboolean(L, B(wscrl(w, n))); return 1; } /* ** ======================================================= ** touch ** ======================================================= */ static int Wtouch(lua_State *L) { WINDOW *w = checkwin(L, 1); int changed; if (lua_isnoneornil(L, 2)) changed = TRUE; else changed = lua_toboolean(L, 2); if (changed) lua_pushboolean(L, B(touchwin(w))); else lua_pushboolean(L, B(untouchwin(w))); return 1; } static int Wtouchline(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int n = luaL_checkint(L, 3); int changed; if (lua_isnoneornil(L, 4)) changed = TRUE; else changed = lua_toboolean(L, 4); lua_pushboolean(L, B(wtouchln(w, y, n, changed))); return 1; } static int Wis_linetouched(lua_State *L) { WINDOW *w = checkwin(L, 1); int line = luaL_checkint(L, 2); lua_pushboolean(L, is_linetouched(w, line)); return 1; } static int Wis_wintouched(lua_State *L) { WINDOW *w = checkwin(L, 1); lua_pushboolean(L, is_wintouched(w)); return 1; } /* ** ======================================================= ** getyx ** ======================================================= */ #define LCW_WIN2YX(v) \ static int W ## v(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ int y, x; \ v(w, y, x); \ lua_pushinteger(L, y); \ lua_pushinteger(L, x); \ return 2; \ } LCW_WIN2YX(getyx) LCW_WIN2YX(getparyx) LCW_WIN2YX(getbegyx) LCW_WIN2YX(getmaxyx) /* ** ======================================================= ** border ** ======================================================= */ static int Wborder(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ls = optch(L, 2, 0); chtype rs = optch(L, 3, 0); chtype ts = optch(L, 4, 0); chtype bs = optch(L, 5, 0); chtype tl = optch(L, 6, 0); chtype tr = optch(L, 7, 0); chtype bl = optch(L, 8, 0); chtype br = optch(L, 9, 0); lua_pushinteger(L, B(wborder(w, ls, rs, ts, bs, tl, tr, bl, br))); return 1; } static int Wbox(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype verch = checkch(L, 2); chtype horch = checkch(L, 3); lua_pushinteger(L, B(box(w, verch, horch))); return 1; } static int Whline(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); int n = luaL_checkint(L, 3); lua_pushboolean(L, B(whline(w, ch, n))); return 1; } static int Wvline(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); int n = luaL_checkint(L, 3); lua_pushboolean(L, B(wvline(w, ch, n))); return 1; } static int Wmvhline(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = checkch(L, 4); int n = luaL_checkint(L, 5); lua_pushboolean(L, B(mvwhline(w, y, x, ch, n))); return 1; } static int Wmvvline(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = checkch(L, 4); int n = luaL_checkint(L, 5); lua_pushboolean(L, B(mvwvline(w, y, x, ch, n))); return 1; } /* ** ======================================================= ** clear ** ======================================================= */ LCW_BOOLOK2(Werase, werase) LCW_BOOLOK2(Wclear, wclear) LCW_BOOLOK2(Wclrtobot, wclrtobot) LCW_BOOLOK2(Wclrtoeol, wclrtoeol) /* ** ======================================================= ** slk ** ======================================================= */ static int Cslk_init(lua_State *L) { int fmt = luaL_checkint(L, 1); lua_pushboolean(L, B(slk_init(fmt))); return 1; } static int Cslk_set(lua_State *L) { int labnum = luaL_checkint(L, 1); const char* label = luaL_checkstring(L, 2); int fmt = luaL_checkint(L, 3); lua_pushboolean(L, B(slk_set(labnum, label, fmt))); return 1; } LC_BOOLOK(slk_refresh) LC_BOOLOK(slk_noutrefresh) static int Cslk_label(lua_State *L) { int labnum = luaL_checkint(L, 1); lua_pushstring(L, slk_label(labnum)); return 1; } LC_BOOLOK(slk_clear) LC_BOOLOK(slk_restore) LC_BOOLOK(slk_touch) #define LC_ATTROK(v) \ static int C ## v(lua_State *L) \ { \ chtype attrs = checkch(L, 1); \ lua_pushboolean(L, B(v(attrs))); \ return 1; \ } LC_ATTROK(slk_attron) LC_ATTROK(slk_attroff) LC_ATTROK(slk_attrset) /* ** ======================================================= ** addch ** ======================================================= */ static int Waddch(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); lua_pushboolean(L, B(waddch(w, ch))); return 1; } static int Wmvaddch(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = checkch(L, 4); lua_pushboolean(L, B(mvwaddch(w, y, x, ch))); return 1; } static int Wechoch(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); lua_pushboolean(L, B(wechochar(w, ch))); return 1; } /* ** ======================================================= ** addchstr ** ======================================================= */ static int Waddchstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_optint(L, 3, -1); chstr *cs = checkchstr(L, 2); if (n < 0 || n > (int) cs->len) n = cs->len; lua_pushboolean(L, B(waddchnstr(w, cs->str, n))); return 1; } static int Wmvaddchstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int n = luaL_optint(L, 5, -1); chstr *cs = checkchstr(L, 4); if (n < 0 || n > (int) cs->len) n = cs->len; lua_pushboolean(L, B(mvwaddchnstr(w, y, x, cs->str, n))); return 1; } /* ** ======================================================= ** addstr ** ======================================================= */ static int Waddstr(lua_State *L) { WINDOW *w = checkwin(L, 1); const char *str = luaL_checkstring(L, 2); int n = luaL_optint(L, 3, -1); lua_pushboolean(L, B(waddnstr(w, str, n))); return 1; } static int Wmvaddstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); const char *str = luaL_checkstring(L, 4); int n = luaL_optint(L, 5, -1); lua_pushboolean(L, B(mvwaddnstr(w, y, x, str, n))); return 1; } /* ** ======================================================= ** bkgd ** ======================================================= */ static int Wwbkgdset(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); wbkgdset(w, ch); return 0; } static int Wwbkgd(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); lua_pushboolean(L, B(wbkgd(w, ch))); return 1; } static int Wgetbkgd(lua_State *L) { WINDOW *w = checkwin(L, 1); lua_pushboolean(L, B(getbkgd(w))); return 1; } /* ** ======================================================= ** inopts ** ======================================================= */ #define LC_TOGGLEOK(v) \ static int C ## v(lua_State *L) \ { \ if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1))\ lua_pushboolean(L, B(v())); \ else \ lua_pushboolean(L, B(no ## v())); \ return 1; \ } LC_TOGGLEOK(cbreak) LC_TOGGLEOK(echo) LC_TOGGLEOK(raw) static int Chalfdelay(lua_State *L) { int tenths = luaL_checkint(L, 1); lua_pushboolean(L, B(halfdelay(tenths))); return 1; } #define LCW_WINBOOLOK(v) \ static int W ## v(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ int bf = lua_toboolean(L, 2); \ lua_pushboolean(L, B(v(w, bf))); \ return 1; \ } LCW_WINBOOLOK(intrflush) static int Wkeypad(lua_State *L) { WINDOW *w = checkwin(L, 1); int bf = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); lua_pushboolean(L, B(keypad(w, bf))); return 1; } LCW_WINBOOLOK(meta) LCW_WINBOOLOK(nodelay) static int Wtimeout(lua_State *L) { WINDOW *w = checkwin(L, 1); int delay = luaL_checkint(L, 2); wtimeout(w, delay); return 0; } static int Wnotimeout(lua_State *L) { WINDOW *w = checkwin(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(notimeout(w, bf))); return 1; } /* ** ======================================================= ** outopts ** ======================================================= */ LC_TOGGLEOK(nl) LCW_WINBOOLOK(clearok) LCW_WINBOOLOK(idlok) LCW_WINBOOLOK(leaveok) LCW_WINBOOLOK(scrollok) static int Widcok(lua_State *L) { WINDOW *w = checkwin(L, 1); int bf = lua_toboolean(L, 2); idcok(w, bf); return 0; } static int Wimmedok(lua_State *L) { WINDOW *w = checkwin(L, 1); int bf = lua_toboolean(L, 2); immedok(w, bf); return 0; } static int Wwsetscrreg(lua_State *L) { WINDOW *w = checkwin(L, 1); int top = luaL_checkint(L, 2); int bot = luaL_checkint(L, 3); lua_pushboolean(L, B(wsetscrreg(w, top, bot))); return 1; } /* ** ======================================================= ** overlay ** ======================================================= */ static int Woverlay(lua_State *L) { WINDOW *srcwin = checkwin(L, 1); WINDOW *dstwin = checkwin(L, 2); lua_pushboolean(L, B(overlay(srcwin, dstwin))); return 1; } static int Woverwrite(lua_State *L) { WINDOW *srcwin = checkwin(L, 1); WINDOW *dstwin = checkwin(L, 2); lua_pushboolean(L, B(overwrite(srcwin, dstwin))); return 1; } static int Wcopywin(lua_State *L) { WINDOW *srcwin = checkwin(L, 1); WINDOW *dstwin = checkwin(L, 2); int sminrow = luaL_checkint(L, 3); int smincol = luaL_checkint(L, 4); int dminrow = luaL_checkint(L, 5); int dmincol = luaL_checkint(L, 6); int dmaxrow = luaL_checkint(L, 7); int dmaxcol = luaL_checkint(L, 8); int woverlay = lua_toboolean(L, 9); lua_pushboolean(L, B(copywin(srcwin, dstwin, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, woverlay))); return 1; } /* ** ======================================================= ** util ** ======================================================= */ static int Cunctrl(lua_State *L) { chtype c = luaL_checknumber(L, 1); lua_pushstring(L, unctrl(c)); return 1; } static int Ckeyname(lua_State *L) { int c = luaL_checkint(L, 1); lua_pushstring(L, keyname(c)); return 1; } static int Cdelay_output(lua_State *L) { int ms = luaL_checkint(L, 1); lua_pushboolean(L, B(delay_output(ms))); return 1; } LC_BOOL(flushinp) /* ** ======================================================= ** delch ** ======================================================= */ LCW_BOOLOK2(Wdelch, wdelch) static int Wmvdelch(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); lua_pushboolean(L, B(mvwdelch(w, y, x))); return 1; } /* ** ======================================================= ** deleteln ** ======================================================= */ LCW_BOOLOK2(Wdeleteln, wdeleteln) LCW_BOOLOK2(Winsertln, winsertln) static int Wwinsdelln(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_checkint(L, 2); lua_pushboolean(L, B(winsdelln(w, n))); return 1; } /* ** ======================================================= ** getch ** ======================================================= */ static int Wgetch(lua_State *L) { WINDOW *w = checkwin(L, 1); int c = wgetch(w); if (c == ERR) return 0; lua_pushinteger(L, c); return 1; } static int Wmvgetch(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int c; if (wmove(w, y, x) == ERR) return 0; c = wgetch(w); if (c == ERR) return 0; lua_pushinteger(L, c); return 1; } static int Cungetch(lua_State *L) { int c = luaL_checkint(L, 1); lua_pushboolean(L, B(ungetch(c))); return 1; } /* ** ======================================================= ** getstr ** ======================================================= */ static int Wgetstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_optint(L, 2, 0); char buf[LUAL_BUFFERSIZE]; if (n == 0 || n >= LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE - 1; if (wgetnstr(w, buf, n) == ERR) return 0; lua_pushstring(L, buf); return 1; } static int Wmvgetstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int n = luaL_optint(L, 4, -1); char buf[LUAL_BUFFERSIZE]; if (n == 0 || n >= LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE - 1; if (mvwgetnstr(w, y, x, buf, n) == ERR) return 0; lua_pushstring(L, buf); return 1; } /* ** ======================================================= ** inch ** ======================================================= */ static int Wwinch(lua_State *L) { WINDOW *w = checkwin(L, 1); lua_pushinteger(L, winch(w)); return 1; } static int Wmvwinch(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); lua_pushinteger(L, mvwinch(w, y, x)); return 1; } /* ** ======================================================= ** inchstr ** ======================================================= */ static int Wwinchnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_checkint(L, 2); chstr *cs = chstr_new(L, n); if (winchnstr(w, cs->str, n) == ERR) return 0; return 1; } static int Wmvwinchnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int n = luaL_checkint(L, 4); chstr *cs = chstr_new(L, n); if (mvwinchnstr(w, y, x, cs->str, n) == ERR) return 0; return 1; } /* ** ======================================================= ** instr ** ======================================================= */ static int Wwinnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int n = luaL_checkint(L, 2); char buf[LUAL_BUFFERSIZE]; if (n >= LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE - 1; if (winnstr(w, buf, n) == ERR) return 0; lua_pushlstring(L, buf, n); return 1; } static int Wmvwinnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int n = luaL_checkint(L, 4); char buf[LUAL_BUFFERSIZE]; if (n >= LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE - 1; if (mvwinnstr(w, y, x, buf, n) == ERR) return 0; lua_pushlstring(L, buf, n); return 1; } /* ** ======================================================= ** insch ** ======================================================= */ static int Wwinsch(lua_State *L) { WINDOW *w = checkwin(L, 1); chtype ch = checkch(L, 2); lua_pushboolean(L, B(winsch(w, ch))); return 1; } static int Wmvwinsch(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = checkch(L, 4); lua_pushboolean(L, B(mvwinsch(w, y, x, ch))); return 1; } /* ** ======================================================= ** insstr ** ======================================================= */ static int Wwinsstr(lua_State *L) { WINDOW *w = checkwin(L, 1); const char *str = luaL_checkstring(L, 2); lua_pushboolean(L, B(winsnstr(w, str, lua_strlen(L, 2)))); return 1; } static int Wmvwinsstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); const char *str = luaL_checkstring(L, 4); lua_pushboolean(L, B(mvwinsnstr(w, y, x, str, lua_strlen(L, 2)))); return 1; } static int Wwinsnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); const char *str = luaL_checkstring(L, 2); int n = luaL_checkint(L, 3); lua_pushboolean(L, B(winsnstr(w, str, n))); return 1; } static int Wmvwinsnstr(lua_State *L) { WINDOW *w = checkwin(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); const char *str = luaL_checkstring(L, 4); int n = luaL_checkint(L, 5); lua_pushboolean(L, B(mvwinsnstr(w, y, x, str, n))); return 1; } /* ** ======================================================= ** pad ** ======================================================= */ static int Cnewpad(lua_State *L) { int nlines = luaL_checkint(L, 1); int ncols = luaL_checkint(L, 2); lc_newwin(L, newpad(nlines, ncols)); return 1; } static int Wsubpad(lua_State *L) { WINDOW *orig = checkwin(L, 1); int nlines = luaL_checkint(L, 2); int ncols = luaL_checkint(L, 3); int begin_y = luaL_checkint(L, 4); int begin_x = luaL_checkint(L, 5); lc_newwin(L, subpad(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int Wprefresh(lua_State *L) { WINDOW *p = checkwin(L, 1); int pminrow = luaL_checkint(L, 2); int pmincol = luaL_checkint(L, 3); int sminrow = luaL_checkint(L, 4); int smincol = luaL_checkint(L, 5); int smaxrow = luaL_checkint(L, 6); int smaxcol = luaL_checkint(L, 7); lua_pushboolean(L, B(prefresh(p, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol))); return 1; } static int Wpnoutrefresh(lua_State *L) { WINDOW *p = checkwin(L, 1); int pminrow = luaL_checkint(L, 2); int pmincol = luaL_checkint(L, 3); int sminrow = luaL_checkint(L, 4); int smincol = luaL_checkint(L, 5); int smaxrow = luaL_checkint(L, 6); int smaxcol = luaL_checkint(L, 7); lua_pushboolean(L, B(pnoutrefresh(p, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol))); return 1; } static int Wpechochar(lua_State *L) { WINDOW *p = checkwin(L, 1); chtype ch = checkch(L, 2); lua_pushboolean(L, B(pechochar(p, ch))); return 1; } /* ** ======================================================= ** attr ** ======================================================= */ #define LCW_WININTOK(v) \ static int W ## v(lua_State *L) \ { \ WINDOW *w = checkwin(L, 1); \ int bf = luaL_checkint(L, 2); \ lua_pushboolean(L, B(w ## v(w, bf))); \ return 1; \ } LCW_WININTOK(attroff) LCW_WININTOK(attron) LCW_WININTOK(attrset) LCW_BOOLOK2(Wstandend, wstandend) LCW_BOOLOK2(Wstandout, wstandout) /* ** ======================================================= ** query terminfo database ** ======================================================= */ static char ti_capname[32]; static int Ctigetflag (lua_State *L) { int res; strlcpy (ti_capname, luaL_checkstring (L, 1), sizeof (ti_capname)); res = tigetflag (ti_capname); if (-1 == res) return luaL_error (L, "`%s' is not a boolean capability", ti_capname); else lua_pushboolean (L, res); return 1; } static int Ctigetnum (lua_State *L) { int res; strlcpy (ti_capname, luaL_checkstring (L, 1), sizeof (ti_capname)); res = tigetnum (ti_capname); if (-2 == res) return luaL_error (L, "`%s' is not a numeric capability", ti_capname); else if (-1 == res) lua_pushnil (L); else lua_pushinteger(L, res); return 1; } static int Ctigetstr (lua_State *L) { const char *res; strlcpy (ti_capname, luaL_checkstring (L, 1), sizeof (ti_capname)); res = tigetstr (ti_capname); if ((char *) -1 == res) return luaL_error (L, "`%s' is not a string capability", ti_capname); else if (NULL == res) lua_pushnil (L); else lua_pushstring(L, res); return 1; } /* ** ======================================================= ** register functions ** ======================================================= */ /* chstr members */ static const luaL_Reg chstrlib[] = { #define MENTRY(_f) { LCURSES_STR(_f), LCURSES_SPLICE(chstr_, _f) } MENTRY( len ), MENTRY( set_ch ), MENTRY( set_str ), MENTRY( get ), MENTRY( dup ), #undef MENTRY { NULL, NULL } }; static const luaL_Reg windowlib[] = { #define MENTRY(_f) { LCURSES_STR_1(_f), (_f) } /* window */ MENTRY( Wclose ), MENTRY( Wsub ), MENTRY( Wderive ), MENTRY( Wmove_window ), MENTRY( Wmove_derived ), MENTRY( Wresize ), MENTRY( Wclone ), MENTRY( Wsyncup ), MENTRY( Wsyncdown ), MENTRY( Wsyncok ), MENTRY( Wcursyncup ), /* inopts */ MENTRY( Wintrflush ), MENTRY( Wkeypad ), MENTRY( Wmeta ), MENTRY( Wnodelay ), MENTRY( Wtimeout ), MENTRY( Wnotimeout ), /* outopts */ MENTRY( Wclearok ), MENTRY( Widlok ), MENTRY( Wleaveok ), MENTRY( Wscrollok ), MENTRY( Widcok ), MENTRY( Wimmedok ), MENTRY( Wwsetscrreg ), /* pad */ MENTRY( Wsubpad ), MENTRY( Wprefresh ), MENTRY( Wpnoutrefresh ), MENTRY( Wpechochar ), /* move */ MENTRY( Wmove ), /* scroll */ MENTRY( Wscrl ), /* refresh */ MENTRY( Wrefresh ), MENTRY( Wnoutrefresh ), MENTRY( Wredrawwin ), MENTRY( Wredrawln ), /* clear */ MENTRY( Werase ), MENTRY( Wclear ), MENTRY( Wclrtobot ), MENTRY( Wclrtoeol ), /* touch */ MENTRY( Wtouch ), MENTRY( Wtouchline ), MENTRY( Wis_linetouched ), MENTRY( Wis_wintouched ), /* attrs */ MENTRY( Wattroff ), MENTRY( Wattron ), MENTRY( Wattrset ), MENTRY( Wstandout ), MENTRY( Wstandend ), /* getch */ MENTRY( Wgetch ), MENTRY( Wmvgetch ), /* getyx */ MENTRY( Wgetyx ), MENTRY( Wgetparyx ), MENTRY( Wgetbegyx ), MENTRY( Wgetmaxyx ), /* border */ MENTRY( Wborder ), MENTRY( Wbox ), MENTRY( Whline ), MENTRY( Wvline ), MENTRY( Wmvhline ), MENTRY( Wmvvline ), /* addch */ MENTRY( Waddch ), MENTRY( Wmvaddch ), MENTRY( Wechoch ), /* addchstr */ MENTRY( Waddchstr ), MENTRY( Wmvaddchstr ), /* addstr */ MENTRY( Waddstr ), MENTRY( Wmvaddstr ), /* bkgd */ MENTRY( Wwbkgdset ), MENTRY( Wwbkgd ), MENTRY( Wgetbkgd ), /* overlay */ MENTRY( Woverlay ), MENTRY( Woverwrite ), MENTRY( Wcopywin ), /* delch */ MENTRY( Wdelch ), MENTRY( Wmvdelch ), /* deleteln */ MENTRY( Wdeleteln ), MENTRY( Winsertln ), MENTRY( Wwinsdelln ), /* getstr */ MENTRY( Wgetstr ), MENTRY( Wmvgetstr ), /* inch */ MENTRY( Wwinch ), MENTRY( Wmvwinch ), MENTRY( Wwinchnstr ), MENTRY( Wmvwinchnstr ), /* instr */ MENTRY( Wwinnstr ), MENTRY( Wmvwinnstr ), /* insch */ MENTRY( Wwinsch ), MENTRY( Wmvwinsch ), /* insstr */ MENTRY( Wwinsstr ), MENTRY( Wwinsnstr ), MENTRY( Wmvwinsstr ), MENTRY( Wmvwinsnstr ), /* misc */ MENTRY( W__tostring ), #undef MENTRY {"__gc", Wclose }, /* rough safety net */ {NULL, NULL} }; static const luaL_Reg curseslib[] = { #define MENTRY(_f) { LCURSES_STR_1(_f), (_f) } /* chstr helper function */ MENTRY( Cnew_chstr ), /* initscr */ MENTRY( Cendwin ), MENTRY( Cisendwin ), MENTRY( Cstdscr ), MENTRY( Ccols ), MENTRY( Clines ), /* color */ MENTRY( Cstart_color ), MENTRY( Chas_colors ), MENTRY( Cuse_default_colors ), MENTRY( Cinit_pair ), MENTRY( Cpair_content ), MENTRY( Ccolors ), MENTRY( Ccolor_pairs ), MENTRY( Ccolor_pair ), /* termattrs */ MENTRY( Cbaudrate ), MENTRY( Cerasechar ), MENTRY( Ckillchar ), MENTRY( Chas_ic ), MENTRY( Chas_il ), MENTRY( Ctermattrs ), MENTRY( Ctermname ), MENTRY( Clongname ), /* kernel */ MENTRY( Cripoffline ), MENTRY( Cnapms ), MENTRY( Ccurs_set ), /* resize */ MENTRY( Cresizeterm ), /* beep */ MENTRY( Cbeep ), MENTRY( Cflash ), /* window */ MENTRY( Cnewwin ), /* pad */ MENTRY( Cnewpad ), /* refresh */ MENTRY( Cdoupdate ), /* inopts */ MENTRY( Ccbreak ), MENTRY( Cecho ), MENTRY( Craw ), MENTRY( Chalfdelay ), /* util */ MENTRY( Cunctrl ), MENTRY( Ckeyname ), MENTRY( Cdelay_output ), MENTRY( Cflushinp ), /* getch */ MENTRY( Cungetch ), /* outopts */ MENTRY( Cnl ), /* query terminfo database */ MENTRY( Ctigetflag ), MENTRY( Ctigetnum ), MENTRY( Ctigetstr ), /* slk */ MENTRY( Cslk_init ), MENTRY( Cslk_set ), MENTRY( Cslk_refresh ), MENTRY( Cslk_noutrefresh ), MENTRY( Cslk_label ), MENTRY( Cslk_clear ), MENTRY( Cslk_restore ), MENTRY( Cslk_touch ), MENTRY( Cslk_attron ), MENTRY( Cslk_attroff ), MENTRY( Cslk_attrset ), #undef MENTRY /* terminator */ {NULL, NULL} }; /* Prototype to keep compiler happy. */ LUALIB_API int luaopen_curses_c (lua_State *L); int luaopen_curses_c (lua_State *L) { /* ** create new metatable for window objects */ luaL_newmetatable(L, WINDOWMETA); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); /* push metatable */ lua_rawset(L, -3); /* metatable.__index = metatable */ luaL_openlib(L, NULL, windowlib, 0); lua_pop(L, 1); /* remove metatable from stack */ /* ** create new metatable for chstr objects */ luaL_newmetatable(L, CHSTRMETA); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); /* push metatable */ lua_rawset(L, -3); /* metatable.__index = metatable */ luaL_openlib(L, NULL, chstrlib, 0); lua_pop(L, 1); /* remove metatable from stack */ /* ** create global table with curses methods/variables/constants */ luaL_register(L, "curses", curseslib); lua_pushstring(L, "initscr"); lua_pushvalue(L, -2); lua_pushcclosure(L, Cinitscr, 1); lua_settable(L, -3); return 1; } /* Local Variables: */ /* c-basic-offset: 4 */ /* End: */