/************************************************************************* * Library: lcurses - Lua 5.1 interface to the curses library * * * * (c) Reuben Thomas <rrt@sc3d.org> 2009-2010 * * (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> #ifdef HAVE_NCURSES_H #include <ncurses.h> #else #include <curses.h> #endif #include <term.h> /* 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)) == ERR)) /* ======================================================= */ #define LC_NUMBER(v) \ static int lc_ ## v(lua_State *L) \ { \ lua_pushnumber(L, v()); \ return 1; \ } #define LC_NUMBER2(n,v) \ static int lc_ ## n(lua_State *L) \ { \ lua_pushnumber(L, v); \ return 1; \ } /* ======================================================= */ #define LC_STRING(v) \ static int lc_ ## v(lua_State *L) \ { \ lua_pushstring(L, v()); \ return 1; \ } #define LC_STRING2(n,v) \ static int lc_ ## n(lua_State *L) \ { \ lua_pushstring(L, v); \ return 1; \ } /* ======================================================= */ #define LC_BOOL(v) \ static int lc_ ## v(lua_State *L) \ { \ lua_pushboolean(L, v()); \ return 1; \ } #define LC_BOOL2(n,v) \ static int lc_ ## n(lua_State *L) \ { \ lua_pushboolean(L, v); \ return 1; \ } /* ======================================================= */ #define LC_BOOLOK(v) \ static int lc_ ## v(lua_State *L) \ { \ lua_pushboolean(L, B(v())); \ return 1; \ } #define LC_BOOLOK2(n,v) \ static int lc_ ## n(lua_State *L) \ { \ lua_pushboolean(L, B(v)); \ return 1; \ } /* ======================================================= */ #define LCW_BOOLOK(n) \ static int lcw_ ## n(lua_State *L) \ { \ WINDOW *w = lcw_check(L, 1); \ lua_pushboolean(L, B(n(w))); \ return 1; \ } /* ** ======================================================= ** privates ** ======================================================= */ static void lcw_new(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 **lcw_get(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 *lcw_check(lua_State *L, int offset) { WINDOW **w = lcw_get(L, offset); if (*w == NULL) luaL_argerror(L, offset, "attempt to use closed curses window"); return *w; } static int lcw_tostring(lua_State *L) { WINDOW **w = lcw_get(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 lc_checkch(lua_State *L, int offset) { if (lua_type(L, offset) == LUA_TNUMBER) return (chtype)luaL_checknumber(L, offset); if (lua_type(L, offset) == LUA_TSTRING) return *lua_tostring(L, offset); luaL_typerror(L, offset, "chtype"); /* never executes */ return (chtype)0; } static chtype lc_optch(lua_State *L, int offset, chtype def) { if (lua_isnoneornil(L, offset)) return def; return lc_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* lc_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 lc_new_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 = lc_checkchstr(L, 1); int offset = luaL_checkint(L, 2); const char *str = luaL_checkstring(L, 3); int len = lua_strlen(L, 3); int attr = (chtype)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 = lc_checkchstr(L, 1); int offset = luaL_checkint(L, 2); chtype ch = lc_checkch(L, 3); int attr = (chtype)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 = lc_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_pushnumber(L, ch & A_CHARTEXT); lua_pushnumber(L, ch & A_ATTRIBUTES); lua_pushnumber(L, ch & A_COLOR); return 3; } /* retrieve chstr length */ static int chstr_len(lua_State *L) { chstr *cs = lc_checkchstr(L, 1); lua_pushnumber(L, cs->len); return 1; } /* duplicate chstr */ static int chstr_dup(lua_State *L) { chstr *cs = lc_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_pushnumber(L, v); \ lua_settable(L, lua_upvalueindex(1)); #define CC(s) CCR(#s, s) #define CC2(s, v) CCR(#s, v) /* ** these values may be fixed only after initialization, so this is ** called from lc_initscr, 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) CC2(KEY_F1, KEY_F(1)) CC2(KEY_F2, KEY_F(2)) CC2(KEY_F3, KEY_F(3)) CC2(KEY_F4, KEY_F(4)) CC2(KEY_F5, KEY_F(5)) CC2(KEY_F6, KEY_F(6)) CC2(KEY_F7, KEY_F(7)) CC2(KEY_F8, KEY_F(8)) CC2(KEY_F9, KEY_F(9)) CC2(KEY_F10, KEY_F(10)) CC2(KEY_F11, KEY_F(11)) CC2(KEY_F12, KEY_F(12)) } /* ** 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 lc_initscr(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 */ lcw_new(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 lc_endwin(lua_State *L) { (void) L; endwin(); return 0; } LC_BOOL(isendwin) static int lc_stdscr(lua_State *L) { lua_pushstring(L, STDSCR_REGISTRY); lua_rawget(L, LUA_REGISTRYINDEX); return 1; } LC_NUMBER2(COLS, COLS) LC_NUMBER2(LINES, LINES) /* ** ======================================================= ** color ** ======================================================= */ LC_BOOLOK(start_color) LC_BOOL(has_colors) static int lc_init_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 lc_pair_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_pushnumber(L, f); lua_pushnumber(L, b); return 2; } LC_NUMBER2(COLORS, COLORS) LC_NUMBER2(COLOR_PAIRS, COLOR_PAIRS) static int lc_COLOR_PAIR(lua_State *L) { int n = luaL_checkint(L, 1); lua_pushnumber(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 lc_termattrs(lua_State *L) { if (lua_gettop(L) < 1) { lua_pushnumber(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 */ lcw_new(rip_L, w); /* create window object */ lua_pushnumber(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 lc_ripoffline(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 lc_curs_set(lua_State *L) { int vis = luaL_checkint(L, 1); int state = curs_set(vis); if (state == ERR) return 0; lua_pushnumber(L, state); return 1; } static int lc_napms(lua_State *L) { int ms = luaL_checkint(L, 1); lua_pushboolean(L, B(napms(ms))); return 1; } /* ** ======================================================= ** beep ** ======================================================= */ LC_BOOLOK(beep) LC_BOOLOK(flash) /* ** ======================================================= ** window ** ======================================================= */ static int lc_newwin(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); lcw_new(L, newwin(nlines, ncols, begin_y, begin_x)); return 1; } static int lcw_delwin(lua_State *L) { WINDOW **w = lcw_get(L, 1); if (*w != NULL && *w != stdscr) { delwin(*w); *w = NULL; } return 0; } static int lcw_mvwin(lua_State *L) { WINDOW *w = lcw_check(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 lcw_subwin(lua_State *L) { WINDOW *orig = lcw_check(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); lcw_new(L, subwin(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int lcw_derwin(lua_State *L) { WINDOW *orig = lcw_check(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); lcw_new(L, derwin(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int lcw_mvderwin(lua_State *L) { WINDOW *w = lcw_check(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 lcw_dupwin(lua_State *L) { WINDOW *w = lcw_check(L, 1); lcw_new(L, dupwin(w)); return 1; } static int lcw_wsyncup(lua_State *L) { WINDOW *w = lcw_check(L, 1); wsyncup(w); return 0; } static int lcw_syncok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(syncok(w, bf))); return 1; } static int lcw_wcursyncup(lua_State *L) { WINDOW *w = lcw_check(L, 1); wcursyncup(w); return 0; } static int lcw_wsyncdown(lua_State *L) { WINDOW *w = lcw_check(L, 1); wsyncdown(w); return 0; } /* ** ======================================================= ** refresh ** ======================================================= */ LCW_BOOLOK(wrefresh) LCW_BOOLOK(wnoutrefresh) LCW_BOOLOK(redrawwin) static int lcw_wredrawln(lua_State *L) { WINDOW *w = lcw_check(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 lcw_wmove(lua_State *L) { WINDOW *w = lcw_check(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 lcw_wscrl(lua_State *L) { WINDOW *w = lcw_check(L, 1); int n = luaL_checkint(L, 2); lua_pushboolean(L, B(wscrl(w, n))); return 1; } /* ** ======================================================= ** touch ** ======================================================= */ static int lcw_touch(lua_State *L) { WINDOW *w = lcw_check(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 lcw_touchline(lua_State *L) { WINDOW *w = lcw_check(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 lcw_is_linetouched(lua_State *L) { WINDOW *w = lcw_check(L, 1); int line = luaL_checkint(L, 2); lua_pushboolean(L, is_linetouched(w, line)); return 1; } static int lcw_is_wintouched(lua_State *L) { WINDOW *w = lcw_check(L, 1); lua_pushboolean(L, is_wintouched(w)); return 1; } /* ** ======================================================= ** getyx ** ======================================================= */ static int lcw_getyx(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y, x; getyx(w, y, x); lua_pushnumber(L, y); lua_pushnumber(L, x); return 2; } static int lcw_getparyx(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y, x; getparyx(w, y, x); lua_pushnumber(L, y); lua_pushnumber(L, x); return 2; } static int lcw_getbegyx(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y, x; getbegyx(w, y, x); lua_pushnumber(L, y); lua_pushnumber(L, x); return 2; } static int lcw_getmaxyx(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y, x; getmaxyx(w, y, x); lua_pushnumber(L, y); lua_pushnumber(L, x); return 2; } /* ** ======================================================= ** border ** ======================================================= */ static int lcw_wborder(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ls = lc_optch(L, 2, 0); chtype rs = lc_optch(L, 3, 0); chtype ts = lc_optch(L, 4, 0); chtype bs = lc_optch(L, 5, 0); chtype tl = lc_optch(L, 6, 0); chtype tr = lc_optch(L, 7, 0); chtype bl = lc_optch(L, 8, 0); chtype br = lc_optch(L, 9, 0); lua_pushnumber(L, B(wborder(w, ls, rs, ts, bs, tl, tr, bl, br))); return 1; } static int lcw_box(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype verch = lc_checkch(L, 2); chtype horch = lc_checkch(L, 3); lua_pushnumber(L, B(box(w, verch, horch))); return 1; } static int lcw_whline(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); int n = luaL_checkint(L, 3); lua_pushnumber(L, B(whline(w, ch, n))); return 1; } static int lcw_wvline(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); int n = luaL_checkint(L, 3); lua_pushnumber(L, B(wvline(w, ch, n))); return 1; } static int lcw_mvwhline(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = lc_checkch(L, 4); int n = luaL_checkint(L, 5); lua_pushnumber(L, B(mvwhline(w, y, x, ch, n))); return 1; } static int lcw_mvwvline(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = lc_checkch(L, 4); int n = luaL_checkint(L, 5); lua_pushnumber(L, B(mvwvline(w, y, x, ch, n))); return 1; } /* ** ======================================================= ** clear ** ======================================================= */ LCW_BOOLOK(werase) LCW_BOOLOK(wclear) LCW_BOOLOK(wclrtobot) LCW_BOOLOK(wclrtoeol) /* ** ======================================================= ** slk ** ======================================================= */ static int lc_slk_init(lua_State *L) { int fmt = luaL_checkint(L, 1); lua_pushboolean(L, B(slk_init(fmt))); return 1; } static int lc_slk_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 lc_slk_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) static int lc_slk_attron(lua_State *L) { chtype attrs = lc_checkch(L, 1); lua_pushboolean(L, B(slk_attron(attrs))); return 1; } static int lc_slk_attroff(lua_State *L) { chtype attrs = lc_checkch(L, 1); lua_pushboolean(L, B(slk_attroff(attrs))); return 1; } static int lc_slk_attrset(lua_State *L) { chtype attrs = lc_checkch(L, 1); lua_pushboolean(L, B(slk_attrset(attrs))); return 1; } /* ** ======================================================= ** addch ** ======================================================= */ static int lcw_waddch(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); lua_pushboolean(L, B(waddch(w, ch))); return 1; } static int lcw_mvwaddch(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = lc_checkch(L, 4); lua_pushboolean(L, B(mvwaddch(w, y, x, ch))); return 1; } static int lcw_wechochar(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); lua_pushboolean(L, B(wechochar(w, ch))); return 1; } /* ** ======================================================= ** addchstr ** ======================================================= */ static int lcw_waddchnstr(lua_State *L) { WINDOW *w = lcw_check(L, 1); int n = luaL_optint(L, 3, -1); chstr *cs = lc_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 lcw_mvwaddchnstr(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); int n = luaL_optint(L, 5, -1); chstr *cs = lc_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 lcw_waddnstr(lua_State *L) { WINDOW *w = lcw_check(L, 1); const char *str = luaL_checkstring(L, 2); int n = luaL_optint(L, 3, -1); if (n < 0) n = lua_strlen(L, 2); lua_pushboolean(L, B(waddnstr(w, str, n))); return 1; } static int lcw_mvwaddnstr(lua_State *L) { WINDOW *w = lcw_check(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); if (n < 0) n = lua_strlen(L, 4); lua_pushboolean(L, B(mvwaddnstr(w, y, x, str, n))); return 1; } /* ** ======================================================= ** bkgd ** ======================================================= */ static int lcw_wbkgdset(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); wbkgdset(w, ch); return 0; } static int lcw_wbkgd(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); lua_pushboolean(L, B(wbkgd(w, ch))); return 1; } static int lcw_getbkgd(lua_State *L) { WINDOW *w = lcw_check(L, 1); lua_pushnumber(L, B(getbkgd(w))); return 1; } /* ** ======================================================= ** inopts ** ======================================================= */ static int lc_cbreak(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) lua_pushboolean(L, B(cbreak())); else lua_pushboolean(L, B(nocbreak())); return 1; } static int lc_echo(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) lua_pushboolean(L, B(echo())); else lua_pushboolean(L, B(noecho())); return 1; } static int lc_raw(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) lua_pushboolean(L, B(raw())); else lua_pushboolean(L, B(noraw())); return 1; } static int lc_halfdelay(lua_State *L) { int tenths = luaL_checkint(L, 1); lua_pushboolean(L, B(halfdelay(tenths))); return 1; } static int lcw_intrflush(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(intrflush(w, bf))); return 1; } static int lcw_keypad(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); lua_pushboolean(L, B(keypad(w, bf))); return 1; } static int lcw_meta(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(meta(w, bf))); return 1; } static int lcw_nodelay(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(nodelay(w, bf))); return 1; } static int lcw_timeout(lua_State *L) { WINDOW *w = lcw_check(L, 1); int delay = luaL_checkint(L, 2); wtimeout(w, delay); return 0; } static int lcw_notimeout(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(notimeout(w, bf))); return 1; } /* ** ======================================================= ** outopts ** ======================================================= */ static int lc_nl(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) lua_pushboolean(L, B(nl())); else lua_pushboolean(L, B(nonl())); return 1; } static int lcw_clearok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(clearok(w, bf))); return 1; } static int lcw_idlok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(idlok(w, bf))); return 1; } static int lcw_leaveok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(leaveok(w, bf))); return 1; } static int lcw_scrollok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); lua_pushboolean(L, B(scrollok(w, bf))); return 1; } static int lcw_idcok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); idcok(w, bf); return 0; } static int lcw_immedok(lua_State *L) { WINDOW *w = lcw_check(L, 1); int bf = lua_toboolean(L, 2); immedok(w, bf); return 0; } static int lcw_wsetscrreg(lua_State *L) { WINDOW *w = lcw_check(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 lcw_overlay(lua_State *L) { WINDOW *srcwin = lcw_check(L, 1); WINDOW *dstwin = lcw_check(L, 2); lua_pushboolean(L, B(overlay(srcwin, dstwin))); return 1; } static int lcw_overwrite(lua_State *L) { WINDOW *srcwin = lcw_check(L, 1); WINDOW *dstwin = lcw_check(L, 2); lua_pushboolean(L, B(overwrite(srcwin, dstwin))); return 1; } static int lcw_copywin(lua_State *L) { WINDOW *srcwin = lcw_check(L, 1); WINDOW *dstwin = lcw_check(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 lc_unctrl(lua_State *L) { chtype c = (chtype)luaL_checknumber(L, 1); lua_pushstring(L, unctrl(c)); return 1; } static int lc_keyname(lua_State *L) { int c = luaL_checkint(L, 1); lua_pushstring(L, keyname(c)); return 1; } static int lc_delay_output(lua_State *L) { int ms = luaL_checkint(L, 1); lua_pushboolean(L, B(delay_output(ms))); return 1; } static int lc_flushinp(lua_State *L) { lua_pushboolean(L, B(flushinp())); return 1; } /* ** ======================================================= ** delch ** ======================================================= */ LCW_BOOLOK(wdelch) static int lcw_mvwdelch(lua_State *L) { WINDOW *w = lcw_check(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_BOOLOK(wdeleteln) LCW_BOOLOK(winsertln) static int lcw_winsdelln(lua_State *L) { WINDOW *w = lcw_check(L, 1); int n = luaL_checkint(L, 2); lua_pushboolean(L, B(winsdelln(w, n))); return 1; } /* ** ======================================================= ** getch ** ======================================================= */ static int lcw_wgetch(lua_State *L) { WINDOW *w = lcw_check(L, 1); int c = wgetch(w); if (c == ERR) return 0; lua_pushnumber(L, c); return 1; } static int lcw_mvwgetch(lua_State *L) { WINDOW *w = lcw_check(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_pushnumber(L, c); return 1; } static int lc_ungetch(lua_State *L) { int c = luaL_checkint(L, 1); lua_pushboolean(L, B(ungetch(c))); return 1; } /* ** ======================================================= ** getstr ** ======================================================= */ static int lcw_wgetnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_mvwgetnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_winch(lua_State *L) { WINDOW *w = lcw_check(L, 1); lua_pushnumber(L, winch(w)); return 1; } static int lcw_mvwinch(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); lua_pushnumber(L, mvwinch(w, y, x)); return 1; } /* ** ======================================================= ** inchstr ** ======================================================= */ static int lcw_winchnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_mvwinchnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_winnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_mvwinnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_winsch(lua_State *L) { WINDOW *w = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); lua_pushboolean(L, B(winsch(w, ch))); return 1; } static int lcw_mvwinsch(lua_State *L) { WINDOW *w = lcw_check(L, 1); int y = luaL_checkint(L, 2); int x = luaL_checkint(L, 3); chtype ch = lc_checkch(L, 4); lua_pushboolean(L, B(mvwinsch(w, y, x, ch))); return 1; } /* ** ======================================================= ** insstr ** ======================================================= */ static int lcw_winsstr(lua_State *L) { WINDOW *w = lcw_check(L, 1); const char *str = luaL_checkstring(L, 2); lua_pushboolean(L, B(winsnstr(w, str, lua_strlen(L, 2)))); return 1; } static int lcw_mvwinsstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_winsnstr(lua_State *L) { WINDOW *w = lcw_check(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 lcw_mvwinsnstr(lua_State *L) { WINDOW *w = lcw_check(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 lc_newpad(lua_State *L) { int nlines = luaL_checkint(L, 1); int ncols = luaL_checkint(L, 2); lcw_new(L, newpad(nlines, ncols)); return 1; } static int lcw_subpad(lua_State *L) { WINDOW *orig = lcw_check(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); lcw_new(L, subpad(orig, nlines, ncols, begin_y, begin_x)); return 1; } static int lcw_prefresh(lua_State *L) { WINDOW *p = lcw_check(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 lcw_pnoutrefresh(lua_State *L) { WINDOW *p = lcw_check(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 lcw_pechochar(lua_State *L) { WINDOW *p = lcw_check(L, 1); chtype ch = lc_checkch(L, 2); lua_pushboolean(L, B(pechochar(p, ch))); return 1; } /* ** ======================================================= ** attr ** ======================================================= */ static int lcw_wattroff(lua_State *L) { WINDOW *w = lcw_check(L, 1); int attrs = luaL_checkint(L, 2); lua_pushboolean(L, B(wattroff(w, attrs))); return 1; } static int lcw_wattron(lua_State *L) { WINDOW *w = lcw_check(L, 1); int attrs = luaL_checkint(L, 2); lua_pushboolean(L, B(wattron(w, attrs))); return 1; } static int lcw_wattrset(lua_State *L) { WINDOW *w = lcw_check(L, 1); int attrs = luaL_checkint(L, 2); lua_pushboolean(L, B(wattrset(w, attrs))); return 1; } LCW_BOOLOK(wstandend) LCW_BOOLOK(wstandout) /* ** ======================================================= ** query terminfo database ** ======================================================= */ static char ti_capname[32]; static int ti_getflag (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 ti_getnum (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_pushnumber(L, res); return 1; } static int ti_getstr (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[] = { { "len", chstr_len }, { "set_ch", chstr_set_ch }, { "set_str", chstr_set_str }, { "get", chstr_get }, { "dup", chstr_dup }, { NULL, NULL } }; #define EWF(name) { #name, lcw_ ## name }, static const luaL_reg windowlib[] = { /* window */ { "close", lcw_delwin }, { "sub", lcw_subwin }, { "derive", lcw_derwin }, { "move_window", lcw_mvwin }, { "move_derived", lcw_mvderwin }, { "clone", lcw_dupwin }, { "syncup", lcw_wsyncup }, { "syncdown", lcw_wsyncdown }, { "syncok", lcw_syncok }, { "cursyncup", lcw_wcursyncup }, /* inopts */ EWF(intrflush) EWF(keypad) EWF(meta) EWF(nodelay) EWF(timeout) EWF(notimeout) /* outopts */ EWF(clearok) EWF(idlok) EWF(leaveok) EWF(scrollok) EWF(idcok) EWF(immedok) EWF(wsetscrreg) /* pad */ EWF(subpad) EWF(prefresh) EWF(pnoutrefresh) EWF(pechochar) /* move */ { "move", lcw_wmove }, /* scroll */ { "scrl", lcw_wscrl }, /* refresh */ { "refresh", lcw_wrefresh }, { "noutrefresh", lcw_wnoutrefresh }, { "redrawwin", lcw_redrawwin }, { "redrawln", lcw_wredrawln }, /* clear */ { "erase", lcw_werase }, { "clear", lcw_wclear }, { "clrtobot", lcw_wclrtobot }, { "clrtoeol", lcw_wclrtoeol }, /* touch */ { "touch", lcw_touch }, { "touchline", lcw_touchline }, { "is_linetouched", lcw_is_linetouched }, { "is_wintouched", lcw_is_wintouched }, /* attrs */ { "attroff", lcw_wattroff }, { "attron", lcw_wattron }, { "attrset", lcw_wattrset }, { "standout", lcw_wstandout }, { "standend", lcw_wstandend }, /* getch */ { "getch", lcw_wgetch }, { "mvgetch", lcw_mvwgetch }, /* getyx */ EWF(getyx) EWF(getparyx) EWF(getbegyx) EWF(getmaxyx) /* border */ { "border", lcw_wborder }, { "box", lcw_box }, { "hline", lcw_whline }, { "vline", lcw_wvline }, { "mvhline", lcw_mvwhline }, { "mvvline", lcw_mvwvline }, /* addch */ { "addch", lcw_waddch }, { "mvaddch", lcw_mvwaddch }, { "echoch", lcw_wechochar }, /* addchstr */ { "addchstr", lcw_waddchnstr }, { "mvaddchstr", lcw_mvwaddchnstr }, /* addstr */ { "addstr", lcw_waddnstr }, { "mvaddstr", lcw_mvwaddnstr }, /* bkgd */ EWF(wbkgdset) EWF(wbkgd) EWF(getbkgd) /* overlay */ { "overlay", lcw_overlay }, { "overwrite", lcw_overwrite }, { "copywin", lcw_copywin }, /* delch */ { "delch", lcw_wdelch }, { "mvdelch", lcw_mvwdelch }, /* deleteln */ { "deleteln", lcw_wdeleteln }, { "insertln", lcw_winsertln }, EWF(winsdelln) /* getstr */ { "getstr", lcw_wgetnstr }, { "mvgetstr", lcw_mvwgetnstr }, /* inch */ EWF(winch) EWF(mvwinch) EWF(winchnstr) EWF(mvwinchnstr) /* instr */ EWF(winnstr) EWF(mvwinnstr) /* insch */ EWF(winsch) EWF(mvwinsch) /* insstr */ EWF(winsstr) EWF(winsnstr) EWF(mvwinsstr) EWF(mvwinsnstr) /* misc */ {"__gc", lcw_delwin }, /* rough safety net */ {"__tostring", lcw_tostring}, {NULL, NULL} }; #define ECF(name) { #name, lc_ ## name }, static const luaL_reg curseslib[] = { /* chstr helper function */ { "new_chstr", lc_new_chstr }, /* initscr */ { "endwin", lc_endwin }, { "isendwin", lc_isendwin }, { "stdscr", lc_stdscr }, { "cols", lc_COLS }, { "lines", lc_LINES }, /* color */ { "start_color", lc_start_color }, { "has_colors", lc_has_colors }, { "init_pair", lc_init_pair }, { "pair_content", lc_pair_content }, { "colors", lc_COLORS }, { "color_pairs", lc_COLOR_PAIRS }, { "color_pair", lc_COLOR_PAIR }, /* termattrs */ { "baudrate", lc_baudrate }, { "erasechar", lc_erasechar }, { "killchar", lc_killchar }, { "has_ic", lc_has_ic }, { "has_il", lc_has_il }, { "termattrs", lc_termattrs }, { "termname", lc_termname }, { "longname", lc_longname }, /* kernel */ { "ripoffline", lc_ripoffline }, { "napms", lc_napms }, { "curs_set", lc_curs_set }, /* beep */ { "beep", lc_beep }, { "flash", lc_flash }, /* window */ { "newwin", lc_newwin }, /* pad */ { "newpad", lc_newpad }, /* refresh */ { "doupdate", lc_doupdate }, /* inopts */ { "cbreak", lc_cbreak }, { "echo", lc_echo }, { "raw", lc_raw }, { "halfdelay", lc_halfdelay }, /* util */ { "unctrl", lc_unctrl }, { "keyname", lc_keyname }, { "delay_output", lc_delay_output }, { "flushinp", lc_flushinp }, /* getch */ { "ungetch", lc_ungetch }, /* outopts */ { "nl", lc_nl }, /* query terminfo database */ { "tigetflag", ti_getflag }, { "tigetnum", ti_getnum }, { "tigetstr", ti_getstr }, /* slk */ ECF(slk_init) ECF(slk_set) ECF(slk_refresh) ECF(slk_noutrefresh) ECF(slk_label) ECF(slk_clear) ECF(slk_restore) ECF(slk_touch) ECF(slk_attron) ECF(slk_attroff) ECF(slk_attrset) /* terminator */ {NULL, NULL} }; /* Prototype to keep compiler happy. */ 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, lc_initscr, 1); lua_settable(L, -3); return 1; } /* Local Variables: */ /* c-basic-offset: 4 */ /* End: */