summaryrefslogtreecommitdiff
path: root/ext/curses/curses.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/curses/curses.c')
-rw-r--r--ext/curses/curses.c600
1 files changed, 563 insertions, 37 deletions
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 218e545..5d1e315 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -73,6 +73,9 @@ static VALUE cMouseEvent;
static VALUE rb_stdscr;
+static rb_encoding *keyboard_encoding;
+static rb_encoding *terminal_encoding;
+
struct windata {
WINDOW *window;
};
@@ -135,8 +138,21 @@ prep_window(VALUE class, WINDOW *window)
return obj;
}
+#if (defined(HAVE_ADDNWSTR) || defined(HAVE_WADDNWSTR)) && defined(_WIN32)
+static inline rb_encoding *
+get_wide_encoding(void)
+{
+ static rb_encoding *utf16le = NULL;
+ if (!utf16le) {
+ utf16le = rb_enc_find("utf-16le");
+ }
+ return utf16le;
+}
+#endif
+
/*-------------------------- module Curses --------------------------*/
+static void curses_finalize(VALUE);
/*
* Document-method: Curses.init_screen
*
@@ -152,6 +168,7 @@ curses_init_screen(void)
if (stdscr == 0) {
rb_raise(rb_eRuntimeError, "can't initialize curses");
}
+ rb_set_end_proc(curses_finalize, 0);
clear();
rb_stdscr = prep_window(cWindow, stdscr);
return rb_stdscr;
@@ -250,6 +267,23 @@ curses_clear(VALUE obj)
return Qnil;
}
+#ifdef HAVE_WERASE
+/*
+ * Document-method: Curses.erase
+ *
+ * Erase the screen.
+ */
+static VALUE
+curses_erase(VALUE obj)
+{
+ curses_stdscr();
+ werase(stdscr);
+ return Qnil;
+}
+#else
+#define curses_erase rb_f_notimplement
+#endif
+
/*
* Document-method: Curses.clrtoeol
*
@@ -628,11 +662,19 @@ static VALUE
curses_addstr(VALUE obj, VALUE str)
{
StringValue(str);
- str = rb_str_export_locale(str);
+#if defined(HAVE_ADDNWSTR) && defined(_WIN32)
+ str = rb_str_export_to_enc(str, get_wide_encoding());
+ curses_stdscr();
+ if (!NIL_P(str)) {
+ addnwstr((wchar_t *)RSTRING_PTR(str), RSTRING_LEN(str) / sizeof(wchar_t));
+ }
+#else
+ str = rb_str_export_to_enc(str, terminal_encoding);
curses_stdscr();
if (!NIL_P(str)) {
addstr(StringValueCStr(str));
}
+#endif
return Qnil;
}
@@ -663,7 +705,7 @@ curses_getch(VALUE obj)
if (rb_isprint(c)) {
char ch = (char)c;
- return rb_locale_str_new(&ch, 1);
+ return rb_external_str_new_with_enc(&ch, 1, keyboard_encoding);
}
return UINT2NUM(c);
}
@@ -696,7 +738,7 @@ curses_getstr(VALUE obj)
curses_stdscr();
rb_thread_call_without_gvl(getstr_func, rtn, RUBY_UBF_IO, 0);
- return rb_locale_str_new_cstr(rtn);
+ return rb_external_str_new_with_enc(rtn, strlen(rtn), keyboard_encoding);
}
/*
@@ -869,7 +911,8 @@ curses_setscrreg(VALUE obj, VALUE top, VALUE bottom)
* Document-method: Curses.attroff
* call-seq: attroff(attrs)
*
- * Turns on the named attributes +attrs+ without affecting any others.
+ * Turns off the named attributes +attrs+
+ * without affecting any others.
*
* See also Curses::Window.attrset for additional information.
*/
@@ -885,7 +928,7 @@ curses_attroff(VALUE obj, VALUE attrs)
* Document-method: Curses.attron
* call-seq: attron(attrs)
*
- * Turns off the named attributes +attrs+
+ * Turns on the named attributes +attrs+
* without turning any other attributes on or off.
*
* See also Curses::Window.attrset for additional information.
@@ -933,7 +976,7 @@ curses_bkgdset(VALUE obj, VALUE ch)
{
#ifdef HAVE_BKGDSET
curses_stdscr();
- bkgdset(NUM2CH(ch));
+ bkgdset(NUM2CHTYPE(ch));
#endif
return Qnil;
}
@@ -954,7 +997,7 @@ curses_bkgd(VALUE obj, VALUE ch)
{
#ifdef HAVE_BKGD
curses_stdscr();
- return (bkgd(NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
+ return (bkgd(NUM2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
#else
return Qfalse;
#endif
@@ -977,6 +1020,23 @@ curses_use_default_colors(VALUE obj)
#define curses_use_default_colors rb_f_notimplement
#endif
+#if defined(HAVE_ASSUME_DEFAULT_COLORS)
+/*
+ * tells which colors to paint for color pair 0.
+ *
+ * see also the system manual for default_colors(3)
+ */
+static VALUE
+curses_assume_default_colors(VALUE obj, VALUE fg, VALUE bg)
+{
+ curses_stdscr();
+ assume_default_colors(NUM2INT(fg), NUM2INT(bg));
+ return Qnil;
+}
+#else
+#define curses_assume_default_colors rb_f_notimplement
+#endif
+
#if defined(HAVE_TABSIZE)
/*
* Document-method: Curses.TABSIZE=
@@ -1562,6 +1622,26 @@ window_clear(VALUE obj)
return Qnil;
}
+#ifdef HAVE_WERASE
+/*
+ * Document-method: Curses::Window.erase
+ *
+ * Erase the window.
+ */
+static VALUE
+window_erase(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ werase(winp->window);
+
+ return Qnil;
+}
+#else
+#define curses_erase rb_f_notimplement
+#endif
+
/*
* Document-method: Curses::Window.clrtoeol
*
@@ -1618,6 +1698,145 @@ window_noutrefresh(VALUE obj)
return Qnil;
}
+#ifdef HAVE_REDRAWWIN
+/*
+ * Document-method: Curses::Window.redraw
+ *
+ * Redraws the entire window.
+ */
+static VALUE
+window_redraw(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ redrawwin(winp->window);
+
+ return Qnil;
+}
+#else
+#define window_redraw rb_f_notimplement
+#endif
+
+#ifdef HAVE_TOUCHWIN
+/*
+ * Document-method: Curses::Window.touch
+ *
+ * Treat the window as if it has been modified since the last call of refresh.
+ */
+static VALUE
+window_touch(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ touchwin(winp->window);
+
+ return Qnil;
+}
+#else
+#define window_touch rb_f_notimplement
+#endif
+
+#ifdef HAVE_UNTOUCHWIN
+/*
+ * Document-method: Curses::Window.untouch
+ *
+ * Treat the window as if it has not been modified since the last call of
+ * refresh.
+ */
+static VALUE
+window_untouch(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ untouchwin(winp->window);
+
+ return Qnil;
+}
+#else
+#define window_touch rb_f_notimplement
+#endif
+
+#ifdef HAVE_IS_WINTOUCHED
+/*
+ * Document-method: Curses::Window.touched?
+ *
+ * Return true if the window has been modified since the last call of refresh.
+ */
+static VALUE
+window_touched(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ return is_wintouched(winp->window) ? Qtrue : Qfalse;
+}
+#else
+#define window_touched rb_f_notimplement
+#endif
+
+#ifdef HAVE_WTOUCHLN
+/*
+ * Document-method: Curses::Window.touch_line
+ * call-seq: touch_line(y, n, changed = true)
+ *
+ * Make n lines from line y look as if they have (changed = true) or have not
+ * (changed = false) been modified since the last call of refresh.
+ */
+static VALUE
+window_touch_line(int argc, VALUE *argv, VALUE obj)
+{
+ struct windata *winp;
+ VALUE y, n, changed;
+ int result;
+
+ rb_scan_args(argc, argv, "12", &y, &n, &changed);
+ if (argc < 2) {
+ n = INT2NUM(1);
+ }
+ if (argc < 3) {
+ changed = Qtrue;
+ }
+ GetWINDOW(obj, winp);
+ result = wtouchln(winp->window, NUM2INT(y), NUM2INT(n), RTEST(changed));
+ if (result == ERR) {
+ rb_raise(rb_eRangeError, "Out of window");
+ }
+
+ return Qnil;
+}
+#else
+#define window_touch_line rb_f_notimplement
+#endif
+
+#ifdef HAVE_IS_LINETOUCHED
+/*
+ * Document-method: Curses::Window.line_touched?
+ * call-seq: line_touched?(line)
+ *
+ * Return true if the specified line has been modified since the last call of
+ * refresh.
+ */
+static VALUE
+window_line_touched(VALUE obj, VALUE line)
+{
+ struct windata *winp;
+ int result, n;
+
+ GetWINDOW(obj, winp);
+ n = NUM2INT(line);
+ result = is_linetouched(winp->window, n);
+ if (result == ERR) {
+ rb_raise(rb_eArgError, "Invalid line %d", n);
+ }
+ return result ? Qtrue : Qfalse;
+}
+#else
+#define window_line_touched rb_f_notimplement
+#endif
+
/*
* Document-method: Curses::Window.move
* call-seq: move(y,x)
@@ -1701,7 +1920,7 @@ window_maxy(VALUE obj)
return INT2FIX(getmaxy(winp->window));
#elif defined(getmaxyx)
{
- int x, y;
+ int RB_UNUSED_VAR(x), y;
getmaxyx(winp->window, y, x);
return INT2FIX(y);
}
@@ -1725,7 +1944,7 @@ window_maxx(VALUE obj)
return INT2FIX(getmaxx(winp->window));
#elif defined(getmaxyx)
{
- int x, y;
+ int x, RB_UNUSED_VAR(y);
getmaxyx(winp->window, y, x);
return INT2FIX(x);
}
@@ -1921,9 +2140,15 @@ window_addstr(VALUE obj, VALUE str)
struct windata *winp;
StringValue(str);
- str = rb_str_export_locale(str);
+#if defined(HAVE_WADDNWSTR) && defined(_WIN32)
+ str = rb_str_export_to_enc(str, get_wide_encoding());
+ GetWINDOW(obj, winp);
+ waddnwstr(winp->window, (wchar_t *)RSTRING_PTR(str), RSTRING_LEN(str) / sizeof(wchar_t));
+#else
+ str = rb_str_export_to_enc(str, terminal_encoding);
GetWINDOW(obj, winp);
waddstr(winp->window, StringValueCStr(str));
+#endif
}
return Qnil;
}
@@ -1981,7 +2206,7 @@ window_getch(VALUE obj)
if (rb_isprint(c)) {
char ch = (char)c;
- return rb_locale_str_new(&ch, 1);
+ return rb_external_str_new_with_enc(&ch, 1, keyboard_encoding);
}
return UINT2NUM(c);
}
@@ -2018,7 +2243,8 @@ window_getstr(VALUE obj)
GetWINDOW(obj, winp);
arg.win = winp->window;
rb_thread_call_without_gvl(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0);
- return rb_locale_str_new_cstr(arg.rtn);
+ return rb_external_str_new_with_enc(arg.rtn, strlen(arg.rtn),
+ keyboard_encoding);
}
/*
@@ -2219,7 +2445,8 @@ window_scrl(VALUE obj, VALUE n)
* Document-method: Curses::Window.attroff
* call-seq: attroff(attrs)
*
- * Turns on the named attributes +attrs+ without affecting any others.
+ * Turns off the named attributes +attrs+
+ * without affecting any others.
*
* See also Curses::Window.attrset
*/
@@ -2240,7 +2467,7 @@ window_attroff(VALUE obj, VALUE attrs)
* Document-method: Curses::Window.attron
* call-seq: attron(attrs)
*
- * Turns off the named attributes +attrs+
+ * Turns on the named attributes +attrs+
* without turning any other attributes on or off.
*
* See also Curses::Window.attrset
@@ -2322,7 +2549,7 @@ window_bkgdset(VALUE obj, VALUE ch)
struct windata *winp;
GetWINDOW(obj,winp);
- wbkgdset(winp->window, NUM2CH(ch));
+ wbkgdset(winp->window, NUM2CHTYPE(ch));
#endif
return Qnil;
}
@@ -2343,7 +2570,7 @@ window_bkgd(VALUE obj, VALUE ch)
struct windata *winp;
GetWINDOW(obj,winp);
- return (wbkgd(winp->window, NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
+ return (wbkgd(winp->window, NUM2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
#else
return Qfalse;
#endif
@@ -2362,7 +2589,7 @@ window_getbkgd(VALUE obj)
struct windata *winp;
GetWINDOW(obj,winp);
- return (c = getbkgd(winp->window) != ERR) ? CH2FIX(c) : Qnil;
+ return (c = getbkgd(winp->window) != ERR) ? ULONG2NUM(c) : Qnil;
#else
return Qnil;
#endif
@@ -2521,9 +2748,6 @@ pad_initialize(VALUE obj, VALUE h, VALUE w)
return obj;
}
-#if 1
-#define pad_subpad window_subwin
-#else
/*
* Document-method: Curses::Pad.subpad
* call-seq:
@@ -2537,7 +2761,7 @@ static VALUE
pad_subpad(VALUE obj, VALUE height, VALUE width, VALUE begin_x, VALUE begin_y)
{
struct windata *padp;
- WINDOW *subpad;
+ WINDOW *sub_pad;
VALUE pad;
int h, w, x, y;
@@ -2546,12 +2770,11 @@ pad_subpad(VALUE obj, VALUE height, VALUE width, VALUE begin_x, VALUE begin_y)
x = NUM2INT(begin_x);
y = NUM2INT(begin_y);
GetWINDOW(obj, padp);
- subpad = subwin(padp->window, h, w, x, y);
- pad = prep_window(rb_obj_class(obj), subpad);
+ sub_pad = subpad(padp->window, h, w, x, y);
+ pad = prep_window(rb_obj_class(obj), sub_pad);
return pad;
}
-#endif
/*
* Document-method: Curses::Pad.refresh
@@ -2622,6 +2845,239 @@ pad_noutrefresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow,
}
#endif /* HAVE_NEWPAD */
+/*
+ * Document-method: Curses.keyboard_encoding
+ * call-seq: Curses.keyboard_encoding
+ *
+ * Returns the encoding for keyboard input.
+ */
+static VALUE
+curses_get_keyboard_encoding(VALUE obj)
+{
+ return rb_enc_from_encoding(keyboard_encoding);
+}
+
+/*
+ * Document-method: Curses.keyboard_encoding=
+ * call-seq: Curses.keyboard_encoding = encoding
+ *
+ * Sets the encoding for keyboard input.
+ */
+static VALUE
+curses_set_keyboard_encoding(VALUE obj, VALUE enc)
+{
+ keyboard_encoding = rb_to_encoding(enc);
+ return enc;
+}
+
+/*
+ * Document-method: Curses.terminal_encoding
+ * call-seq: Curses.terminal_encoding
+ *
+ * Returns the encoding for terminal output.
+ */
+static VALUE
+curses_get_terminal_encoding(VALUE obj)
+{
+ return rb_enc_from_encoding(terminal_encoding);
+}
+
+/*
+ * Document-method: Curses.terminal_encoding=
+ * call-seq: Curses.terminal_encoding = encoding
+ *
+ * Sets the encoding for terminal output.
+ */
+static VALUE
+curses_set_terminal_encoding(VALUE obj, VALUE enc)
+{
+ terminal_encoding = rb_to_encoding(enc);
+ return enc;
+}
+
+/*
+ * Document-method: Curses.unget_char
+ * call-seq: unget_char(ch)
+ *
+ * Places +ch+ back onto the input queue to be returned by
+ * the next call to Curses.get_char etc.
+ *
+ * There is just one input queue for all windows.
+ */
+static VALUE
+curses_unget_char(VALUE obj, VALUE ch)
+{
+ ID id_ord;
+ unsigned int c;
+
+ curses_stdscr();
+ if (FIXNUM_P(ch)) {
+ ungetch(NUM2UINT(ch));
+ }
+ else {
+ StringValue(ch);
+ CONST_ID(id_ord, "ord");
+ c = NUM2UINT(rb_funcall(ch, id_ord, 0));
+#ifdef HAVE_UNGET_WCH
+ unget_wch(c);
+#else
+ if (c > 0xff) {
+ rb_raise(rb_eRangeError, "Out of range: %u", c);
+ }
+ ungetch(c);
+#endif
+ }
+ return Qnil;
+}
+
+static VALUE
+keyboard_uint_chr(unsigned int ch)
+{
+ return rb_enc_uint_chr(ch, keyboard_encoding);
+}
+
+#ifdef HAVE_GET_WCH
+struct get_wch_arg {
+ int retval;
+ wint_t ch;
+};
+
+static void *
+get_wch_func(void *_arg)
+{
+ struct get_wch_arg *arg = (struct get_wch_arg *) _arg;
+ arg->retval = get_wch(&arg->ch);
+ return 0;
+}
+#endif
+
+/*
+ * Document-method: Curses.get_char
+ *
+ * Read and returns a character or function key from the window.
+ * A single or multibyte character is represented by a String, and
+ * a function key is represented by an Integer.
+ * Returns nil if no input is ready.
+ *
+ * See Curses::Key to all the function KEY_* available
+ *
+ */
+static VALUE
+curses_get_char(VALUE obj)
+{
+#ifdef HAVE_GET_WCH
+ struct get_wch_arg arg;
+
+ curses_stdscr();
+ rb_thread_call_without_gvl(get_wch_func, &arg, RUBY_UBF_IO, 0);
+ switch (arg.retval) {
+ case OK:
+ return keyboard_uint_chr(arg.ch);
+ case KEY_CODE_YES:
+ return UINT2NUM(arg.ch);
+ }
+ return Qnil;
+#else
+ int c;
+
+ curses_stdscr();
+ rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
+ if (c > 0xff) {
+ return INT2NUM(c);
+ }
+ else if (c >= 0) {
+ return keyboard_uint_chr(c);
+ }
+ else {
+ return Qnil;
+ }
+#endif
+}
+
+
+#ifdef HAVE_WGET_WCH
+struct wget_wch_arg {
+ WINDOW *win;
+ int retval;
+ wint_t ch;
+};
+
+static void *
+wget_wch_func(void *_arg)
+{
+ struct wget_wch_arg *arg = (struct wget_wch_arg *) _arg;
+ arg->retval = wget_wch(arg->win, &arg->ch);
+ return 0;
+}
+#endif
+
+/*
+ * Document-method: Curses::Window.get_char
+ *
+ * Read and returns a character or function key from the window.
+ * A single or multibyte character is represented by a String, and
+ * a function key is represented by an Integer.
+ * Returns nil if no input is ready.
+ *
+ * See Curses::Key to all the function KEY_* available
+ *
+ */
+static VALUE
+window_get_char(VALUE obj)
+{
+#ifdef HAVE_WGET_WCH
+ struct windata *winp;
+ struct wget_wch_arg arg;
+
+ GetWINDOW(obj, winp);
+ arg.win = winp->window;
+ rb_thread_call_without_gvl(wget_wch_func, &arg, RUBY_UBF_IO, 0);
+ switch (arg.retval) {
+ case OK:
+ return keyboard_uint_chr(arg.ch);
+ case KEY_CODE_YES:
+ return UINT2NUM(arg.ch);
+ }
+ return Qnil;
+#else
+ struct windata *winp;
+ struct wgetch_arg arg;
+
+ GetWINDOW(obj, winp);
+ arg.win = winp->window;
+ rb_thread_call_without_gvl(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0);
+ if (arg.c > 0xff) {
+ return INT2NUM(arg.c);
+ }
+ else if (arg.c >= 0) {
+ return keyboard_uint_chr(arg.c);
+ }
+ else {
+ return Qnil;
+ }
+#endif
+}
+
+#ifdef HAVE_PDC_GET_KEY_MODIFIERS
+static VALUE
+curses_get_key_modifiers(VALUE obj)
+{
+ return ULONG2NUM(PDC_get_key_modifiers());
+}
+
+static VALUE
+curses_return_key_modifiers(VALUE obj, VALUE flag)
+{
+ return INT2NUM(PDC_return_key_modifiers(RTEST(flag)));
+}
+
+static VALUE
+curses_save_key_modifiers(VALUE obj, VALUE flag)
+{
+ return INT2NUM(PDC_save_key_modifiers(RTEST(flag)));
+}
+#endif
+
/*------------------------- Initialization -------------------------*/
/*
@@ -2656,6 +3112,13 @@ pad_noutrefresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow,
void
Init_curses(void)
{
+#ifdef HAVE_GET_WCH
+ keyboard_encoding = rb_locale_encoding();
+#else
+ keyboard_encoding = rb_ascii8bit_encoding();
+#endif
+ terminal_encoding = rb_locale_encoding();
+
mCurses = rb_define_module("Curses");
/*
@@ -2700,6 +3163,7 @@ Init_curses(void)
rb_define_module_function(mCurses, "TABSIZE=", curses_tabsize_set, 1);
rb_define_module_function(mCurses, "use_default_colors", curses_use_default_colors, 0);
+ rb_define_module_function(mCurses, "assume_default_colors", curses_assume_default_colors, 2);
rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
rb_define_module_function(mCurses, "closed?", curses_closed, 0);
@@ -2707,6 +3171,7 @@ Init_curses(void)
rb_define_module_function(mCurses, "refresh", curses_refresh, 0);
rb_define_module_function(mCurses, "doupdate", curses_doupdate, 0);
rb_define_module_function(mCurses, "clear", curses_clear, 0);
+ rb_define_module_function(mCurses, "erase", curses_erase, 0);
rb_define_module_function(mCurses, "clrtoeol", curses_clrtoeol, 0);
rb_define_module_function(mCurses, "echo", curses_echo, 0);
rb_define_module_function(mCurses, "noecho", curses_noecho, 0);
@@ -2770,6 +3235,17 @@ Init_curses(void)
rb_define_module_function(mCurses, "timeout=", curses_timeout, 1);
rb_define_module_function(mCurses, "def_prog_mode", curses_def_prog_mode, 0);
rb_define_module_function(mCurses, "reset_prog_mode", curses_reset_prog_mode, 0);
+ rb_define_module_function(mCurses, "keyboard_encoding", curses_get_keyboard_encoding, 0);
+ rb_define_module_function(mCurses, "keyboard_encoding=", curses_set_keyboard_encoding, 1);
+ rb_define_module_function(mCurses, "terminal_encoding", curses_get_terminal_encoding, 0);
+ rb_define_module_function(mCurses, "terminal_encoding=", curses_set_terminal_encoding, 1);
+ rb_define_module_function(mCurses, "unget_char", curses_unget_char, 1);
+ rb_define_module_function(mCurses, "get_char", curses_get_char, 0);
+#ifdef HAVE_PDC_GET_KEY_MODIFIERS
+ rb_define_module_function(mCurses, "get_key_modifiers", curses_get_key_modifiers, 0);
+ rb_define_module_function(mCurses, "return_key_modifiers", curses_return_key_modifiers, 1);
+ rb_define_module_function(mCurses, "save_key_modifiers", curses_save_key_modifiers, 1);
+#endif
{
VALUE version;
@@ -2808,23 +3284,23 @@ Init_curses(void)
*
* == Usage
*
- * require 'curses'
+ * require "curses"
*
- * Curses.init_screen()
+ * Curses.init_screen
*
* my_str = "LOOK! PONIES!"
- * bwin = Curses::Window.new( 10, (my_str.length + 10),
- * (Curses.lines - 10) / 2,
- * (Curses.cols - (my_str.length + 10)) / 2 )
+ *
+ * height, width = 12, my_str.length + 10
+ * top, left = (Curses.lines - height) / 2, (Curses.cols - width) / 2
+ * bwin = Curses::Window.new(height, width, top, left)
* bwin.box("\\", "/")
* bwin.refresh
- * win = bwin.subwin( 6, my_str.length + 6,
- * (Curses.lines - 6) / 2,
- * (Curses.cols - (my_str.length + 6)) / 2 )
- * win.setpos(2,3)
+ *
+ * win = bwin.subwin(height - 4, width - 4, top + 2, left + 2)
+ * win.setpos(2, 3)
* win.addstr(my_str)
* # or even
- * win << "\nORLY"
+ * win << "\nOH REALLY?"
* win << "\nYES!! " + my_str
* win.refresh
* win.getch
@@ -2837,9 +3313,16 @@ Init_curses(void)
rb_define_method(cWindow, "subwin", window_subwin, 4);
rb_define_method(cWindow, "close", window_close, 0);
rb_define_method(cWindow, "clear", window_clear, 0);
+ rb_define_method(cWindow, "erase", window_erase, 0);
rb_define_method(cWindow, "clrtoeol", window_clrtoeol, 0);
rb_define_method(cWindow, "refresh", window_refresh, 0);
rb_define_method(cWindow, "noutrefresh", window_noutrefresh, 0);
+ rb_define_method(cWindow, "redraw", window_redraw, 0);
+ rb_define_method(cWindow, "touch", window_touch, 0);
+ rb_define_method(cWindow, "untouch", window_untouch, 0);
+ rb_define_method(cWindow, "touched?", window_touched, 0);
+ rb_define_method(cWindow, "touch_line", window_touch_line, -1);
+ rb_define_method(cWindow, "line_touched?", window_line_touched, 1);
rb_define_method(cWindow, "box", window_box, -1);
rb_define_method(cWindow, "move", window_move, 2);
rb_define_method(cWindow, "setpos", window_setpos, 2);
@@ -2883,6 +3366,8 @@ Init_curses(void)
rb_define_method(cWindow, "nodelay=", window_nodelay, 1);
rb_define_method(cWindow, "timeout=", window_timeout, 1);
+ rb_define_method(cWindow, "get_char", window_get_char, 0);
+
#ifdef HAVE_NEWPAD
/*
* Document-class: Curses::Pad
@@ -2903,7 +3388,7 @@ Init_curses(void)
rb_undef_method(cPad, "subwin");
#endif
-#define rb_curses_define_const(c) rb_define_const(mCurses,#c,UINT2NUM(c))
+#define rb_curses_define_const(c) rb_define_const(mCurses,#c,CHTYPE2NUM(c))
#ifdef USE_COLOR
/* Document-const: A_ATTRIBUTES
@@ -4326,7 +4811,48 @@ Init_curses(void)
rb_define_const(mCurses, name, INT2FIX(c - 'A' + 1));
}
}
+#ifdef PDC_KEY_MODIFIER_SHIFT
+ /* PDCurses-specific keys */
+ rb_curses_define_const(ALT_0);
+ rb_curses_define_const(ALT_1);
+ rb_curses_define_const(ALT_2);
+ rb_curses_define_const(ALT_3);
+ rb_curses_define_const(ALT_4);
+ rb_curses_define_const(ALT_5);
+ rb_curses_define_const(ALT_6);
+ rb_curses_define_const(ALT_7);
+ rb_curses_define_const(ALT_8);
+ rb_curses_define_const(ALT_9);
+ rb_curses_define_const(ALT_A);
+ rb_curses_define_const(ALT_B);
+ rb_curses_define_const(ALT_C);
+ rb_curses_define_const(ALT_D);
+ rb_curses_define_const(ALT_E);
+ rb_curses_define_const(ALT_F);
+ rb_curses_define_const(ALT_G);
+ rb_curses_define_const(ALT_H);
+ rb_curses_define_const(ALT_I);
+ rb_curses_define_const(ALT_J);
+ rb_curses_define_const(ALT_K);
+ rb_curses_define_const(ALT_L);
+ rb_curses_define_const(ALT_M);
+ rb_curses_define_const(ALT_N);
+ rb_curses_define_const(ALT_O);
+ rb_curses_define_const(ALT_P);
+ rb_curses_define_const(ALT_Q);
+ rb_curses_define_const(ALT_R);
+ rb_curses_define_const(ALT_S);
+ rb_curses_define_const(ALT_T);
+ rb_curses_define_const(ALT_U);
+ rb_curses_define_const(ALT_V);
+ rb_curses_define_const(ALT_W);
+ rb_curses_define_const(ALT_X);
+ rb_curses_define_const(ALT_Y);
+ rb_curses_define_const(ALT_Z);
+ rb_curses_define_const(PDC_KEY_MODIFIER_SHIFT);
+ rb_curses_define_const(PDC_KEY_MODIFIER_CONTROL);
+ rb_curses_define_const(PDC_KEY_MODIFIER_ALT);
+ rb_curses_define_const(PDC_KEY_MODIFIER_NUMLOCK);
+#endif
#undef rb_curses_define_const
-
- rb_set_end_proc(curses_finalize, 0);
}