/* * Curses binding for Lua 5.1, 5.2 & 5.3. * * (c) Gary V. Vaughan 2013-2017 * (c) Reuben Thomas 2009-2012 * (c) Tiago Dionizio 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. */ /*** Full-screen Text Terminal Manipulation. Some of the C functions beginning with "no" do not exist in Lua. You should use `curses.nl(false)` and `curses.nl(true)` instead of `nonl()` and `nl()`, and likewise `curses.echo(false)` and `curses.echo(true)` instead of `noecho()` and `echo()` . In this Lua module the `stdscr:getch()` function always returns an integer. In C, a single character is an integer, but in Lua (and Perl) a single character is a short string. The Perl Curses function `getch()` returns a char if it was a char, and a number if it was a constant; to get this behaviour in Lua you have to convert explicitly, e.g.: if c < 256 then c = string.char(c) end Some Lua functions take a different set of parameters than their C counterparts; for example, you should use `y, x = stdscr.getyx()` instead of `getstr(str)` and `getyx(y, x)`, and likewise for `getbegyx` and `getmaxyx` and `getparyx` and `pair_content`. The Perl Curses module now uses the C-compatible parameters, so be aware of this difference when translating code from Perl into Lua, as well as from C into Lua. Many curses functions have variants starting with the prefixes `w-`, `mv-`, and/or `wmv-`. These variants differ only in the explicit addition of a window, or by the addition of two coordinates that are used to move the cursor first. For example, in C `addch()` has three other variants: `waddch()`, `mvaddch()` and `mvwaddch()`. The Lua equivalents, respectively being `stdscr:addch()`, `somewindow:addch()`, `stdscr:mvaddch()` and `somewindow:mvaddch()`, with the window argument passed implicitly with Lua's `:` syntax sugar. @module curses */ #include "_helpers.c" #ifdef __linux__ #include "strlcpy.c" #endif #include "chstr.c" #include "window.c" static const char *STDSCR_REGISTRY = "curses:stdscr"; static const char *RIPOFF_TABLE = "curses:ripoffline"; /*** Create a new line drawing buffer instance. @function new_chstr @int len number of element to allocate @treturn chstr a new char buffer object @see curses.chstr */ static int Pnew_chstr(lua_State *L) { int len = checkint(L, 1); chstr* ncs = chstr_new(L, len); /* defined in curses/chstr.c */ memset(ncs->str, ' ', len*sizeof(chtype)); return 1; } #define CCR(n, v) \ lua_pushstring(L, n); \ lua_pushinteger(L, v); \ lua_settable(L, -3); #define CC(s) CCR(#s, s) #define CF(i) CCR(LCURSES_STR(LCURSES_SPLICE(KEY_F, i)), KEY_F(i)) /* ** 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); #ifdef A_COLOR CC(A_COLOR); #endif /* 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); /* ncurses extension: 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(31); 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) */ void cleanup_curses(void) { if (!isendwin()) { wclear(stdscr); wrefresh(stdscr); endwin(); } } extern void stack_dump(lua_State *L); static int init_stdscr(lua_State *L) { /* return stdscr - main window */ lc_newwin(L, stdscr); /* 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 */ lua_pushvalue(L, -2); register_curses_constants(L); /* install cleanup handler to help in debugging and screen trashing */ atexit(cleanup_curses); return 1; } /*** Clean up terminal prior to exiting or escaping curses. @function endwin @treturn bool `true`, if successful @see endwin(3x) */ static int Pendwin(lua_State *L) { return pushokresult(endwin()); } /*** Has @{endwin} been called more recently than @{curses.window:refresh}? @function isendwin @treturn bool whether @{endwin} has been called @see isendwin(3x) */ static int Pisendwin(lua_State *L) { return pushboolresult(isendwin()); } /*** Retern the main screen window. @function stdscr @treturn window main screen @see initscr @see stdscr(3x) */ static int Pstdscr(lua_State *L) { lua_pushstring(L, STDSCR_REGISTRY); lua_rawget(L, LUA_REGISTRYINDEX); return 1; } /*** Number of columns in the main screen window. @function cols @treturn int number of columns in the main screen @see lines @see stdscr @see COLS(3x) */ static int Pcols(lua_State *L) { return pushintresult(COLS); } /*** Number of lines in the main screen window. @function lines @treturn int number of lines in the main screen @see cols @see stdscr @see LINES(3x) */ static int Plines(lua_State *L) { return pushintresult(LINES); } /*** Initialise color output facility. @function start_color @treturn bool `true`, if successful @see can_change_color(3x) @see has_colors */ static int Pstart_color(lua_State *L) { return pushokresult(start_color()); } /*** Does the terminal have color capability? @function has_colors @treturn bool `true`, if the terminal supports colors @see can_change_color(3x) @see start_color @usage if curses.has_colors () then curses.start_color () end */ static int Phas_colors(lua_State *L) { return pushboolresult(has_colors()); } /*** Reserve `-1` to represent terminal default colors. @function use_default_colors @treturn bool `true`, if successful @see use_default_colors(3x) @fixme ncurses only? */ static int Puse_default_colors(lua_State *L) { return pushokresult(use_default_colors()); } /*** Set -1 foreground and background colors. @function use_default_colors @treturn bool `true`, if successful @see use_default_colors(3x) @fixme ncurses only? */ static int Passume_default_colors(lua_State *L) { int fg = checkint(L, 1); int bg = checkint(L, 2); return pushokresult(assume_default_colors(fg, bg)); } /*** Associate a color pair id with a specific foreground and background color. @function init_pair @int pair color pair id to act on @int f foreground color to assign @int b background color to assign @treturn bool `true`, if successful @see init_pair(3x) @see pair_content */ static int Pinit_pair(lua_State *L) { short pair = checkint(L, 1); short f = checkint(L, 2); short b = checkint(L, 3); return pushokresult(init_pair(pair, f, b)); } /*** Return the foreground and background colors associated with a color pair id. @function pair_content @int pair color pair id to act on @treturn int foreground color of *pair* @treturn int background color of *pair* @see can_change_color(3x) @see init_pair */ static int Ppair_content(lua_State *L) { short pair = 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; } /*** How many colors are available for this terminal? @function colors @treturn int total number of available colors @see can_change_color(3x) @see color_pairs */ static int Pcolors(lua_State *L) { return pushintresult(COLORS); } /*** How may distinct color pairs are supported by this terminal? @function color_pairs @treturn int total number of available color pairs @see can_change_color(3x) @see colors */ static int Pcolor_pairs(lua_State *L) { return pushintresult(COLOR_PAIRS); } /*** Return the attributes for the given color pair id. @function color_pair @int pair color pair id to act on @treturn int attributes for color pair *pair* @see can_change_color(3x) */ static int Pcolor_pair(lua_State *L) { int n = checkint(L, 1); return pushintresult(COLOR_PAIR(n)); } /*** Fetch the output speed of the terminal. @function baudrate @treturn int output speed of the terminal in bits-per-second @see baudrate(3x) */ static int Pbaudrate(lua_State *L) { return pushintresult(baudrate()); } /*** Fetch the terminal's current erase character. @function erasechar @treturn int current erase character @see erasechar(3x) */ static int Perasechar(lua_State *L) { return pushintresult(erasechar()); } /*** Fetch the character insert and delete capability of the terminal. @function has_ic @treturn bool `true`, if the terminal has insert and delete character operations @see has_ic(3x) */ static int Phas_ic(lua_State *L) { return pushboolresult(has_ic()); } /*** Fetch the line insert and delete capability of the terminal. @function has_il @treturn bool `true`, if the terminal has insert and delete line operations @see has_il(3x) */ static int Phas_il(lua_State *L) { return pushboolresult(has_il()); } /*** Fetch the terminal's current kill character. @function killchar @treturn int current line kill character @see killchar(3x) */ static int Pkillchar(lua_State *L) { return pushintresult(killchar()); } /*** Bitwise OR of all (or selected) video attributes supported by the terminal. @function termattrs @int[opt] a terminal attribute bits @treturn[1] bool `true`, if the terminal supports attribute *a* @treturn[2] int bitarray of supported terminal attributes @see termattrs(3x) */ static int Ptermattrs(lua_State *L) { if (lua_gettop(L) > 0) { int a = checkint(L, 1); return pushboolresult(termattrs() & a); } return pushintresult(termattrs()); } /*** Fetch the name of the terminal. @function termname @treturn string terminal name @see termname(3x) */ static int Ptermname(lua_State *L) { return pushstringresult(termname()); } /*** Fetch the verbose name of the terminal. @function longname @treturn string verbose description of the current terminal @see longname(3x) */ static int Plongname(lua_State *L) { return pushstringresult(longname()); } /* 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; } /*** Reduce the available size of the main screen. @function ripoffline @bool top_line @func callback @treturn bool `true`, if successful @see ripoffline(3x) */ static int Pripoffline(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 */ return pushokresult(ripoffline(top_line ? 1 : -1, ripoffline_cb)); } /*** Change the visibility of the cursor. @function curs_set @int vis one of `0` (invisible), `1` (visible) or `2` (very visible) @treturn[1] int previous cursor state @return[2] nil if *vis* is not supported @see curs_set(3x) */ static int Pcurs_set(lua_State *L) { int vis = checkint(L, 1); int state = curs_set(vis); if (state == ERR) return 0; return pushintresult(state); } /*** Sleep for a few milliseconds. @function napms @int ms time to wait in milliseconds @treturn bool `true`, if successful @see napms(3x) @see delay_output */ static int Pnapms(lua_State *L) { int ms = checkint(L, 1); return pushokresult(napms(ms)); } /*** Change the terminal size. @function resizeterm @int nlines number of lines @int ncols number of columns @treturn bool `true`, if successful @raise unimplemented @fixme ncurses only? */ static int Presizeterm(lua_State *L) { int nlines = checkint(L, 1); int ncols = checkint(L, 2); return pushokresult(resizeterm (nlines, ncols)); } /*** Send the terminal audible bell. @function beep @treturn bool `true`, if successful @see beep(3x) @see flash */ static int Pbeep(lua_State *L) { return pushokresult(beep()); } /*** Send the terminal visible bell. @function flash @treturn bool `true`, if successful @see flash(3x) @see beep */ static int Pflash(lua_State *L) { return pushokresult(flash()); } /*** Create a new window. @function newwin @int nlines number of window lines @int ncols number of window columns @int begin_y top line of window @int begin_x leftmost column of window @treturn window a new window object @see newwin(3x) @see curses.window */ static int Pnewwin(lua_State *L) { int nlines = checkint(L, 1); int ncols = checkint(L, 2); int begin_y = checkint(L, 3); int begin_x = checkint(L, 4); lc_newwin(L, newwin(nlines, ncols, begin_y, begin_x)); return 1; } /*** Refresh the visible terminal screen. @function doupdate @treturn bool `true`, if successful @see doupdate(3x) @see curses.window:refresh */ static int Pdoupdate(lua_State *L) { return pushokresult(doupdate()); } /*** Initialise the soft label keys area. This must be called before @{initscr}. @function slk_init @int fmt @treturn bool `true`, if successful @see slk_init(3x) */ static int Pslk_init(lua_State *L) { int fmt = checkint(L, 1); return pushokresult(slk_init(fmt)); } /*** Set the label for a soft label key. @function slk_set @int labnum @string label @int fmt @treturn bool `true`, if successful @see slk_set(3x) */ static int Pslk_set(lua_State *L) { int labnum = checkint(L, 1); const char* label = luaL_checkstring(L, 2); int fmt = checkint(L, 3); return pushokresult(slk_set(labnum, label, fmt)); } /*** Refresh the soft label key area. @function slk_refresh @treturn bool `true`, if successful @see slk_refresh(3x) @see curses.window:refresh */ static int Pslk_refresh(lua_State *L) { return pushokresult(slk_refresh()); } /*** Copy the soft label key area backing screen to the virtual screen. @function slk_noutrefresh @treturn bool `true`, if successful @see slk_noutrefresh(3x) @see curses.window:refresh */ static int Pslk_noutrefresh(lua_State *L) { return pushokresult(slk_noutrefresh()); } /*** Fetch the label for a soft label key. @function slk_label @int labnum @treturn string current label for *labnum* @see slk_label(3x) */ static int Pslk_label(lua_State *L) { int labnum = checkint(L, 1); return pushstringresult(slk_label(labnum)); } /*** Clears the soft labels from the screen. @function slk_clear @treturn bool `true`, if successful @see slk_clear(3x) @see slk_restore */ static int Pslk_clear(lua_State *L) { return pushokresult(slk_clear()); } /*** Restores the soft labels to the screen. @function slk_restore @treturn bool `true`, if successful @see slk_restore(3x) @see slk_clear */ static int Pslk_restore(lua_State *L) { return pushokresult(slk_restore()); } /*** Mark the soft label key area for refresh. @function slk_touch @treturn bool `true`, if successful @see slk_touch(3x) */ static int Pslk_touch(lua_State *L) { return pushokresult(slk_touch()); } /*** Enable an attribute for soft labels. @function slk_attron @int attrs @treturn bool `true`, if successful @see slk_attron(3x) */ static int Pslk_attron(lua_State *L) { chtype attrs = checkch(L, 1); return pushokresult(slk_attron(attrs)); } /*** Disable an attribute for soft labels. @function slk_attroff @int attrs @treturn bool `true`, if successful @see slk_attroff(3x) */ static int Pslk_attroff(lua_State *L) { chtype attrs = checkch(L, 1); return pushokresult(slk_attroff(attrs)); } /*** Set the attributes for soft labels. @function slk_attrset @int attrs @treturn bool `true`, if successful @see slk_attrset(3x) */ static int Pslk_attrset(lua_State *L) { chtype attrs = checkch(L, 1); return pushokresult(slk_attrset(attrs)); } /*** Put the terminal into cbreak mode. @function cbreak @bool[opt] on @treturn bool `true`, if successful @see cbreak(3x) @see nocbreak(3x) */ static int Pcbreak(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) return pushokresult(cbreak()); return pushokresult(nocbreak()); } /*** Whether characters are echoed to the terminal as they are typed. @function echo @bool[opt] on @treturn bool `true`, if successful @see echo(3x) @see noecho(3x) */ static int Pecho(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) return pushokresult(echo()); return pushokresult(noecho()); } /*** Put the terminal into raw mode. @function raw @bool[opt] on @treturn bool `true`, if successful @see noraw(3x) @see raw(3x) */ static int Praw(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) return pushokresult(raw()); return pushokresult(noraw()); } /*** Put the terminal into halfdelay mode. @function halfdelay @int tenths delay in tenths of a second @treturn bool `true`, if successful @see halfdelay(3x) */ static int Phalfdelay(lua_State *L) { int tenths = checkint(L, 1); return pushokresult(halfdelay(tenths)); } /*** Whether to translate a return key to newline on input. @function nl @bool[opt] on @treturn bool `true`, if successful @see nl(3x) @see nonl(3x) */ static int Pnl(lua_State *L) { if (lua_isnoneornil(L, 1) || lua_toboolean(L, 1)) return pushokresult(nl()); return pushokresult(nonl()); } /*** Return a printable representation of a character, ignoring attributes. @function unctrl @int c character to act on @treturn string printable representation of *c* @see unctrl(3x) @see keyname */ static int Punctrl(lua_State *L) { chtype c = checkch(L, 1); return pushstringresult(unctrl(c)); } /*** Return a printable representation of a key. @function keyname @int c a key @treturn string key name of *c* @see keyname(3x) @see unctrl */ static int Pkeyname(lua_State *L) { int c = checkint(L, 1); return pushstringresult(keyname(c)); } /*** Insert padding characters to force a short delay. @function delay_output @int ms delay time in milliseconds @treturn bool `true`, if successful @see napms @fixme ncurses only? */ static int Pdelay_output(lua_State *L) { int ms = checkint(L, 1); return pushokresult(delay_output(ms)); } /*** Throw away any typeahead in the keyboard input buffer. @function flushinp @treturn bool `true`, if successful @see flushinp(3x) @see ungetch */ static int Pflushinp(lua_State *L) { return pushboolresult(flushinp()); } /*** Return a character to the keyboard input buffer. @function ungetch @int c @treturn bool `true`, if successful @see ungetch(3x) @see flushinp */ static int Pungetch(lua_State *L) { int c = checkint(L, 1); return pushokresult(ungetch(c)); } /*** Create a new pad. @function newpad @int nlines @int ncols @treturn bool `true`, if successful @see newpad(3x) */ static int Pnewpad(lua_State *L) { int nlines = checkint(L, 1); int ncols = checkint(L, 2); lc_newwin(L, newpad(nlines, ncols)); return 1; } static char ti_capname[32]; /*** Fetch terminfo boolean capability. @function tigetflag @string capname @treturn bool content of terminal boolean capability @see tigetflag(3x) @see terminfo(5) */ static int Ptigetflag (lua_State *L) { int r; strlcpy (ti_capname, luaL_checkstring (L, 1), sizeof (ti_capname)); r = tigetflag (ti_capname); if (-1 == r) return luaL_error (L, "`%s' is not a boolean capability", ti_capname); return pushboolresult (r); } /*** Fetch terminfo numeric capability. @function tigetnum @string capname @treturn int content of terminal numeric capability @see tigetnum(3x) @see terminfo(5) */ static int Ptigetnum (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; } /*** Fetch terminfo string capability. @function tigetstr @string capname @treturn string content of terminal string capability @see tigetstr(3x) @see terminfo(5) */ static int Ptigetstr (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; } static const luaL_Reg curseslib[] = { LCURSES_FUNC( Pbaudrate ), LCURSES_FUNC( Pbeep ), LCURSES_FUNC( Pcbreak ), LCURSES_FUNC( Pcolor_pair ), LCURSES_FUNC( Pcolor_pairs ), LCURSES_FUNC( Pcolors ), LCURSES_FUNC( Pcols ), LCURSES_FUNC( Pcurs_set ), LCURSES_FUNC( Pdelay_output ), LCURSES_FUNC( Pdoupdate ), LCURSES_FUNC( Pecho ), LCURSES_FUNC( Pendwin ), LCURSES_FUNC( Perasechar ), LCURSES_FUNC( Pflash ), LCURSES_FUNC( Pflushinp ), LCURSES_FUNC( Phalfdelay ), LCURSES_FUNC( Phas_colors ), LCURSES_FUNC( Phas_ic ), LCURSES_FUNC( Phas_il ), LCURSES_FUNC( Pinit_pair ), LCURSES_FUNC( Pisendwin ), LCURSES_FUNC( Pkeyname ), LCURSES_FUNC( Pkillchar ), LCURSES_FUNC( Plines ), LCURSES_FUNC( Plongname ), LCURSES_FUNC( Pnapms ), LCURSES_FUNC( Pnew_chstr ), LCURSES_FUNC( Pnewpad ), LCURSES_FUNC( Pnewwin ), LCURSES_FUNC( Pnl ), LCURSES_FUNC( Ppair_content ), LCURSES_FUNC( Praw ), LCURSES_FUNC( Presizeterm ), LCURSES_FUNC( Pripoffline ), LCURSES_FUNC( Pslk_attroff ), LCURSES_FUNC( Pslk_attron ), LCURSES_FUNC( Pslk_attrset ), LCURSES_FUNC( Pslk_clear ), LCURSES_FUNC( Pslk_init ), LCURSES_FUNC( Pslk_label ), LCURSES_FUNC( Pslk_noutrefresh ), LCURSES_FUNC( Pslk_refresh ), LCURSES_FUNC( Pslk_restore ), LCURSES_FUNC( Pslk_set ), LCURSES_FUNC( Pslk_touch ), LCURSES_FUNC( Pstart_color ), LCURSES_FUNC( Pstdscr ), LCURSES_FUNC( Ptermattrs ), LCURSES_FUNC( Ptermname ), LCURSES_FUNC( Ptigetflag ), LCURSES_FUNC( Ptigetnum ), LCURSES_FUNC( Ptigetstr ), LCURSES_FUNC( Punctrl ), LCURSES_FUNC( Pungetch ), LCURSES_FUNC( Puse_default_colors), LCURSES_FUNC( Passume_default_colors), {NULL, NULL} }; /*** Constants. @section constants */ /*** Curses constants. Any constants not available in the underlying system will be `nil` valued, see @{curses.lua}. Many of the `KEY_` constants cannot be generated by modern keyboards and are mostly for historical compatibility with ancient terminal hardware keyboards. Note that almost all of these constants remain undefined (`nil`) until after @{curses.initscr} has returned successfully. @table curses @int ACS_BLOCK alternate character set solid block @int ACS_BOARD alternate character set board of squares @int ACS_BTEE alternate character set bottom-tee @int ACS_BULLET alternate character set bullet @int ACS_CKBOARD alternate character set stipple @int ACS_DARROW alternate character set down arrow @int ACS_DEGREE alternate character set degrees mark @int ACS_DIAMOND alternate character set diamond @int ACS_HLINE alternate character set horizontal line @int ACS_LANTERN alternate character set lantern @int ACS_LARROW alternate character set left arrow @int ACS_LLCORNER alternate character set lower left corner @int ACS_LRCORNER alternate character set lower right corner @int ACS_LTEE alternate character set left tee @int ACS_PLMINUS alternate character set plus/minus @int ACS_PLUS alternate character set plus @int ACS_RARROW alternate character set right arrow @int ACS_RTEE alternate character set right tee @int ACS_S1 alternate character set scan-line 1 @int ACS_S9 alternate character set scan-line 9 @int ACS_TTEE alternate character set top tee @int ACS_UARROW alternate character set up arrow @int ACS_ULCORNER alternate character set upper left corner @int ACS_URCORNER alternate character set upper right corner @int ACS_VLINE alternate character set vertical line @int A_ALTCHARSET alternatate character set attribute @int A_ATTRIBUTES attributed character attributes bitmask @int A_BLINK blinking attribute @int A_BOLD bold attribute @int A_CHARTEXT attributed character text bitmask @int A_COLOR attributed character color-pair bitmask @int A_DIM half-bright attribute @int A_INVIS invisible attribute @int A_NORMAL normal attribute (all attributes off) @int A_PROTECT protected attribute @int A_REVERSE reverse video attribute @int A_STANDOUT standout attribute @int A_UNDERLINE underline attribute @int COLOR_BLACK black color attribute @int COLOR_BLUE blue color attribute @int COLOR_CYAN cyan color attribute @int COLOR_GREEN green color attribute @int COLOR_MAGENTA magenta color attribute @int COLOR_RED red color attribute @int COLOR_WHITE white color attribute @int COLOR_YELLOW yellow color attribute @int KEY_A1 upper-left of keypad key @int KEY_A3 upper-right of keypad key @int KEY_B2 center of keypad key @int KEY_BACKSPACE backspace key @int KEY_BEG beginning key @int KEY_BREAK break key @int KEY_BTAB backtab key @int KEY_C1 bottom-left of keypad key @int KEY_C3 bottom-right of keypad key @int KEY_CANCEL cancel key @int KEY_CATAB clear all tabs key @int KEY_CLEAR clear screen key @int KEY_CLOSE close key @int KEY_COMMAND command key @int KEY_COPY copy key @int KEY_CREATE create key @int KEY_CTAB clear tab key @int KEY_DC delete character key @int KEY_DL delete line key @int KEY_DOWN down arrow key @int KEY_EIC exit insert char mode key @int KEY_END end key @int KEY_ENTER enter key @int KEY_EOL clear to end of line key @int KEY_EOS clear to end of screen key @int KEY_EXIT exit key @int KEY_F0 f0 key @int KEY_F1 f1 key @int KEY_F2 f2 key @int KEY_F3 f3 key @int KEY_F4 f4 key @int KEY_F5 f5 key @int KEY_F6 f6 key @int KEY_F7 f7 key @int KEY_F8 f8 key @int KEY_F9 f9 key @int KEY_F10 f10 key @int KEY_F11 f11 key @int KEY_F12 f12 key @int KEY_F13 f13 key @int KEY_F14 f14 key @int KEY_F15 f15 key @int KEY_F16 f16 key @int KEY_F17 f17 key @int KEY_F18 f18 key @int KEY_F19 f19 key @int KEY_F20 f20 key @int KEY_F21 f21 key @int KEY_F22 f22 key @int KEY_F23 f23 key @int KEY_F24 f24 key @int KEY_F25 f25 key @int KEY_F26 f26 key @int KEY_F27 f27 key @int KEY_F28 f28 key @int KEY_F29 f29 key @int KEY_F30 f30 key @int KEY_F31 f31 key @int KEY_F32 f32 key @int KEY_F33 f33 key @int KEY_F34 f34 key @int KEY_F35 f35 key @int KEY_F36 f36 key @int KEY_F37 f37 key @int KEY_F38 f38 key @int KEY_F39 f39 key @int KEY_F40 f40 key @int KEY_F41 f41 key @int KEY_F42 f42 key @int KEY_F43 f43 key @int KEY_F44 f44 key @int KEY_F45 f45 key @int KEY_F46 f46 key @int KEY_F47 f47 key @int KEY_F48 f48 key @int KEY_F49 f49 key @int KEY_F50 f50 key @int KEY_F51 f51 key @int KEY_F52 f52 key @int KEY_F53 f53 key @int KEY_F54 f54 key @int KEY_F55 f55 key @int KEY_F56 f56 key @int KEY_F57 f57 key @int KEY_F58 f58 key @int KEY_F59 f59 key @int KEY_F60 f60 key @int KEY_F61 f61 key @int KEY_F62 f62 key @int KEY_F63 f63 key @int KEY_FIND find key @int KEY_HELP help key @int KEY_HOME home key @int KEY_IC enter insert char mode key @int KEY_IL insert line key @int KEY_LEFT cursor left key @int KEY_LL home down or bottom key @int KEY_MARK mark key @int KEY_MESSAGE message key @int KEY_MOUSE mouse event available virtual key @int KEY_MOVE move key @int KEY_NEXT next object key @int KEY_NPAGE next page key @int KEY_OPEN open key @int KEY_OPTIONS options key @int KEY_PPAGE previous page key @int KEY_PREVIOUS prewious object key @int KEY_PRINT print key @int KEY_REDO redo key @int KEY_REFERENCE reference key @int KEY_REFRESH refresh key @int KEY_REPLACE replace key @int KEY_RESET hard reset key @int KEY_RESIZE resize event virtual key @int KEY_RESTART restart key @int KEY_RESUME resume key @int KEY_RIGHT cursor right key @int KEY_SAVE save key @int KEY_SBEG shift beginning key @int KEY_SCANCEL shift cancel key @int KEY_SCOMMAND shift command key @int KEY_SCOPY shift copy key @int KEY_SCREATE shift create key @int KEY_SDC shift delete character key @int KEY_SDL shift delete line key @int KEY_SELECT select key @int KEY_SEND send key @int KEY_SEOL shift clear to end of line key @int KEY_SEXIT shift exit key @int KEY_SF scroll one line forward key @int KEY_SFIND shift find key @int KEY_SHELP shift help key @int KEY_SHOME shift home key @int KEY_SIC shift enter insert mode key @int KEY_SLEFT shift cursor left key @int KEY_SMESSAGE shift message key @int KEY_SMOVE shift move key @int KEY_SNEXT shift next object key @int KEY_SOPTIONS shift options key @int KEY_SPREVIOUS shift previous object key @int KEY_SPRINT shift print key @int KEY_SR scroll one line backward key @int KEY_SREDO shift redo key @int KEY_SREPLACE shift replace key @int KEY_SRESET soft reset key @int KEY_SRIGHT shift cursor right key @int KEY_SRSUME shift resume key @int KEY_SSAVE shift save key @int KEY_SSUSPEND shift suspend key @int KEY_STAB shift tab key @int KEY_SUNDO shift undo key @int KEY_SUSPEND suspend key @int KEY_UNDO undo key @int KEY_UP cursor up key @usage -- Print curses constants supported on this host. for name, value in pairs (require "curses") do if type (value) == "number" then print (name, value) end end */ LUALIB_API int luaopen_curses(lua_State *L) { luaopen_curses_window(L); luaopen_curses_chstr(L); luaL_register(L, "curses", curseslib); init_stdscr(L); return 1; }