Ruby 1.9.3p327(2012-11-10revision37606)
ext/curses/curses.c
Go to the documentation of this file.
00001 /* -*- C -*-
00002  * $Id: curses.c 32145 2011-06-17 04:10:37Z drbrain $
00003  *
00004  * ext/curses/curses.c
00005  *
00006  * by MAEDA Shugo (ender@pic-internet.or.jp)
00007  * modified by Yukihiro Matsumoto (matz@netlab.co.jp),
00008  *         Toki Yoshinori,
00009  *         Hitoshi Takahashi,
00010  *         and Takaaki Tateishi (ttate@kt.jaist.ac.jp)
00011  *
00012  * maintainers:
00013  * - Takaaki Tateishi (ttate@kt.jaist.ac.jp)
00014  *
00015  * doumentation:
00016  * - Vincent Batts (vbatts@hashbangbash.com)
00017  */
00018 
00019 #include "ruby.h"
00020 #include "ruby/io.h"
00021 
00022 #if defined(HAVE_NCURSES_H)
00023 # include <ncurses.h>
00024 #elif defined(HAVE_NCURSES_CURSES_H)
00025 # include <ncurses/curses.h>
00026 #elif defined(HAVE_CURSES_COLR_CURSES_H)
00027 # ifdef HAVE_STDARG_PROTOTYPES
00028 #  include <stdarg.h>
00029 # else
00030 #  include <varargs.h>
00031 # endif
00032 # include <curses_colr/curses.h>
00033 #else
00034 # include <curses.h>
00035 # if defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__)
00036 #  if !defined(_maxx)
00037 #  define _maxx maxx
00038 #  endif
00039 #  if !defined(_maxy)
00040 #  define _maxy maxy
00041 #  endif
00042 #  if !defined(_begx)
00043 #  define _begx begx
00044 #  endif
00045 #  if !defined(_begy)
00046 #  define _begy begy
00047 #  endif
00048 # endif
00049 #endif
00050 
00051 #ifdef HAVE_INIT_COLOR
00052 # define USE_COLOR 1
00053 #endif
00054 
00055 /* supports only ncurses mouse routines */
00056 #ifdef NCURSES_MOUSE_VERSION
00057 # define USE_MOUSE 1
00058 #endif
00059 
00060 #define NUM2CH NUM2CHR
00061 #define CH2FIX CHR2FIX
00062 
00063 static VALUE mCurses;
00064 static VALUE mKey;
00065 static VALUE cWindow;
00066 #ifdef USE_MOUSE
00067 static VALUE cMouseEvent;
00068 #endif
00069 
00070 static VALUE rb_stdscr;
00071 
00072 struct windata {
00073     WINDOW *window;
00074 };
00075 
00076 static VALUE window_attroff(VALUE obj, VALUE attrs);
00077 static VALUE window_attron(VALUE obj, VALUE attrs);
00078 static VALUE window_attrset(VALUE obj, VALUE attrs);
00079 
00080 static void
00081 no_window(void)
00082 {
00083     rb_raise(rb_eRuntimeError, "already closed window");
00084 }
00085 
00086 #define GetWINDOW(obj, winp) do {\
00087     if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
00088         rb_raise(rb_eSecurityError, "Insecure: operation on untainted window");\
00089     Data_Get_Struct((obj), struct windata, (winp));\
00090     if ((winp)->window == 0) no_window();\
00091 } while (0)
00092 
00093 static void
00094 free_window(struct windata *winp)
00095 {
00096     if (winp->window && winp->window != stdscr) delwin(winp->window);
00097     winp->window = 0;
00098     xfree(winp);
00099 }
00100 
00101 static VALUE
00102 prep_window(VALUE class, WINDOW *window)
00103 {
00104     VALUE obj;
00105     struct windata *winp;
00106 
00107     if (window == NULL) {
00108         rb_raise(rb_eRuntimeError, "failed to create window");
00109     }
00110 
00111     obj = rb_obj_alloc(class);
00112     Data_Get_Struct(obj, struct windata, winp);
00113     winp->window = window;
00114 
00115     return obj;
00116 }
00117 
00118 /*-------------------------- module Curses --------------------------*/
00119 
00120 /*
00121  * Document-method: Curses.init_screen
00122  *
00123  * Initialize a standard screen
00124  *
00125  * see also Curses.stdscr
00126  */
00127 static VALUE
00128 curses_init_screen(void)
00129 {
00130     rb_secure(4);
00131     if (rb_stdscr) return rb_stdscr;
00132     initscr();
00133     if (stdscr == 0) {
00134         rb_raise(rb_eRuntimeError, "can't initialize curses");
00135     }
00136     clear();
00137     rb_stdscr = prep_window(cWindow, stdscr);
00138     return rb_stdscr;
00139 }
00140 
00141 /*
00142  * Document-method: Curses.stdscr
00143  *
00144  * The Standard Screen.
00145  *
00146  * Upon initializing curses, a default window called stdscr,
00147  * which is the size of the terminal screen, is created.
00148  *
00149  * Many curses functions use this window.
00150  */
00151 #define curses_stdscr curses_init_screen
00152 
00153 /*
00154  * Document-method: Curses.close_screen
00155  *
00156  * A program should always call Curses.close_screen before exiting or
00157  * escaping from curses mode temporarily. This routine
00158  * restores tty modes, moves the cursor to the lower
00159  * left-hand corner of the screen and resets the terminal
00160  * into the proper non-visual mode.
00161  *
00162  * Calling Curses.refresh or Curses.doupdate after a temporary
00163  * escape causes the program to resume visual mode.
00164  *
00165  */
00166 static VALUE
00167 curses_close_screen(void)
00168 {
00169     curses_stdscr();
00170 #ifdef HAVE_ISENDWIN
00171     if (!isendwin())
00172 #endif
00173         endwin();
00174     rb_stdscr = 0;
00175     return Qnil;
00176 }
00177 
00178 /*
00179  * This is no runtime method,
00180  * but a function called before the proc ends
00181  *
00182  * Similar to Curses.close_screen, except that it also
00183  * garbage collects/unregisters the Curses.stdscr
00184  */
00185 static void
00186 curses_finalize(VALUE dummy)
00187 {
00188     if (stdscr
00189 #ifdef HAVE_ISENDWIN
00190         && !isendwin()
00191 #endif
00192         )
00193         endwin();
00194     rb_stdscr = 0;
00195     rb_gc_unregister_address(&rb_stdscr);
00196 }
00197 
00198 #ifdef HAVE_ISENDWIN
00199 /*
00200  * Document-method: Curses.closed?
00201  *
00202  * Returns +true+ if the window/screen has been closed,
00203  * without any subsequent Curses.refresh calls,
00204  * returns +false+ otherwise.
00205  */
00206 static VALUE
00207 curses_closed(void)
00208 {
00209     curses_stdscr();
00210     if (isendwin()) {
00211         return Qtrue;
00212     }
00213     return Qfalse;
00214 }
00215 #else
00216 #define curses_closed rb_f_notimplement
00217 #endif
00218 
00219 /*
00220  * Document-method: Curses.clear
00221  *
00222  * Clears every position on the screen completely,
00223  * so that a subsequent call by Curses.refresh for the screen/window
00224  * will be repainted from scratch.
00225  */
00226 static VALUE
00227 curses_clear(VALUE obj)
00228 {
00229     curses_stdscr();
00230     wclear(stdscr);
00231     return Qnil;
00232 }
00233 
00234 /*
00235  * Document-method: Curses.clrtoeol
00236  *
00237  * Clears to the end of line, that the cursor is currently on.
00238  */
00239 static VALUE
00240 curses_clrtoeol(void)
00241 {
00242     curses_stdscr();
00243     clrtoeol();
00244     return Qnil;
00245 }
00246 
00247 /*
00248  * Document-method: Curses.refresh
00249  *
00250  * Refreshes the windows and lines.
00251  *
00252  */
00253 static VALUE
00254 curses_refresh(VALUE obj)
00255 {
00256     curses_stdscr();
00257     refresh();
00258     return Qnil;
00259 }
00260 
00261 /*
00262  * Document-method: Curses.doupdate
00263  *
00264  * Refreshes the windows and lines.
00265  *
00266  * Curses.doupdate allows multiple updates with
00267  * more efficiency than Curses.refresh alone.
00268  */
00269 static VALUE
00270 curses_doupdate(VALUE obj)
00271 {
00272     curses_stdscr();
00273 #ifdef HAVE_DOUPDATE
00274     doupdate();
00275 #else
00276     refresh();
00277 #endif
00278     return Qnil;
00279 }
00280 
00281 /*
00282  * Document-method: Curses.echo
00283  *
00284  * Enables characters typed by the user
00285  * to be echoed by Curses.getch as they are typed.
00286  */
00287 static VALUE
00288 curses_echo(VALUE obj)
00289 {
00290     curses_stdscr();
00291     echo();
00292     return Qnil;
00293 }
00294 
00295 /*
00296  * Document-method: Curses.noecho
00297  *
00298  * Disables characters typed by the user
00299  * to be echoed by Curses.getch as they are typed.
00300  */
00301 static VALUE
00302 curses_noecho(VALUE obj)
00303 {
00304     curses_stdscr();
00305     noecho();
00306     return Qnil;
00307 }
00308 
00309 /*
00310  * Document-method: Curses.raw
00311  *
00312  * Put the terminal into raw mode.
00313  *
00314  * Raw mode is similar to Curses.cbreak mode, in that characters typed
00315  * are immediately passed through to the user program.
00316  *
00317  * The differences are that in raw mode, the interrupt, quit,
00318  * suspend, and flow control characters are all passed through
00319  * uninterpreted, instead of generating a signal. The behavior
00320  * of the BREAK key depends on other bits in the tty driver
00321  * that are not set by curses.
00322  */
00323 static VALUE
00324 curses_raw(VALUE obj)
00325 {
00326     curses_stdscr();
00327     raw();
00328     return Qnil;
00329 }
00330 
00331 /*
00332  * Document-method: Curses.noraw
00333  *
00334  * Put the terminal out of raw mode.
00335  *
00336  * see Curses.raw for more detail
00337  */
00338 static VALUE
00339 curses_noraw(VALUE obj)
00340 {
00341     curses_stdscr();
00342     noraw();
00343     return Qnil;
00344 }
00345 
00346 /*
00347  * Document-method: Curses.cbreak
00348  *
00349  * Put the terminal into cbreak mode.
00350  *
00351  * Normally, the tty driver buffers typed characters until
00352  * a newline or carriage return is typed. The Curses.cbreak
00353  * routine disables line buffering and erase/kill
00354  * character-processing (interrupt and flow control characters
00355  * are unaffected), making characters typed by the user
00356  * immediately available to the program.
00357  *
00358  * The Curses.nocbreak routine returns the terminal to normal (cooked) mode.
00359  *
00360  * Initially the terminal may or may not be in cbreak mode,
00361  * as the mode is inherited; therefore, a program should
00362  * call Curses.cbreak or Curses.nocbreak explicitly.
00363  * Most interactive programs using curses set the cbreak mode.
00364  * Note that Curses.cbreak overrides Curses.raw.
00365  *
00366  * see also Curses.raw
00367  */
00368 static VALUE
00369 curses_cbreak(VALUE obj)
00370 {
00371     curses_stdscr();
00372     cbreak();
00373     return Qnil;
00374 }
00375 
00376 /*
00377  * Document-method: Curses.nocbreak
00378  *
00379  * Put the terminal into normal mode (out of cbreak mode).
00380  *
00381  * See Curses.cbreak for more detail.
00382  */
00383 static VALUE
00384 curses_nocbreak(VALUE obj)
00385 {
00386     curses_stdscr();
00387     nocbreak();
00388     return Qnil;
00389 }
00390 
00391 /*
00392  * Document-method: Curses.nl
00393  *
00394  * Enable the underlying display device to translate
00395  * the return key into newline on input, and whether it
00396  * translates newline into return and line-feed on output
00397  * (in either case, the call Curses.addch('\n') does the
00398  * equivalent of return and line feed on the virtual screen).
00399  *
00400  * Initially, these translations do occur. If you disable
00401  * them using Curses.nonl, curses will be able to make better use
00402  * of the line-feed capability, resulting in faster cursor
00403  * motion. Also, curses will then be able to detect the return key.
00404  */
00405 static VALUE
00406 curses_nl(VALUE obj)
00407 {
00408     curses_stdscr();
00409     nl();
00410     return Qnil;
00411 }
00412 
00413 /*
00414  * Document-method: Curses.nl
00415  *
00416  * Disable the underlying display device to translate
00417  * the return key into newline on input
00418  *
00419  * See Curses.nl for more detail
00420  */
00421 static VALUE
00422 curses_nonl(VALUE obj)
00423 {
00424     curses_stdscr();
00425     nonl();
00426     return Qnil;
00427 }
00428 
00429 /*
00430  * Document-method: Curses.beep
00431  *
00432  * Sounds an audible alarm on the terminal, if possible;
00433  * otherwise it flashes the screen (visual bell).
00434  *
00435  * see also Curses.flash
00436  */
00437 static VALUE
00438 curses_beep(VALUE obj)
00439 {
00440 #ifdef HAVE_BEEP
00441     curses_stdscr();
00442     beep();
00443 #endif
00444     return Qnil;
00445 }
00446 
00447 /*
00448  * Document-method: Curses.flash
00449  *
00450  * Flashs the screen, for visual alarm on the terminal, if possible;
00451  * otherwise it sounds the alert.
00452  *
00453  * see also Curses.beep
00454  */
00455 static VALUE
00456 curses_flash(VALUE obj)
00457 {
00458 #ifdef HAVE_FLASH
00459     curses_stdscr();
00460     flash();
00461 #endif
00462     return Qnil;
00463 }
00464 
00465 static int
00466 curses_char(VALUE c)
00467 {
00468     if (FIXNUM_P(c)) {
00469         return NUM2INT(c);
00470     }
00471     else {
00472         int cc;
00473 
00474         StringValue(c);
00475         if (RSTRING_LEN(c) == 0 || RSTRING_LEN(c) > 1) {
00476             rb_raise(rb_eArgError, "string not corresponding a character");
00477         }
00478         cc = RSTRING_PTR(c)[0];
00479         if (cc > 0x7f) {
00480             rb_raise(rb_eArgError, "no multibyte string supported (yet)");
00481         }
00482         return cc;
00483     }
00484 }
00485 
00486 #ifdef HAVE_UNGETCH
00487 /*
00488  * Document-method: Curses.ungetch
00489  * call-seq: ungetch(ch)
00490  *
00491  * Places +ch+ back onto the input queue to be returned by
00492  * the next call to Curses.getch.
00493  *
00494  * There is just one input queue for all windows.
00495  */
00496 static VALUE
00497 curses_ungetch(VALUE obj, VALUE ch)
00498 {
00499     int c = curses_char(ch);
00500     curses_stdscr();
00501     ungetch(c);
00502     return Qnil;
00503 }
00504 #else
00505 #define curses_ungetch rb_f_notimplement
00506 #endif
00507 
00508 /*
00509  * Document-method: Curses.setpos
00510  * call-seq: setpos(y, x)
00511  *
00512  * A setter for the position of the cursor,
00513  * using coordinates +x+ and +y+
00514  *
00515  */
00516 static VALUE
00517 curses_setpos(VALUE obj, VALUE y, VALUE x)
00518 {
00519     curses_stdscr();
00520     move(NUM2INT(y), NUM2INT(x));
00521     return Qnil;
00522 }
00523 
00524 /*
00525  * Document-method: Curses.standout
00526  *
00527  * Enables the best highlighting mode of the terminal.
00528  *
00529  * This is equivalent to Curses:Window.attron(A_STANDOUT)
00530  *
00531  * see also Curses::Window.attrset additional information
00532  */
00533 static VALUE
00534 curses_standout(VALUE obj)
00535 {
00536     curses_stdscr();
00537     standout();
00538     return Qnil;
00539 }
00540 
00541 /*
00542  * Document-method: Curses.standend
00543  *
00544  * Enables the Normal display (no highlight)
00545  *
00546  * This is equivalent to Curses.attron(A_NORMAL)
00547  *
00548  * see also Curses::Window.attrset for additional information.
00549  */
00550 static VALUE
00551 curses_standend(VALUE obj)
00552 {
00553     curses_stdscr();
00554     standend();
00555     return Qnil;
00556 }
00557 
00558 /*
00559  * Document-method: Curses.inch
00560  *
00561  * Returns the character at the current position.
00562  */
00563 static VALUE
00564 curses_inch(VALUE obj)
00565 {
00566     curses_stdscr();
00567     return CH2FIX(inch());
00568 }
00569 
00570 /*
00571  * Document-method: Curses.addch
00572  * call-seq: addch(ch)
00573  *
00574  * Add a character +ch+, with attributes, then advance the cursor.
00575  *
00576  * see also the system manual for curs_addch(3)
00577  */
00578 static VALUE
00579 curses_addch(VALUE obj, VALUE ch)
00580 {
00581     curses_stdscr();
00582     addch(NUM2CH(ch));
00583     return Qnil;
00584 }
00585 
00586 /*
00587  * Document-method: Curses.insch
00588  * call-seq: insch(ch)
00589  *
00590  * Insert a character +ch+, before the cursor.
00591  *
00592  */
00593 static VALUE
00594 curses_insch(VALUE obj, VALUE ch)
00595 {
00596     curses_stdscr();
00597     insch(NUM2CH(ch));
00598     return Qnil;
00599 }
00600 
00601 /*
00602  * Document-method: Curses.addstr
00603  * call-seq: addstr(str)
00604  *
00605  * add a string of characters +str+, to the window and advance cursor
00606  *
00607  */
00608 static VALUE
00609 curses_addstr(VALUE obj, VALUE str)
00610 {
00611     StringValue(str);
00612     str = rb_str_export_locale(str);
00613     curses_stdscr();
00614     if (!NIL_P(str)) {
00615         addstr(StringValueCStr(str));
00616     }
00617     return Qnil;
00618 }
00619 
00620 static VALUE
00621 getch_func(void *arg)
00622 {
00623     int *ip = (int *)arg;
00624     *ip = getch();
00625     return Qnil;
00626 }
00627 
00628 /*
00629  * Document-method: Curses.getch
00630  *
00631  * Read and returns a character from the window.
00632  *
00633  * See Curses::Key to all the function KEY_* available
00634  *
00635  */
00636 static VALUE
00637 curses_getch(VALUE obj)
00638 {
00639     int c;
00640 
00641     curses_stdscr();
00642     rb_thread_blocking_region(getch_func, (void *)&c, RUBY_UBF_IO, 0);
00643     if (c == EOF) return Qnil;
00644     if (rb_isprint(c)) {
00645         char ch = (char)c;
00646 
00647         return rb_locale_str_new(&ch, 1);
00648     }
00649     return UINT2NUM(c);
00650 }
00651 
00652 /* This should be big enough.. I hope */
00653 #define GETSTR_BUF_SIZE 1024
00654 
00655 static VALUE
00656 getstr_func(void *arg)
00657 {
00658     char *rtn = (char *)arg;
00659 #if defined(HAVE_GETNSTR)
00660     getnstr(rtn,GETSTR_BUF_SIZE-1);
00661 #else
00662     getstr(rtn);
00663 #endif
00664     return Qnil;
00665 }
00666 
00667 /*
00668  * Document-method: Curses.getstr
00669  *
00670  * This is equivalent to a series f Curses::Window.getch calls
00671  *
00672  */
00673 static VALUE
00674 curses_getstr(VALUE obj)
00675 {
00676     char rtn[GETSTR_BUF_SIZE];
00677 
00678     curses_stdscr();
00679     rb_thread_blocking_region(getstr_func, (void *)rtn, RUBY_UBF_IO, 0);
00680     return rb_locale_str_new_cstr(rtn);
00681 }
00682 
00683 /*
00684  * Document-method: Curses.delch
00685  *
00686  * Delete the character under the cursor
00687  *
00688  */
00689 static VALUE
00690 curses_delch(VALUE obj)
00691 {
00692     curses_stdscr();
00693     delch();
00694     return Qnil;
00695 }
00696 
00697 /*
00698  * Document-method: Curses.deleteln
00699  *
00700  * Delete the line under the cursor.
00701  *
00702  */
00703 static VALUE
00704 curses_deleteln(VALUE obj)
00705 {
00706     curses_stdscr();
00707 #if defined(HAVE_DELETELN) || defined(deleteln)
00708     deleteln();
00709 #endif
00710     return Qnil;
00711 }
00712 
00713 /*
00714  * Document-method: Curses.insertln
00715  *
00716  * Inserts a line above the cursor, and the bottom line is lost
00717  *
00718  */
00719 static VALUE
00720 curses_insertln(VALUE obj)
00721 {
00722     curses_stdscr();
00723 #if defined(HAVE_INSERTLN) || defined(insertln)
00724     insertln();
00725 #endif
00726     return Qnil;
00727 }
00728 
00729 /*
00730  * Document-method: Curses.keyname
00731  * call-seq: keyname(c)
00732  *
00733  * Returns the character string corresponding to key +c+
00734  */
00735 static VALUE
00736 curses_keyname(VALUE obj, VALUE c)
00737 {
00738 #ifdef HAVE_KEYNAME
00739     int cc = curses_char(c);
00740     const char *name;
00741 
00742     curses_stdscr();
00743     name = keyname(cc);
00744     if (name) {
00745         return rb_str_new_cstr(name);
00746     }
00747     else {
00748         return Qnil;
00749     }
00750 #else
00751     return Qnil;
00752 #endif
00753 }
00754 
00755 /*
00756  * Document-method: Curses.lines
00757  *
00758  * Returns the number of lines on the screen
00759  */
00760 static VALUE
00761 curses_lines(void)
00762 {
00763     return INT2FIX(LINES);
00764 }
00765 
00766 /*
00767  * Document-method: Curses.cols
00768  *
00769  * Returns the number of columns on the screen
00770  */
00771 static VALUE
00772 curses_cols(void)
00773 {
00774     return INT2FIX(COLS);
00775 }
00776 
00777 /*
00778  * Document-method: Curses.curs_set
00779  * call-seq: curs_set(visibility)
00780  *
00781  * Sets Cursor Visibility.
00782  * 0: invisible
00783  * 1: visible
00784  * 2: very visible
00785  */
00786 static VALUE
00787 curses_curs_set(VALUE obj, VALUE visibility)
00788 {
00789 #ifdef HAVE_CURS_SET
00790     int n;
00791     curses_stdscr();
00792     return (n = curs_set(NUM2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil;
00793 #else
00794     return Qnil;
00795 #endif
00796 }
00797 
00798 /*
00799  * Document-method: Curses.scrl
00800  * call-seq: scrl(num)
00801  *
00802  * Scrolls the current window Fixnum +num+ lines.
00803  * The current cursor position is not changed.
00804  *
00805  * For positive +num+, it scrolls up.
00806  *
00807  * For negative +num+, it scrolls down.
00808  *
00809  */
00810 static VALUE
00811 curses_scrl(VALUE obj, VALUE n)
00812 {
00813     /* may have to raise exception on ERR */
00814 #ifdef HAVE_SCRL
00815     curses_stdscr();
00816     return (scrl(NUM2INT(n)) == OK) ? Qtrue : Qfalse;
00817 #else
00818     return Qfalse;
00819 #endif
00820 }
00821 
00822 /*
00823  * Document-method: Curses.setscrreg
00824  *
00825  * call-seq:
00826  *   setscrreg(top, bottom)
00827  *
00828  * Set a software scrolling region in a window.
00829  * +top+ and +bottom+ are lines numbers of the margin.
00830  *
00831  * If this option and Curses.scrollok are enabled, an attempt to move off
00832  * the bottom margin line causes all lines in the scrolling region
00833  * to scroll one line in the direction of the first line.
00834  * Only the text of the window is scrolled.
00835  *
00836  */
00837 static VALUE
00838 curses_setscrreg(VALUE obj, VALUE top, VALUE bottom)
00839 {
00840     /* may have to raise exception on ERR */
00841 #ifdef HAVE_SETSCRREG
00842     curses_stdscr();
00843     return (setscrreg(NUM2INT(top), NUM2INT(bottom)) == OK) ? Qtrue : Qfalse;
00844 #else
00845     return Qfalse;
00846 #endif
00847 }
00848 
00849 /*
00850  * Document-method: Curses.attroff
00851  * call-seq: attroff(attrs)
00852  *
00853  * Turns on the named attributes +attrs+ without affecting any others.
00854  *
00855  * See also Curses::Window.attrset for additional information.
00856  */
00857 static VALUE
00858 curses_attroff(VALUE obj, VALUE attrs)
00859 {
00860     curses_stdscr();
00861     return window_attroff(rb_stdscr,attrs);
00862     /* return INT2FIX(attroff(NUM2INT(attrs))); */
00863 }
00864 
00865 /*
00866  * Document-method: Curses.attron
00867  * call-seq: attron(attrs)
00868  *
00869  * Turns off the named attributes +attrs+
00870  * without turning any other attributes on or off.
00871  *
00872  * See also Curses::Window.attrset for additional information.
00873  */
00874 static VALUE
00875 curses_attron(VALUE obj, VALUE attrs)
00876 {
00877     curses_stdscr();
00878     return window_attron(rb_stdscr,attrs);
00879     /* return INT2FIX(attroff(NUM2INT(attrs))); */
00880 }
00881 
00882 /*
00883  * Document-method: Curses.attrset
00884  * call-seq: attrset(attrs)
00885  *
00886  * Sets the current attributes of the given window to +attrs+.
00887  *
00888  * see also Curses::Window.attrset
00889  *
00890  */
00891 static VALUE
00892 curses_attrset(VALUE obj, VALUE attrs)
00893 {
00894     curses_stdscr();
00895     return window_attrset(rb_stdscr,attrs);
00896     /* return INT2FIX(attroff(NUM2INT(attrs))); */
00897 }
00898 
00899 /*
00900  * Document-method: Curses.bkgdset
00901  * call-seq: bkgdset(ch)
00902  *
00903  * Manipulate the background of the named window
00904  * with character Integer +ch+
00905  *
00906  * The background becomes a property of the character
00907  * and moves with the character through any scrolling
00908  * and insert/delete line/character operations.
00909  *
00910  * see also the system manual for curs_bkgd(3)
00911  */
00912 static VALUE
00913 curses_bkgdset(VALUE obj, VALUE ch)
00914 {
00915 #ifdef HAVE_BKGDSET
00916     curses_stdscr();
00917     bkgdset(NUM2CH(ch));
00918 #endif
00919     return Qnil;
00920 }
00921 
00922 /*
00923  * call-seq: bkgd(ch)
00924  *
00925  * Window background manipulation routines.
00926  *
00927  * Set the background property of the current
00928  * and then apply the character Integer +ch+ setting
00929  * to every character position in that window.
00930  *
00931  * see also the system manual for curs_bkgd(3)
00932  */
00933 static VALUE
00934 curses_bkgd(VALUE obj, VALUE ch)
00935 {
00936 #ifdef HAVE_BKGD
00937     curses_stdscr();
00938     return (bkgd(NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
00939 #else
00940     return Qfalse;
00941 #endif
00942 }
00943 
00944 #if defined(HAVE_USE_DEFAULT_COLORS)
00945 /*
00946  * tells the curses library to use terminal's default colors.
00947  *
00948  * see also the system manual for default_colors(3)
00949  */
00950 static VALUE
00951 curses_use_default_colors(VALUE obj)
00952 {
00953     curses_stdscr();
00954     use_default_colors();
00955     return Qnil;
00956 }
00957 #else
00958 #define curses_use_default_colors rb_f_notimplement
00959 #endif
00960 
00961 #if defined(HAVE_TABSIZE)
00962 /*
00963  * Document-method: Curses.TABSIZE=
00964  * call-seq: TABSIZE=(value)
00965  *
00966  * Sets the TABSIZE to Integer +value+
00967  */
00968 static VALUE
00969 curses_tabsize_set(VALUE obj, VALUE val)
00970 {
00971     TABSIZE = NUM2INT(val);
00972     return INT2NUM(TABSIZE);
00973 }
00974 #else
00975 #define curses_tabsize_set rb_f_notimplement
00976 #endif
00977 
00978 #if defined(HAVE_TABSIZE)
00979 /*
00980  * Returns the number of positions in a tab.
00981  */
00982 static VALUE
00983 curses_tabsize_get(VALUE ojb)
00984 {
00985     return INT2NUM(TABSIZE);
00986 }
00987 #else
00988 #define curses_tabsize_get rb_f_notimplement
00989 #endif
00990 
00991 #if defined(HAVE_ESCDELAY)
00992 /*
00993  * call-seq: Curses.ESCDELAY=(value)
00994  *
00995  * Sets the ESCDELAY to Integer +value+
00996  */
00997 static VALUE
00998 curses_escdelay_set(VALUE obj, VALUE val)
00999 {
01000     ESCDELAY = NUM2INT(val);
01001     return INT2NUM(ESCDELAY);
01002 }
01003 #else
01004 #define curses_escdelay_set rb_f_notimplement
01005 #endif
01006 
01007 #if defined(HAVE_ESCDELAY)
01008 /*
01009  * Returns the total time, in milliseconds, for which
01010  * curses will await a character sequence, e.g., a function key
01011  */
01012 static VALUE
01013 curses_escdelay_get(VALUE obj)
01014 {
01015     return INT2NUM(ESCDELAY);
01016 }
01017 #else
01018 #define curses_escdelay_get rb_f_notimplement
01019 #endif
01020 
01021 /*
01022  * Document-method: Curses.resize
01023  * call-seq: resize(lines, cols)
01024  *
01025  * alias for Curses.resizeterm
01026  *
01027  */
01028 
01029 /*
01030  * Document-method: Curses.resizeterm
01031  * call-seq: resizeterm(lines, cols)
01032  *
01033  * Resize the current term to Fixnum +lines+ and Fixnum +cols+
01034  *
01035  */
01036 static VALUE
01037 curses_resizeterm(VALUE obj, VALUE lin, VALUE col)
01038 {
01039 #if defined(HAVE_RESIZETERM)
01040     curses_stdscr();
01041     return (resizeterm(NUM2INT(lin),NUM2INT(col)) == OK) ? Qtrue : Qfalse;
01042 #else
01043     return Qnil;
01044 #endif
01045 }
01046 
01047 #ifdef USE_COLOR
01048 /*
01049  * Document-method: Curses.start_color
01050  *
01051  * Initializes the color attributes, for terminals that support it.
01052  *
01053  * This must be called, in order to use color attributes.
01054  * It is good practice to call it just after Curses.init_screen
01055  */
01056 static VALUE
01057 curses_start_color(VALUE obj)
01058 {
01059     /* may have to raise exception on ERR */
01060     curses_stdscr();
01061     return (start_color() == OK) ? Qtrue : Qfalse;
01062 }
01063 
01064 /*
01065  * Document-method: Curses.init_pair
01066  * call-seq: init_pair(pair, f, b)
01067  *
01068  * Changes the definition of a color-pair.
01069  *
01070  * It takes three arguments: the number of the color-pair to be changed +pair+,
01071  * the foreground color number +f+, and the background color number +b+.
01072  *
01073  * If the color-pair was previously initialized, the screen is
01074  * refreshed and all occurrences of that color-pair are changed
01075  * to the new definition.
01076  *
01077  */
01078 static VALUE
01079 curses_init_pair(VALUE obj, VALUE pair, VALUE f, VALUE b)
01080 {
01081     /* may have to raise exception on ERR */
01082     curses_stdscr();
01083     return (init_pair(NUM2INT(pair),NUM2INT(f),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
01084 }
01085 
01086 /*
01087  * Document-method: Curses.init_color
01088  * call-seq: init_color(color, r, g, b)
01089  *
01090  * Changes the definition of a color. It takes four arguments:
01091  * * the number of the color to be changed, +color+
01092  * * the amount of red, +r+
01093  * * the amount of green, +g+
01094  * * the amount of blue, +b+
01095  *
01096  * The value of the first argument must be between 0 and  COLORS.
01097  * (See the section Colors for the default color index.)  Each
01098  * of the last three arguments must be a value between 0 and 1000.
01099  * When Curses.init_color is used, all occurrences of that color
01100  * on the screen immediately change to the new definition.
01101  */
01102 static VALUE
01103 curses_init_color(VALUE obj, VALUE color, VALUE r, VALUE g, VALUE b)
01104 {
01105     /* may have to raise exception on ERR */
01106     curses_stdscr();
01107     return (init_color(NUM2INT(color),NUM2INT(r),
01108                        NUM2INT(g),NUM2INT(b)) == OK) ? Qtrue : Qfalse;
01109 }
01110 
01111 /*
01112  * Document-method: Curses.has_colors?
01113  *
01114  * Returns +true+ or +false+ depending on whether the terminal has color capbilities.
01115  */
01116 static VALUE
01117 curses_has_colors(VALUE obj)
01118 {
01119     curses_stdscr();
01120     return has_colors() ? Qtrue : Qfalse;
01121 }
01122 
01123 /*
01124  * Document-method: Curses.can_change_color?
01125  *
01126  * Returns +true+ or +false+ depending on whether the terminal can change color attributes
01127  */
01128 static VALUE
01129 curses_can_change_color(VALUE obj)
01130 {
01131     curses_stdscr();
01132     return can_change_color() ? Qtrue : Qfalse;
01133 }
01134 
01135 #if defined(HAVE_COLORS)
01136 /*
01137  * Document-method: Curses.color
01138  *
01139  * returns COLORS
01140  */
01141 static VALUE
01142 curses_colors(VALUE obj)
01143 {
01144     return INT2FIX(COLORS);
01145 }
01146 #else
01147 #define curses_colors rb_f_notimplement
01148 #endif
01149 
01150 /*
01151  * Document-method: Curses.color_content
01152  * call-seq: color_content(color)
01153  *
01154  * Returns an 3 item Array of the RGB values in +color+
01155  */
01156 static VALUE
01157 curses_color_content(VALUE obj, VALUE color)
01158 {
01159     short r,g,b;
01160 
01161     curses_stdscr();
01162     color_content(NUM2INT(color),&r,&g,&b);
01163     return rb_ary_new3(3,INT2FIX(r),INT2FIX(g),INT2FIX(b));
01164 }
01165 
01166 
01167 #if defined(HAVE_COLOR_PAIRS)
01168 /*
01169  * Document-method: Curses.color_pairs
01170  *
01171  * Returns the COLOR_PAIRS available, if the curses library supports it.
01172  */
01173 static VALUE
01174 curses_color_pairs(VALUE obj)
01175 {
01176     return INT2FIX(COLOR_PAIRS);
01177 }
01178 #else
01179 #define curses_color_pairs rb_f_notimplement
01180 #endif
01181 
01182 /*
01183  * Document-method: Curses.pair_content
01184  * call-seq: pair_content(pair)
01185  *
01186  * Returns a 2 item Array, with the foreground and
01187  * background color, in +pair+
01188  */
01189 static VALUE
01190 curses_pair_content(VALUE obj, VALUE pair)
01191 {
01192     short f,b;
01193 
01194     curses_stdscr();
01195     pair_content(NUM2INT(pair),&f,&b);
01196     return rb_ary_new3(2,INT2FIX(f),INT2FIX(b));
01197 }
01198 
01199 /*
01200  * Document-method: Curses.color_pair
01201  * call-seq: color_pair(attrs)
01202  *
01203  * Sets the color pair attributes to +attrs+.
01204  *
01205  * This should be equivalent to Curses.attrset(COLOR_PAIR(+attrs+))
01206  *
01207  * TODO: validate that equivalency
01208  */
01209 static VALUE
01210 curses_color_pair(VALUE obj, VALUE attrs)
01211 {
01212     return INT2FIX(COLOR_PAIR(NUM2INT(attrs)));
01213 }
01214 
01215 /*
01216  * Document-method: Curses.pair_number
01217  * call-seq: pair_number(attrs)
01218  *
01219  * Returns the Fixnum color pair number of attributes +attrs+.
01220  */
01221 static VALUE
01222 curses_pair_number(VALUE obj, VALUE attrs)
01223 {
01224     curses_stdscr();
01225     return INT2FIX(PAIR_NUMBER(NUM2INT(attrs)));
01226 }
01227 #endif /* USE_COLOR */
01228 
01229 #ifdef USE_MOUSE
01230 struct mousedata {
01231     MEVENT *mevent;
01232 };
01233 
01234 static void
01235 no_mevent(void)
01236 {
01237     rb_raise(rb_eRuntimeError, "no such mouse event");
01238 }
01239 
01240 #define GetMOUSE(obj, data) do {\
01241     if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
01242         rb_raise(rb_eSecurityError, "Insecure: operation on untainted mouse");\
01243     Data_Get_Struct((obj), struct mousedata, (data));\
01244     if ((data)->mevent == 0) no_mevent();\
01245 } while (0)
01246 
01247 static void
01248 curses_mousedata_free(struct mousedata *mdata)
01249 {
01250     if (mdata->mevent)
01251         xfree(mdata->mevent);
01252 }
01253 
01254 /*
01255  * Document-method: Curses.getmouse
01256  *
01257  * Returns coordinates of the mouse.
01258  *
01259  * This will read and pop the mouse event data off the queue
01260  *
01261  * See the BUTTON*, ALL_MOUSE_EVENTS and REPORT_MOUSE_POSITION constants, to examine the mask of the event
01262  */
01263 static VALUE
01264 curses_getmouse(VALUE obj)
01265 {
01266     struct mousedata *mdata;
01267     VALUE val;
01268 
01269     curses_stdscr();
01270     val = Data_Make_Struct(cMouseEvent,struct mousedata,
01271                            0,curses_mousedata_free,mdata);
01272     mdata->mevent = (MEVENT*)xmalloc(sizeof(MEVENT));
01273     return (getmouse(mdata->mevent) == OK) ? val : Qnil;
01274 }
01275 
01276 /*
01277  * Document-method: Curses.ungetmouse
01278  *
01279  * It pushes a KEY_MOUSE event onto the input queue, and associates with that
01280  * event the given state data and screen-relative character-cell coordinates.
01281  *
01282  * The Curses.ungetmouse function behaves analogously to Curses.ungetch.
01283  */
01284 static VALUE
01285 curses_ungetmouse(VALUE obj, VALUE mevent)
01286 {
01287     struct mousedata *mdata;
01288 
01289     curses_stdscr();
01290     GetMOUSE(mevent,mdata);
01291     return (ungetmouse(mdata->mevent) == OK) ? Qtrue : Qfalse;
01292 }
01293 
01294 /*
01295  * Document-method: Curses.mouseinterval
01296  * call-seq: mouseinterval(interval)
01297  *
01298  * The Curses.mouseinterval function sets the maximum time
01299  * (in thousands of a second) that can elapse between press
01300  * and release events for them to be recognized as a click.
01301  *
01302  * Use Curses.mouseinterval(0) to disable click resolution.
01303  * This function returns the previous interval value.
01304  *
01305  * Use Curses.mouseinterval(-1) to obtain the interval without
01306  * altering it.
01307  *
01308  * The default is one sixth of a second.
01309  */
01310 static VALUE
01311 curses_mouseinterval(VALUE obj, VALUE interval)
01312 {
01313     curses_stdscr();
01314     return mouseinterval(NUM2INT(interval)) ? Qtrue : Qfalse;
01315 }
01316 
01317 /*
01318  * Document-method: Curses.mousemask
01319  * call-seq: mousemask(mask)
01320  *
01321  * Returns the +mask+ of the reportable events
01322  */
01323 static VALUE
01324 curses_mousemask(VALUE obj, VALUE mask)
01325 {
01326     curses_stdscr();
01327     return INT2NUM(mousemask(NUM2UINT(mask),NULL));
01328 }
01329 
01330 #define DEFINE_MOUSE_GET_MEMBER(func_name,mem) \
01331 static VALUE func_name (VALUE mouse) \
01332 { \
01333     struct mousedata *mdata; \
01334     GetMOUSE(mouse, mdata); \
01335     return (UINT2NUM(mdata->mevent -> mem)); \
01336 }
01337 
01338 /*
01339  * Document-method: Curses::MouseEvent.eid
01340  *
01341  * Returns the current mouse id
01342  */
01343 DEFINE_MOUSE_GET_MEMBER(curs_mouse_id, id)
01344 /*
01345  * Document-method: Curses::MouseEvent.x
01346  *
01347  * Returns the current mouse's X coordinate
01348  */
01349 DEFINE_MOUSE_GET_MEMBER(curs_mouse_x, x)
01350 /*
01351  * Document-method: Curses::MouseEvent.y
01352  *
01353  * Returns the current mouse's Y coordinate
01354  */
01355 DEFINE_MOUSE_GET_MEMBER(curs_mouse_y, y)
01356 /*
01357  * Document-method: Curses::MouseEvent.z
01358  *
01359  * Returns the current mouse's Z coordinate
01360  */
01361 DEFINE_MOUSE_GET_MEMBER(curs_mouse_z, z)
01362 /*
01363  * Document-method: Curses::MouseEvent.bstate
01364  *
01365  * Returns the current mouse's button state.  Use this with the button state
01366  * constants to determine which buttons were pressed.
01367  */
01368 DEFINE_MOUSE_GET_MEMBER(curs_mouse_bstate, bstate)
01369 #undef define_curs_mouse_member
01370 #endif /* USE_MOUSE */
01371 
01372 #ifdef HAVE_TIMEOUT
01373 /*
01374  * Document-method: Curses.timeout=
01375  * call-seq: timeout=(delay)
01376  *
01377  * Sets block and non-blocking reads for the window.
01378  * - If delay is negative, blocking read is used (i.e., waits indefinitely for input).
01379  * - If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting).
01380  * - If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input.
01381  *
01382  */
01383 static VALUE
01384 curses_timeout(VALUE obj, VALUE delay)
01385 {
01386     curses_stdscr();
01387     timeout(NUM2INT(delay));
01388     return Qnil;
01389 }
01390 #else
01391 #define curses_timeout rb_f_notimplement
01392 #endif
01393 
01394 #ifdef HAVE_DEF_PROG_MODE
01395 /*
01396  * Document-method: Curses.def_prog_mode
01397  *
01398  * Save the current terminal modes as the "program"
01399  * state for use by the Curses.reset_prog_mode
01400  *
01401  * This is done automatically by Curses.init_screen
01402  */
01403 static VALUE
01404 curses_def_prog_mode(VALUE obj)
01405 {
01406     curses_stdscr();
01407     return def_prog_mode() == OK ? Qtrue : Qfalse;
01408 }
01409 #else
01410 #define curses_def_prog_mode rb_f_notimplement
01411 #endif
01412 
01413 #ifdef HAVE_RESET_PROG_MODE
01414 /*
01415  * Document-method: Curses.reset_prog_mode
01416  *
01417  * Reset the current terminal modes to the saved state
01418  * by the Curses.def_prog_mode
01419  *
01420  * This is done automatically by Curses.close_screen
01421  */
01422 static VALUE
01423 curses_reset_prog_mode(VALUE obj)
01424 {
01425     curses_stdscr();
01426     return reset_prog_mode() == OK ? Qtrue : Qfalse;
01427 }
01428 #else
01429 #define curses_reset_prog_mode rb_f_notimplement
01430 #endif
01431 
01432 /*-------------------------- class Window --------------------------*/
01433 
01434 /* returns a Curses::Window object */
01435 static VALUE
01436 window_s_allocate(VALUE class)
01437 {
01438     struct windata *winp;
01439 
01440     return Data_Make_Struct(class, struct windata, 0, free_window, winp);
01441 }
01442 
01443 /*
01444  * Document-method: Curses::Window.new
01445  * call-seq: new(height, width, top, left)
01446  *
01447  * Contruct a new Curses::Window with constraints of
01448  * +height+ lines, +width+ columns, begin at +top+ line, and begin +left+ most column.
01449  *
01450  * A new window using full screen is called as
01451  *      Curses::Window.new(0,0,0,0)
01452  *
01453  */
01454 static VALUE
01455 window_initialize(VALUE obj, VALUE h, VALUE w, VALUE top, VALUE left)
01456 {
01457     struct windata *winp;
01458     WINDOW *window;
01459 
01460     rb_secure(4);
01461     curses_init_screen();
01462     Data_Get_Struct(obj, struct windata, winp);
01463     if (winp->window) delwin(winp->window);
01464     window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left));
01465     wclear(window);
01466     winp->window = window;
01467 
01468     return obj;
01469 }
01470 
01471 /*
01472  * Document-method: Curses::Window.subwin
01473  * call-seq: subwin(height, width, top, left)
01474  *
01475  * Contruct a new subwindow with constraints of
01476  * +height+ lines, +width+ columns, begin at +top+ line, and begin +left+ most column.
01477  *
01478  */
01479 static VALUE
01480 window_subwin(VALUE obj, VALUE height, VALUE width, VALUE top, VALUE left)
01481 {
01482     struct windata *winp;
01483     WINDOW *window;
01484     VALUE win;
01485     int h, w, t, l;
01486 
01487     h = NUM2INT(height);
01488     w = NUM2INT(width);
01489     t = NUM2INT(top);
01490     l = NUM2INT(left);
01491     GetWINDOW(obj, winp);
01492     window = subwin(winp->window, h, w, t, l);
01493     win = prep_window(rb_obj_class(obj), window);
01494 
01495     return win;
01496 }
01497 
01498 /*
01499  * Document-method: Curses::Window.close
01500  *
01501  * Deletes the window, and frees the memory
01502  */
01503 static VALUE
01504 window_close(VALUE obj)
01505 {
01506     struct windata *winp;
01507 
01508     GetWINDOW(obj, winp);
01509     delwin(winp->window);
01510     winp->window = 0;
01511 
01512     return Qnil;
01513 }
01514 
01515 /*
01516  * Document-method: Curses::Window.clear
01517  *
01518  * Clear the window.
01519  */
01520 static VALUE
01521 window_clear(VALUE obj)
01522 {
01523     struct windata *winp;
01524 
01525     GetWINDOW(obj, winp);
01526     wclear(winp->window);
01527 
01528     return Qnil;
01529 }
01530 
01531 /*
01532  * Document-method: Curses::Window.clrtoeol
01533  *
01534  * Clear the window to the end of line, that the cursor is currently on.
01535  */
01536 static VALUE
01537 window_clrtoeol(VALUE obj)
01538 {
01539     struct windata *winp;
01540 
01541     GetWINDOW(obj, winp);
01542     wclrtoeol(winp->window);
01543 
01544     return Qnil;
01545 }
01546 
01547 /*
01548  * Document-method: Curses::Window.refresh
01549  *
01550  * Refreshes the windows and lines.
01551  *
01552  */
01553 static VALUE
01554 window_refresh(VALUE obj)
01555 {
01556     struct windata *winp;
01557 
01558     GetWINDOW(obj, winp);
01559     wrefresh(winp->window);
01560 
01561     return Qnil;
01562 }
01563 
01564 /*
01565  * Document-method: Curses::Window.noutrefresh
01566  *
01567  * Refreshes the windows and lines.
01568  *
01569  * Curses::Window.noutrefresh allows multiple updates with
01570  * more efficiency than Curses::Window.refresh alone.
01571  */
01572 static VALUE
01573 window_noutrefresh(VALUE obj)
01574 {
01575     struct windata *winp;
01576 
01577     GetWINDOW(obj, winp);
01578 #ifdef HAVE_DOUPDATE
01579     wnoutrefresh(winp->window);
01580 #else
01581     wrefresh(winp->window);
01582 #endif
01583 
01584     return Qnil;
01585 }
01586 
01587 /*
01588  * Document-method: Curses::Window.move
01589  * call-seq: move(y,x)
01590  *
01591  * Moves the window so that the upper left-hand corner is at position (+y+, +x+)
01592  */
01593 static VALUE
01594 window_move(VALUE obj, VALUE y, VALUE x)
01595 {
01596     struct windata *winp;
01597 
01598     GetWINDOW(obj, winp);
01599     mvwin(winp->window, NUM2INT(y), NUM2INT(x));
01600 
01601     return Qnil;
01602 }
01603 
01604 /*
01605  * Document-method: Curses::Window.setpos
01606  * call-seq: setpos(y, x)
01607  *
01608  * A setter for the position of the cursor
01609  * in the current window,
01610  * using coordinates +x+ and +y+
01611  *
01612  */
01613 static VALUE
01614 window_setpos(VALUE obj, VALUE y, VALUE x)
01615 {
01616     struct windata *winp;
01617 
01618     GetWINDOW(obj, winp);
01619     wmove(winp->window, NUM2INT(y), NUM2INT(x));
01620     return Qnil;
01621 }
01622 
01623 /*
01624  * Document-method: Curses::Window.cury
01625  *
01626  * A getter for the current line (Y coord) of the window
01627  */
01628 static VALUE
01629 window_cury(VALUE obj)
01630 {
01631     struct windata *winp;
01632     int x, y;
01633 
01634     GetWINDOW(obj, winp);
01635     getyx(winp->window, y, x);
01636     return INT2FIX(y);
01637 }
01638 
01639 /*
01640  * Document-method: Curses::Window.curx
01641  *
01642  * A getter for the current column (X coord) of the window
01643  */
01644 static VALUE
01645 window_curx(VALUE obj)
01646 {
01647     struct windata *winp;
01648     int x, y;
01649 
01650     GetWINDOW(obj, winp);
01651     getyx(winp->window, y, x);
01652     return INT2FIX(x);
01653 }
01654 
01655 /*
01656  * Document-method: Curses::Window.maxy
01657  *
01658  * A getter for the maximum lines for the window
01659  */
01660 static VALUE
01661 window_maxy(VALUE obj)
01662 {
01663     struct windata *winp;
01664 
01665     GetWINDOW(obj, winp);
01666 #if defined(getmaxy)
01667     return INT2FIX(getmaxy(winp->window));
01668 #elif defined(getmaxyx)
01669     {
01670         int x, y;
01671         getmaxyx(winp->window, y, x);
01672         return INT2FIX(y);
01673     }
01674 #else
01675     return INT2FIX(winp->window->_maxy+1);
01676 #endif
01677 }
01678 
01679 /*
01680  * Document-method: Curses::Window.maxx
01681  *
01682  * A getter for the maximum columns for the window
01683  */
01684 static VALUE
01685 window_maxx(VALUE obj)
01686 {
01687     struct windata *winp;
01688 
01689     GetWINDOW(obj, winp);
01690 #if defined(getmaxx)
01691     return INT2FIX(getmaxx(winp->window));
01692 #elif defined(getmaxyx)
01693     {
01694         int x, y;
01695         getmaxyx(winp->window, y, x);
01696         return INT2FIX(x);
01697     }
01698 #else
01699     return INT2FIX(winp->window->_maxx+1);
01700 #endif
01701 }
01702 
01703 /*
01704  * Document-method: Curses::Window.begy
01705  *
01706  * A getter for the beginning line (Y coord) of the window
01707  */
01708 static VALUE
01709 window_begy(VALUE obj)
01710 {
01711     struct windata *winp;
01712     int x, y;
01713 
01714     GetWINDOW(obj, winp);
01715 #ifdef getbegyx
01716     getbegyx(winp->window, y, x);
01717     return INT2FIX(y);
01718 #else
01719     return INT2FIX(winp->window->_begy);
01720 #endif
01721 }
01722 
01723 /*
01724  * Document-method: Curses::Window.begx
01725  *
01726  * A getter for the beginning column (X coord) of the window
01727  */
01728 static VALUE
01729 window_begx(VALUE obj)
01730 {
01731     struct windata *winp;
01732     int x, y;
01733 
01734     GetWINDOW(obj, winp);
01735 #ifdef getbegyx
01736     getbegyx(winp->window, y, x);
01737     return INT2FIX(x);
01738 #else
01739     return INT2FIX(winp->window->_begx);
01740 #endif
01741 }
01742 
01743 /*
01744  * Document-method: Curses::Window.box
01745  * call-seq: box(vert, hor)
01746  *
01747  * set the characters to frame the window in.
01748  * The vertical +vert+ and horizontal +hor+ character.
01749  *
01750  *      win = Curses::Window.new(5,5,5,5)
01751  *      win.box(?|, ?-)
01752  *
01753  */
01754 static VALUE
01755 window_box(int argc, VALUE *argv, VALUE self)
01756 {
01757     struct windata *winp;
01758     VALUE vert, hor, corn;
01759 
01760     rb_scan_args(argc, argv, "21", &vert, &hor, &corn);
01761 
01762     GetWINDOW(self, winp);
01763     box(winp->window, NUM2CH(vert), NUM2CH(hor));
01764 
01765     if (!NIL_P(corn)) {
01766         int cur_x, cur_y, x, y;
01767         chtype c;
01768 
01769         c = NUM2CH(corn);
01770         getyx(winp->window, cur_y, cur_x);
01771         x = NUM2INT(window_maxx(self)) - 1;
01772         y = NUM2INT(window_maxy(self)) - 1;
01773         wmove(winp->window, 0, 0);
01774         waddch(winp->window, c);
01775         wmove(winp->window, y, 0);
01776         waddch(winp->window, c);
01777         wmove(winp->window, y, x);
01778         waddch(winp->window, c);
01779         wmove(winp->window, 0, x);
01780         waddch(winp->window, c);
01781         wmove(winp->window, cur_y, cur_x);
01782     }
01783 
01784     return Qnil;
01785 }
01786 
01787 /*
01788  * Document-method: Curses::Window.standout
01789  *
01790  * Enables the best highlighting mode of the terminal.
01791  *
01792  * This is equivalent to Curses::Window.attron(A_STANDOUT)
01793  *
01794  * see also Curses::Window.attrset
01795  */
01796 static VALUE
01797 window_standout(VALUE obj)
01798 {
01799     struct windata *winp;
01800 
01801     GetWINDOW(obj, winp);
01802     wstandout(winp->window);
01803     return Qnil;
01804 }
01805 
01806 /*
01807  * Document-method: Curses::Window.standend
01808  *
01809  * Enables the Normal display (no highlight)
01810  *
01811  * This is equivalent to Curses::Window.attron(A_NORMAL)
01812  *
01813  * see also Curses::Window.attrset
01814  */
01815 static VALUE
01816 window_standend(VALUE obj)
01817 {
01818     struct windata *winp;
01819 
01820     GetWINDOW(obj, winp);
01821     wstandend(winp->window);
01822     return Qnil;
01823 }
01824 
01825 /*
01826  * Document-method: Curses::Window.inch
01827  *
01828  * Returns the character at the current position of the window.
01829  */
01830 static VALUE
01831 window_inch(VALUE obj)
01832 {
01833     struct windata *winp;
01834 
01835     GetWINDOW(obj, winp);
01836     return CH2FIX(winch(winp->window));
01837 }
01838 
01839 /*
01840  * Document-method: Curses::Window.addch
01841  * call-seq: addch(ch)
01842  *
01843  * Add a character +ch+, with attributes, to the window, then advance the cursor.
01844  *
01845  * see also the system manual for curs_addch(3)
01846  */
01847 static VALUE
01848 window_addch(VALUE obj, VALUE ch)
01849 {
01850     struct windata *winp;
01851 
01852     GetWINDOW(obj, winp);
01853     waddch(winp->window, NUM2CH(ch));
01854 
01855     return Qnil;
01856 }
01857 
01858 /*
01859  * Document-method: Curses::Window.insch
01860  * call-seq: insch(ch)
01861  *
01862  * Insert a character +ch+, before the cursor, in the current window
01863  *
01864  */
01865 static VALUE
01866 window_insch(VALUE obj, VALUE ch)
01867 {
01868     struct windata *winp;
01869 
01870     GetWINDOW(obj, winp);
01871     winsch(winp->window, NUM2CH(ch));
01872 
01873     return Qnil;
01874 }
01875 
01876 /*
01877  * Document-method: Curses::Window.addstr
01878  * call-seq: addstr(str)
01879  *
01880  * add a string of characters +str+, to the window and advance cursor
01881  *
01882  */
01883 static VALUE
01884 window_addstr(VALUE obj, VALUE str)
01885 {
01886     if (!NIL_P(str)) {
01887         struct windata *winp;
01888 
01889         StringValue(str);
01890         str = rb_str_export_locale(str);
01891         GetWINDOW(obj, winp);
01892         waddstr(winp->window, StringValueCStr(str));
01893     }
01894     return Qnil;
01895 }
01896 
01897 /*
01898  * Document-method: Curses::Window.<<
01899  *
01900  * call-seq:
01901  *   <<(str)
01902  *
01903  * Add String +str+ to the current string.
01904  *
01905  * See also Curses::Window.addstr
01906  */
01907 static VALUE
01908 window_addstr2(VALUE obj, VALUE str)
01909 {
01910     window_addstr(obj, str);
01911     return obj;
01912 }
01913 
01914 struct wgetch_arg {
01915     WINDOW *win;
01916     int c;
01917 };
01918 
01919 static VALUE
01920 wgetch_func(void *_arg)
01921 {
01922     struct wgetch_arg *arg = (struct wgetch_arg *)_arg;
01923     arg->c = wgetch(arg->win);
01924     return Qnil;
01925 }
01926 
01927 /*
01928  * Document-method: Curses::Window.getch
01929  *
01930  * Read and returns a character from the window.
01931  *
01932  * See Curses::Key to all the function KEY_* available
01933  *
01934  */
01935 static VALUE
01936 window_getch(VALUE obj)
01937 {
01938     struct windata *winp;
01939     struct wgetch_arg arg;
01940     int c;
01941 
01942     GetWINDOW(obj, winp);
01943     arg.win = winp->window;
01944     rb_thread_blocking_region(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0);
01945     c = arg.c;
01946     if (c == EOF) return Qnil;
01947     if (rb_isprint(c)) {
01948         char ch = (char)c;
01949 
01950         return rb_locale_str_new(&ch, 1);
01951     }
01952     return UINT2NUM(c);
01953 }
01954 
01955 struct wgetstr_arg {
01956     WINDOW *win;
01957     char rtn[GETSTR_BUF_SIZE];
01958 };
01959 
01960 static VALUE
01961 wgetstr_func(void *_arg)
01962 {
01963     struct wgetstr_arg *arg = (struct wgetstr_arg *)_arg;
01964 #if defined(HAVE_WGETNSTR)
01965     wgetnstr(arg->win, arg->rtn, GETSTR_BUF_SIZE-1);
01966 #else
01967     wgetstr(arg->win, arg->rtn);
01968 #endif
01969     return Qnil;
01970 }
01971 
01972 /*
01973  * Document-method: Curses::Window.getstr
01974  *
01975  * This is equivalent to a series f Curses::Window.getch calls
01976  *
01977  */
01978 static VALUE
01979 window_getstr(VALUE obj)
01980 {
01981     struct windata *winp;
01982     struct wgetstr_arg arg;
01983 
01984     GetWINDOW(obj, winp);
01985     arg.win = winp->window;
01986     rb_thread_blocking_region(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0);
01987     return rb_locale_str_new_cstr(arg.rtn);
01988 }
01989 
01990 /*
01991  * Document-method: Curses::Window.delch
01992  *
01993  * Delete the character under the cursor
01994  *
01995  */
01996 static VALUE
01997 window_delch(VALUE obj)
01998 {
01999     struct windata *winp;
02000 
02001     GetWINDOW(obj, winp);
02002     wdelch(winp->window);
02003     return Qnil;
02004 }
02005 
02006 /*
02007  * Document-method: Curses::Window.deleteln
02008  *
02009  * Delete the line under the cursor.
02010  *
02011  */
02012 static VALUE
02013 window_deleteln(VALUE obj)
02014 {
02015 #if defined(HAVE_WDELETELN) || defined(wdeleteln)
02016     struct windata *winp;
02017 
02018     GetWINDOW(obj, winp);
02019     wdeleteln(winp->window);
02020 #endif
02021     return Qnil;
02022 }
02023 
02024 /*
02025  * Document-method: Curses::Window.insertln
02026  *
02027  * Inserts a line above the cursor, and the bottom line is lost
02028  *
02029  */
02030 static VALUE
02031 window_insertln(VALUE obj)
02032 {
02033 #if defined(HAVE_WINSERTLN) || defined(winsertln)
02034     struct windata *winp;
02035 
02036     GetWINDOW(obj, winp);
02037     winsertln(winp->window);
02038 #endif
02039     return Qnil;
02040 }
02041 
02042 /*
02043  * Document-method: Curses::Window.scrollok
02044  * call-seq: scrollok(bool)
02045  *
02046  * Controls what happens when the cursor of a window
02047  * is moved off the edge of the window or scrolling region,
02048  * either as a result of a newline action on the bottom line,
02049  * or typing the last character of the last line.
02050  *
02051  * If disabled, (+bool+ is false), the cursor is left on the bottom line.
02052  *
02053  * If enabled, (+bool+ is true), the window is scrolled up one line
02054  * (Note that to get the physical scrolling effect on the terminal,
02055  * it is also necessary to call Curses::Window.idlok)
02056  */
02057 static VALUE
02058 window_scrollok(VALUE obj, VALUE bf)
02059 {
02060     struct windata *winp;
02061 
02062     GetWINDOW(obj, winp);
02063     scrollok(winp->window, RTEST(bf) ? TRUE : FALSE);
02064     return Qnil;
02065 }
02066 
02067 /*
02068  * Document-method: Curses::Window.idlok
02069  * call-seq: idlok(bool)
02070  *
02071  * If +bool+ is +true+ curses considers using the hardware insert/delete
02072  * line feature of terminals so equipped.
02073  *
02074  * If +bool+ is +false+, disables use of line insertion and deletion.
02075  * This option should be enabled only if the application needs insert/delete
02076  * line, for example, for a screen editor.
02077  *
02078  * It is disabled by default because insert/delete line tends to be visually
02079  * annoying when used in applications where it is not really needed.
02080  * If insert/delete line cannot be used, curses redraws the changed portions of all lines.
02081  *
02082  */
02083 static VALUE
02084 window_idlok(VALUE obj, VALUE bf)
02085 {
02086     struct windata *winp;
02087 
02088     GetWINDOW(obj, winp);
02089     idlok(winp->window, RTEST(bf) ? TRUE : FALSE);
02090     return Qnil;
02091 }
02092 
02093 /*
02094  * Document-method: Curses::Window.setscrreg
02095  * call-seq:
02096  *   setscrreg(top, bottom)
02097  *
02098  * Set a software scrolling region in a window.
02099  * +top+ and +bottom+ are lines numbers of the margin.
02100  *
02101  * If this option and Curses::Window.scrollok are enabled, an attempt to move
02102  * off the bottom margin line causes all lines in the scrolling region to
02103  * scroll one line in the direction of the first line.  Only the text of the
02104  * window is scrolled.
02105  *
02106  */
02107 static VALUE
02108 window_setscrreg(VALUE obj, VALUE top, VALUE bottom)
02109 {
02110 #ifdef HAVE_WSETSCRREG
02111     struct windata *winp;
02112     int res;
02113 
02114     GetWINDOW(obj, winp);
02115     res = wsetscrreg(winp->window, NUM2INT(top), NUM2INT(bottom));
02116     /* may have to raise exception on ERR */
02117     return (res == OK) ? Qtrue : Qfalse;
02118 #else
02119     return Qfalse;
02120 #endif
02121 }
02122 
02123 #if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET)
02124 /*
02125  * Document-method: Curses::Window.color_set
02126  * call-seq: color_set(col)
02127  *
02128  * Sets the current color of the given window to the
02129  * foreground/background combination described by the Fixnum +col+.
02130  */
02131 static VALUE
02132 window_color_set(VALUE obj, VALUE col)
02133 {
02134     struct windata *winp;
02135     int res;
02136 
02137     GetWINDOW(obj, winp);
02138     res = wcolor_set(winp->window, NUM2INT(col), NULL);
02139     return (res == OK) ? Qtrue : Qfalse;
02140 }
02141 #endif /* defined(USE_COLOR) && defined(HAVE_WCOLOR_SET) */
02142 
02143 /*
02144  * Document-method: Curses::Window.scroll
02145  *
02146  * Scrolls the current window up one line.
02147  */
02148 static VALUE
02149 window_scroll(VALUE obj)
02150 {
02151     struct windata *winp;
02152 
02153     GetWINDOW(obj, winp);
02154     /* may have to raise exception on ERR */
02155     return (scroll(winp->window) == OK) ? Qtrue : Qfalse;
02156 }
02157 
02158 /*
02159  * Document-method: Curses::Window.scrl
02160  * call-seq: scrl(num)
02161  *
02162  * Scrolls the current window Fixnum +num+ lines.
02163  * The current cursor position is not changed.
02164  *
02165  * For positive +num+, it scrolls up.
02166  *
02167  * For negative +num+, it scrolls down.
02168  *
02169  */
02170 static VALUE
02171 window_scrl(VALUE obj, VALUE n)
02172 {
02173 #ifdef HAVE_WSCRL
02174     struct windata *winp;
02175 
02176     GetWINDOW(obj, winp);
02177     /* may have to raise exception on ERR */
02178     return (wscrl(winp->window,NUM2INT(n)) == OK) ? Qtrue : Qfalse;
02179 #else
02180     return Qfalse;
02181 #endif
02182 }
02183 
02184 /*
02185  * Document-method: Curses::Window.attroff
02186  * call-seq: attroff(attrs)
02187  *
02188  * Turns on the named attributes +attrs+ without affecting any others.
02189  *
02190  * See also Curses::Window.attrset
02191  */
02192 static VALUE
02193 window_attroff(VALUE obj, VALUE attrs)
02194 {
02195 #ifdef HAVE_WATTROFF
02196     struct windata *winp;
02197 
02198     GetWINDOW(obj,winp);
02199     return INT2FIX(wattroff(winp->window,NUM2INT(attrs)));
02200 #else
02201     return Qtrue;
02202 #endif
02203 }
02204 
02205 /*
02206  * Document-method: Curses::Window.attron
02207  * call-seq: attron(attrs)
02208  *
02209  * Turns off the named attributes +attrs+
02210  * without turning any other attributes on or off.
02211  *
02212  * See also Curses::Window.attrset
02213  */
02214 static VALUE
02215 window_attron(VALUE obj, VALUE attrs)
02216 {
02217 #ifdef HAVE_WATTRON
02218     struct windata *winp;
02219     VALUE val;
02220 
02221     GetWINDOW(obj,winp);
02222     val = INT2FIX(wattron(winp->window,NUM2INT(attrs)));
02223     if (rb_block_given_p()) {
02224         rb_yield(val);
02225         wattroff(winp->window,NUM2INT(attrs));
02226         return val;
02227     }
02228     else{
02229         return val;
02230     }
02231 #else
02232     return Qtrue;
02233 #endif
02234 }
02235 
02236 /*
02237  * Document-method: Curses::Window.attrset
02238  * call-seq: attrset(attrs)
02239  *
02240  * Sets the current attributes of the given window to +attrs+.
02241  *
02242  * The following video attributes, defined in <curses.h>, can
02243  * be passed to the routines Curses::Window.attron, Curses::Window.attroff,
02244  * and Curses::Window.attrset, or OR'd with the characters passed to addch.
02245  *   A_NORMAL        Normal display (no highlight)
02246  *   A_STANDOUT      Best highlighting mode of the terminal.
02247  *   A_UNDERLINE     Underlining
02248  *   A_REVERSE       Reverse video
02249  *   A_BLINK         Blinking
02250  *   A_DIM           Half bright
02251  *   A_BOLD          Extra bright or bold
02252  *   A_PROTECT       Protected mode
02253  *   A_INVIS         Invisible or blank mode
02254  *   A_ALTCHARSET    Alternate character set
02255  *   A_CHARTEXT      Bit-mask to extract a character
02256  *   COLOR_PAIR(n)   Color-pair number n
02257  *
02258  * TODO: provide some examples here.
02259  *
02260  * see also system manual curs_attr(3)
02261  */
02262 static VALUE
02263 window_attrset(VALUE obj, VALUE attrs)
02264 {
02265 #ifdef HAVE_WATTRSET
02266     struct windata *winp;
02267 
02268     GetWINDOW(obj,winp);
02269     return INT2FIX(wattrset(winp->window,NUM2INT(attrs)));
02270 #else
02271     return Qtrue;
02272 #endif
02273 }
02274 
02275 /*
02276  * Document-method: Curses::Window.bkgdset
02277  * call-seq: bkgdset(ch)
02278  *
02279  * Manipulate the background of the current window
02280  * with character Integer +ch+
02281  *
02282  * see also Curses.bkgdset
02283  */
02284 static VALUE
02285 window_bkgdset(VALUE obj, VALUE ch)
02286 {
02287 #ifdef HAVE_WBKGDSET
02288     struct windata *winp;
02289 
02290     GetWINDOW(obj,winp);
02291     wbkgdset(winp->window, NUM2CH(ch));
02292 #endif
02293     return Qnil;
02294 }
02295 
02296 /*
02297  * Document-method: Curses::Window.bkgd
02298  * call-seq: bkgd(ch)
02299  *
02300  * Set the background of the current window
02301  * and apply character Integer +ch+ to every character.
02302  *
02303  * see also Curses.bkgd
02304  */
02305 static VALUE
02306 window_bkgd(VALUE obj, VALUE ch)
02307 {
02308 #ifdef HAVE_WBKGD
02309     struct windata *winp;
02310 
02311     GetWINDOW(obj,winp);
02312     return (wbkgd(winp->window, NUM2CH(ch)) == OK) ? Qtrue : Qfalse;
02313 #else
02314     return Qfalse;
02315 #endif
02316 }
02317 
02318 /*
02319  * Document-method: Curses::Window.getbkgd
02320  *
02321  * Returns an Interer (+ch+) for the character property in the current window.
02322  */
02323 static VALUE
02324 window_getbkgd(VALUE obj)
02325 {
02326 #ifdef HAVE_WGETBKGD
02327     chtype c;
02328     struct windata *winp;
02329 
02330     GetWINDOW(obj,winp);
02331     return (c = getbkgd(winp->window) != ERR) ? CH2FIX(c) : Qnil;
02332 #else
02333     return Qnil;
02334 #endif
02335 }
02336 
02337 /*
02338  * Document-method: Curses::Window.resize
02339  * call-seq: resize(lines, cols)
02340  *
02341  * Resize the current window to Fixnum +lines+ and Fixnum +cols+
02342  *
02343  */
02344 static VALUE
02345 window_resize(VALUE obj, VALUE lin, VALUE col)
02346 {
02347 #if defined(HAVE_WRESIZE)
02348     struct windata *winp;
02349 
02350     GetWINDOW(obj,winp);
02351     return wresize(winp->window, NUM2INT(lin), NUM2INT(col)) == OK ? Qtrue : Qfalse;
02352 #else
02353     return Qnil;
02354 #endif
02355 }
02356 
02357 
02358 #ifdef HAVE_KEYPAD
02359 /*
02360  * Document-method: Curses::Window.keypad=
02361  * call-seq:
02362  *   keypad=(bool)
02363  *
02364  * See Curses::Window.keypad
02365  */
02366 
02367 /*
02368  * Document-method: Curses::Window.keypad
02369  * call-seq:
02370  *   keypad(bool)
02371  *
02372  * Enables the keypad of the user's terminal.
02373  *
02374  * If enabled (+bool+ is +true+), the user can press a function key
02375  * (such as an arrow key) and wgetch returns a single value representing
02376  * the function key, as in KEY_LEFT.  If disabled (+bool+ is +false+),
02377  * curses does not treat function keys specially and the program has to
02378  * interpret the escape sequences itself.  If the keypad in the terminal
02379  * can be turned on (made to transmit) and off (made to work locally),
02380  * turning on this option causes the terminal keypad to be turned on when
02381  * Curses::Window.getch is called.
02382  *
02383  * The default value for keypad is false.
02384  *
02385  */
02386 static VALUE
02387 window_keypad(VALUE obj, VALUE val)
02388 {
02389     struct windata *winp;
02390 
02391     GetWINDOW(obj,winp);
02392     /* keypad() of NetBSD's libcurses returns no value */
02393 #if defined(__NetBSD__) && !defined(NCURSES_VERSION)
02394     keypad(winp->window,(RTEST(val) ? TRUE : FALSE));
02395     return Qnil;
02396 #else
02397     /* may have to raise exception on ERR */
02398     return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ?
02399         Qtrue : Qfalse;
02400 #endif
02401 }
02402 #else
02403 #define window_keypad rb_f_notimplement
02404 #endif
02405 
02406 #ifdef HAVE_NODELAY
02407 /*
02408  * Document-method: Curses::Window.nodelay
02409  * call-seq: nodelay(bool)
02410  *
02411  * Causes Curses::Window.getch to be a non-blocking call.  If no input is ready, getch returns ERR.
02412  *
02413  * If disabled (+bool+ is +false+), Curses::Window.getch waits until a key is pressed.
02414  *
02415  */
02416 static VALUE
02417 window_nodelay(VALUE obj, VALUE val)
02418 {
02419     struct windata *winp;
02420     GetWINDOW(obj,winp);
02421 
02422     /* nodelay() of NetBSD's libcurses returns no value */
02423 #if defined(__NetBSD__) && !defined(NCURSES_VERSION)
02424     nodelay(winp->window, RTEST(val) ? TRUE : FALSE);
02425     return Qnil;
02426 #else
02427     return nodelay(winp->window,RTEST(val) ? TRUE : FALSE) == OK ? Qtrue : Qfalse;
02428 #endif
02429 }
02430 #else
02431 #define window_nodelay rb_f_notimplement
02432 #endif
02433 
02434 #ifdef HAVE_WTIMEOUT
02435 /*
02436  * Document-method: Curses::Window.timeout=
02437  * call-seq: timeout=(delay)
02438  *
02439  * Sets block and non-blocking reads for the window.
02440  * - If delay is negative, blocking read is used (i.e., waits indefinitely for input).
02441  * - If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting).
02442  * - If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input.
02443  *
02444  */
02445 static VALUE
02446 window_timeout(VALUE obj, VALUE delay)
02447 {
02448     struct windata *winp;
02449     GetWINDOW(obj,winp);
02450 
02451     wtimeout(winp->window,NUM2INT(delay));
02452     return Qnil;
02453 }
02454 #else
02455 #define window_timeout rb_f_notimplement
02456 #endif
02457 
02458 /*------------------------- Initialization -------------------------*/
02459 
02460 /*
02461  * Document-module: Curses
02462  *
02463  * == Description
02464  * An implementation of the CRT screen handling and optimization library.
02465  *
02466  * == Structures and such
02467  *
02468  * === Classes
02469  *
02470  * * Curses::Window - class with the means to draw a window or box
02471  * * Curses::MouseEvent - class for collecting mouse events
02472  *
02473  * === Modules
02474  *
02475  * Curses:: The curses implementation
02476  * Curses::Key:: Collection of constants for keypress events
02477  *
02478  * == Examples
02479  *
02480  * * hello.rb
02481  *     :include: hello.rb
02482  *
02483  *
02484  * * rain.rb
02485  *     :include: rain.rb
02486  *
02487  *
02488  */
02489 void
02490 Init_curses(void)
02491 {
02492     mCurses    = rb_define_module("Curses");
02493 
02494     /*
02495      * Document-module: Curses::Key
02496      *
02497      *
02498      * a container for the KEY_* values.
02499      *
02500      * See also system manual for getch(3)
02501      *
02502      */
02503     mKey       = rb_define_module_under(mCurses, "Key");
02504 
02505     rb_gc_register_address(&rb_stdscr);
02506 
02507 #ifdef USE_MOUSE
02508     /*
02509      * Document-class: Curses::MouseEvent
02510      *
02511      * == Description
02512      *
02513      * Curses::MouseEvent
02514      *
02515      * == Example
02516      *
02517      * * mouse.rb
02518      *     :include: mouse.rb
02519      *
02520      */
02521     cMouseEvent = rb_define_class_under(mCurses,"MouseEvent",rb_cObject);
02522     rb_undef_method(CLASS_OF(cMouseEvent),"new");
02523     rb_define_method(cMouseEvent, "eid", curs_mouse_id, 0);
02524     rb_define_method(cMouseEvent, "x", curs_mouse_x, 0);
02525     rb_define_method(cMouseEvent, "y", curs_mouse_y, 0);
02526     rb_define_method(cMouseEvent, "z", curs_mouse_z, 0);
02527     rb_define_method(cMouseEvent, "bstate", curs_mouse_bstate, 0);
02528 #endif /* USE_MOUSE */
02529 
02530     rb_define_module_function(mCurses, "ESCDELAY=", curses_escdelay_set, 1);
02531     rb_define_module_function(mCurses, "ESCDELAY", curses_escdelay_get, 0);
02532     rb_define_module_function(mCurses, "TABSIZE", curses_tabsize_get, 0);
02533     rb_define_module_function(mCurses, "TABSIZE=", curses_tabsize_set, 1);
02534 
02535     rb_define_module_function(mCurses, "use_default_colors", curses_use_default_colors, 0);
02536     rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
02537     rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
02538     rb_define_module_function(mCurses, "closed?", curses_closed, 0);
02539     rb_define_module_function(mCurses, "stdscr", curses_stdscr, 0);
02540     rb_define_module_function(mCurses, "refresh", curses_refresh, 0);
02541     rb_define_module_function(mCurses, "doupdate", curses_doupdate, 0);
02542     rb_define_module_function(mCurses, "clear", curses_clear, 0);
02543     rb_define_module_function(mCurses, "clrtoeol", curses_clrtoeol, 0);
02544     rb_define_module_function(mCurses, "echo", curses_echo, 0);
02545     rb_define_module_function(mCurses, "noecho", curses_noecho, 0);
02546     rb_define_module_function(mCurses, "raw", curses_raw, 0);
02547     rb_define_module_function(mCurses, "noraw", curses_noraw, 0);
02548     rb_define_module_function(mCurses, "cbreak", curses_cbreak, 0);
02549     rb_define_module_function(mCurses, "nocbreak", curses_nocbreak, 0);
02550     rb_define_module_function(mCurses, "crmode", curses_nocbreak, 0);
02551     rb_define_module_function(mCurses, "nocrmode", curses_nocbreak, 0);
02552     rb_define_module_function(mCurses, "nl", curses_nl, 0);
02553     rb_define_module_function(mCurses, "nonl", curses_nonl, 0);
02554     rb_define_module_function(mCurses, "beep", curses_beep, 0);
02555     rb_define_module_function(mCurses, "flash", curses_flash, 0);
02556     rb_define_module_function(mCurses, "ungetch", curses_ungetch, 1);
02557     rb_define_module_function(mCurses, "setpos", curses_setpos, 2);
02558     rb_define_module_function(mCurses, "standout", curses_standout, 0);
02559     rb_define_module_function(mCurses, "standend", curses_standend, 0);
02560     rb_define_module_function(mCurses, "inch", curses_inch, 0);
02561     rb_define_module_function(mCurses, "addch", curses_addch, 1);
02562     rb_define_module_function(mCurses, "insch", curses_insch, 1);
02563     rb_define_module_function(mCurses, "addstr", curses_addstr, 1);
02564     rb_define_module_function(mCurses, "getch", curses_getch, 0);
02565     rb_define_module_function(mCurses, "getstr", curses_getstr, 0);
02566     rb_define_module_function(mCurses, "delch", curses_delch, 0);
02567     rb_define_module_function(mCurses, "deleteln", curses_deleteln, 0);
02568     rb_define_module_function(mCurses, "insertln", curses_insertln, 0);
02569     rb_define_module_function(mCurses, "keyname", curses_keyname, 1);
02570     rb_define_module_function(mCurses, "lines", curses_lines, 0);
02571     rb_define_module_function(mCurses, "cols", curses_cols, 0);
02572     rb_define_module_function(mCurses, "curs_set", curses_curs_set, 1);
02573     rb_define_module_function(mCurses, "scrl", curses_scrl, 1);
02574     rb_define_module_function(mCurses, "setscrreg", curses_setscrreg, 2);
02575     rb_define_module_function(mCurses, "attroff", curses_attroff, 1);
02576     rb_define_module_function(mCurses, "attron", curses_attron, 1);
02577     rb_define_module_function(mCurses, "attrset", curses_attrset, 1);
02578     rb_define_module_function(mCurses, "bkgdset", curses_bkgdset, 1);
02579     rb_define_module_function(mCurses, "bkgd", curses_bkgd, 1);
02580     rb_define_module_function(mCurses, "resizeterm", curses_resizeterm, 2);
02581     rb_define_module_function(mCurses, "resize", curses_resizeterm, 2);
02582 #ifdef USE_COLOR
02583     rb_define_module_function(mCurses, "start_color", curses_start_color, 0);
02584     rb_define_module_function(mCurses, "init_pair", curses_init_pair, 3);
02585     rb_define_module_function(mCurses, "init_color", curses_init_color, 4);
02586     rb_define_module_function(mCurses, "has_colors?", curses_has_colors, 0);
02587     rb_define_module_function(mCurses, "can_change_color?",
02588                               curses_can_change_color, 0);
02589     rb_define_module_function(mCurses, "colors", curses_colors, 0);
02590     rb_define_module_function(mCurses, "color_content", curses_color_content, 1);
02591     rb_define_module_function(mCurses, "color_pairs", curses_color_pairs, 0);
02592     rb_define_module_function(mCurses, "pair_content", curses_pair_content, 1);
02593     rb_define_module_function(mCurses, "color_pair", curses_color_pair, 1);
02594     rb_define_module_function(mCurses, "pair_number", curses_pair_number, 1);
02595 #endif /* USE_COLOR */
02596 #ifdef USE_MOUSE
02597     rb_define_module_function(mCurses, "getmouse", curses_getmouse, 0);
02598     rb_define_module_function(mCurses, "ungetmouse", curses_ungetmouse, 1);
02599     rb_define_module_function(mCurses, "mouseinterval", curses_mouseinterval, 1);
02600     rb_define_module_function(mCurses, "mousemask", curses_mousemask, 1);
02601 #endif /* USE_MOUSE */
02602 
02603     rb_define_module_function(mCurses, "timeout=", curses_timeout, 1);
02604     rb_define_module_function(mCurses, "def_prog_mode", curses_def_prog_mode, 0);
02605     rb_define_module_function(mCurses, "reset_prog_mode", curses_reset_prog_mode, 0);
02606 
02607     /*
02608      * Document-class: Curses::Window
02609      *
02610      * == Description
02611      *
02612      * The means by which to create and manage frames or windows.
02613      * While there may be more than one window at a time, only one window
02614      * will receive input.
02615      *
02616      * == Usage
02617      *
02618      *   require 'curses'
02619      *
02620      *   Curses.init_screen()
02621      *
02622      *   my_str = "LOOK! PONIES!"
02623      *   win = Curses::Window.new( 8, (my_str.length + 10),
02624      *                             (Curses.lines - 8) / 2,
02625      *                             (Curses.cols - (my_str.length + 10)) / 2 )
02626      *   win.box("|", "-")
02627      *   win.setpos(2,3)
02628      *   win.addstr(my_str)
02629      *   # or even
02630      *   win << "\nORLY"
02631      *   win << "\nYES!! " + my_str
02632      *   win.refresh
02633      *   win.getch
02634      *   win.close
02635      *
02636      */
02637     cWindow = rb_define_class_under(mCurses, "Window", rb_cData);
02638     rb_define_alloc_func(cWindow, window_s_allocate);
02639     rb_define_method(cWindow, "initialize", window_initialize, 4);
02640     rb_define_method(cWindow, "subwin", window_subwin, 4);
02641     rb_define_method(cWindow, "close", window_close, 0);
02642     rb_define_method(cWindow, "clear", window_clear, 0);
02643     rb_define_method(cWindow, "clrtoeol", window_clrtoeol, 0);
02644     rb_define_method(cWindow, "refresh", window_refresh, 0);
02645     rb_define_method(cWindow, "noutrefresh", window_noutrefresh, 0);
02646     rb_define_method(cWindow, "box", window_box, -1);
02647     rb_define_method(cWindow, "move", window_move, 2);
02648     rb_define_method(cWindow, "setpos", window_setpos, 2);
02649 #if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET)
02650     rb_define_method(cWindow, "color_set", window_color_set, 1);
02651 #endif /* USE_COLOR && HAVE_WCOLOR_SET */
02652     rb_define_method(cWindow, "cury", window_cury, 0);
02653     rb_define_method(cWindow, "curx", window_curx, 0);
02654     rb_define_method(cWindow, "maxy", window_maxy, 0);
02655     rb_define_method(cWindow, "maxx", window_maxx, 0);
02656     rb_define_method(cWindow, "begy", window_begy, 0);
02657     rb_define_method(cWindow, "begx", window_begx, 0);
02658     rb_define_method(cWindow, "standout", window_standout, 0);
02659     rb_define_method(cWindow, "standend", window_standend, 0);
02660     rb_define_method(cWindow, "inch", window_inch, 0);
02661     rb_define_method(cWindow, "addch", window_addch, 1);
02662     rb_define_method(cWindow, "insch", window_insch, 1);
02663     rb_define_method(cWindow, "addstr", window_addstr, 1);
02664     rb_define_method(cWindow, "<<", window_addstr2, 1);
02665     rb_define_method(cWindow, "getch", window_getch, 0);
02666     rb_define_method(cWindow, "getstr", window_getstr, 0);
02667     rb_define_method(cWindow, "delch", window_delch, 0);
02668     rb_define_method(cWindow, "deleteln", window_deleteln, 0);
02669     rb_define_method(cWindow, "insertln", window_insertln, 0);
02670     rb_define_method(cWindow, "scroll", window_scroll, 0);
02671     rb_define_method(cWindow, "scrollok", window_scrollok, 1);
02672     rb_define_method(cWindow, "idlok", window_idlok, 1);
02673     rb_define_method(cWindow, "setscrreg", window_setscrreg, 2);
02674     rb_define_method(cWindow, "scrl", window_scrl, 1);
02675     rb_define_method(cWindow, "resize", window_resize, 2);
02676     rb_define_method(cWindow, "keypad", window_keypad, 1);
02677     rb_define_method(cWindow, "keypad=", window_keypad, 1);
02678 
02679     rb_define_method(cWindow, "attroff", window_attroff, 1);
02680     rb_define_method(cWindow, "attron", window_attron, 1);
02681     rb_define_method(cWindow, "attrset", window_attrset, 1);
02682     rb_define_method(cWindow, "bkgdset", window_bkgdset, 1);
02683     rb_define_method(cWindow, "bkgd", window_bkgd, 1);
02684     rb_define_method(cWindow, "getbkgd", window_getbkgd, 0);
02685 
02686     rb_define_method(cWindow, "nodelay=", window_nodelay, 1);
02687     rb_define_method(cWindow, "timeout=", window_timeout, 1);
02688 
02689 #define rb_curses_define_const(c) rb_define_const(mCurses,#c,UINT2NUM(c))
02690 
02691 #ifdef USE_COLOR
02692     /* Document-const: A_ATTRIBUTES
02693      *
02694      * Character attribute mask:
02695      * Bit-mask to extract attributes
02696      *
02697      * See Curses.inch or Curses::Window.inch
02698      */
02699     rb_curses_define_const(A_ATTRIBUTES);
02700 #ifdef A_NORMAL
02701     /* Document-const: A_NORMAL
02702      *
02703      * Attribute mask:
02704      * Normal display (no highlight)
02705      *
02706      * See Curses.attrset
02707      */
02708     rb_curses_define_const(A_NORMAL);
02709 #endif
02710     /* Document-const: A_STANDOUT
02711      *
02712      * Attribute mask:
02713      * Best highlighting mode of the terminal.
02714      *
02715      * See Curses.attrset
02716      */
02717     rb_curses_define_const(A_STANDOUT);
02718     /* Document-const: A_UNDERLINE
02719      *
02720      * Attribute mask:
02721      * Underlining
02722      *
02723      * See Curses.attrset
02724      */
02725     rb_curses_define_const(A_UNDERLINE);
02726     /* Document-const: A_REVERSE
02727      *
02728      * Attribute mask:
02729      * Reverse video
02730      *
02731      * See Curses.attrset
02732      */
02733     rb_curses_define_const(A_REVERSE);
02734     /* Document-const: A_BLINK
02735      *
02736      * Attribute mask:
02737      * Blinking
02738      *
02739      * See Curses.attrset
02740      */
02741     rb_curses_define_const(A_BLINK);
02742     /* Document-const: A_DIM
02743      *
02744      * Attribute mask:
02745      * Half bright
02746      *
02747      * See Curses.attrset
02748      */
02749     rb_curses_define_const(A_DIM);
02750     /* Document-const: A_BOLD
02751      *
02752      * Attribute mask:
02753      * Extra bright or bold
02754      *
02755      * See Curses.attrset
02756      */
02757     rb_curses_define_const(A_BOLD);
02758     /* Document-const: A_PROTECT
02759      *
02760      * Attribute mask:
02761      * Protected mode
02762      *
02763      * See Curses.attrset
02764      */
02765     rb_curses_define_const(A_PROTECT);
02766 #ifdef A_INVIS /* for NetBSD */
02767     /* Document-const: A_INVIS
02768      *
02769      * Attribute mask:
02770      * Invisible or blank mode
02771      *
02772      * See Curses.attrset
02773      */
02774     rb_curses_define_const(A_INVIS);
02775 #endif
02776     /* Document-const: A_ALTCHARSET
02777      *
02778      * Attribute mask:
02779      * Alternate character set
02780      *
02781      * See Curses.attrset
02782      */
02783     rb_curses_define_const(A_ALTCHARSET);
02784     /* Document-const: A_CHARTEXT
02785      *
02786      * Attribute mask:
02787      * Bit-mask to extract a character
02788      *
02789      * See Curses.attrset
02790      */
02791     rb_curses_define_const(A_CHARTEXT);
02792 #ifdef A_HORIZONTAL
02793     /* Document-const: A_HORIZONTAL
02794      *
02795      * Attribute mask:
02796      * horizontal highlight
02797      *
02798      * Check system curs_attr(3x) for support
02799      */
02800     rb_curses_define_const(A_HORIZONTAL);
02801 #endif
02802 #ifdef A_LEFT
02803     /* Document-const: A_LEFT
02804      *
02805      * Attribute mask:
02806      * left highlight
02807      *
02808      * Check system curs_attr(3x) for support
02809      */
02810     rb_curses_define_const(A_LEFT);
02811 #endif
02812 #ifdef A_LOW
02813     /* Document-const: A_LOW
02814      *
02815      * Attribute mask:
02816      * low highlight
02817      *
02818      * Check system curs_attr(3x) for support
02819      */
02820     rb_curses_define_const(A_LOW);
02821 #endif
02822 #ifdef A_RIGHT
02823     /* Document-const: A_RIGHT
02824      *
02825      * Attribute mask:
02826      * right highlight
02827      *
02828      * Check system curs_attr(3x) for support
02829      */
02830     rb_curses_define_const(A_RIGHT);
02831 #endif
02832 #ifdef A_TOP
02833     /* Document-const: A_TOP
02834      *
02835      * Attribute mask:
02836      * top highlight
02837      *
02838      * Check system curs_attr(3x) for support
02839      */
02840     rb_curses_define_const(A_TOP);
02841 #endif
02842 #ifdef A_VERTICAL
02843     /* Document-const: A_VERTICAL
02844      *
02845      * Attribute mask:
02846      * vertical highlight
02847      *
02848      * Check system curs_attr(3x) for support
02849      */
02850     rb_curses_define_const(A_VERTICAL);
02851 #endif
02852     /* Document-const: A_COLOR
02853      *
02854      * Character attribute mask:
02855      * Bit-mask to extract color-pair field information
02856      *
02857      * See Curses.inch or Curses::Window.inch
02858      */
02859     rb_curses_define_const(A_COLOR);
02860 
02861 #ifdef COLORS
02862     /*
02863      * Document-const: Curses::COLORS
02864      *
02865      * Number of the colors available
02866      */
02867     rb_curses_define_const(COLORS);
02868 #endif
02869     /*
02870      * Document-const: Curses::COLOR_BLACK
02871      *
02872      * Value of the color black
02873      */
02874     rb_curses_define_const(COLOR_BLACK);
02875     /*
02876      * Document-const: COLOR_RED
02877      *
02878      * Value of the color red
02879      */
02880     rb_curses_define_const(COLOR_RED);
02881     /*
02882      * Document-const: COLOR_GREEN
02883      *
02884      * Value of the color green
02885      */
02886     rb_curses_define_const(COLOR_GREEN);
02887     /*
02888      * Document-const: COLOR_YELLOW
02889      *
02890      * Value of the color yellow
02891      */
02892     rb_curses_define_const(COLOR_YELLOW);
02893     /*
02894      * Document-const: COLOR_BLUE
02895      *
02896      * Value of the color blue
02897      */
02898     rb_curses_define_const(COLOR_BLUE);
02899     /*
02900      * Document-const: COLOR_MAGENTA
02901      *
02902      * Value of the color magenta
02903      */
02904     rb_curses_define_const(COLOR_MAGENTA);
02905     /*
02906      * Document-const: COLOR_CYAN
02907      *
02908      * Value of the color cyan
02909      */
02910     rb_curses_define_const(COLOR_CYAN);
02911     /*
02912      * Document-const: COLOR_WHITE
02913      *
02914      * Value of the color white
02915      */
02916     rb_curses_define_const(COLOR_WHITE);
02917 #endif /* USE_COLOR */
02918 #ifdef USE_MOUSE
02919 #ifdef BUTTON1_PRESSED
02920     /* Document-const: BUTTON1_PRESSED
02921      *
02922      * Mouse event mask:
02923      * mouse button 1 down
02924      *
02925      * See Curses.getmouse
02926      */
02927     rb_curses_define_const(BUTTON1_PRESSED);
02928 #endif
02929 #ifdef BUTTON1_RELEASED
02930     /* Document-const: BUTTON1_RELEASED
02931      *
02932      * Mouse event mask:
02933      * mouse button 1 up
02934      *
02935      * See Curses.getmouse
02936      */
02937     rb_curses_define_const(BUTTON1_RELEASED);
02938 #endif
02939 #ifdef BUTTON1_CLICKED
02940     /* Document-const: BUTTON1_CLICKED
02941      *
02942      * Mouse event mask:
02943      * mouse button 1 clicked
02944      *
02945      * See Curses.getmouse
02946      */
02947     rb_curses_define_const(BUTTON1_CLICKED);
02948 #endif
02949 #ifdef BUTTON1_DOUBLE_CLICKED
02950     /* Document-const: BUTTON1_DOUBLE_CLICKED
02951      *
02952      * Mouse event mask:
02953      * mouse button 1 double clicked
02954      *
02955      * See Curses.getmouse
02956      */
02957     rb_curses_define_const(BUTTON1_DOUBLE_CLICKED);
02958 #endif
02959 #ifdef BUTTON1_TRIPLE_CLICKED
02960     /* Document-const: BUTTON1_TRIPLE_CLICKED
02961      *
02962      * Mouse event mask:
02963      * mouse button 1 triple clicked
02964      *
02965      * See Curses.getmouse
02966      */
02967     rb_curses_define_const(BUTTON1_TRIPLE_CLICKED);
02968 #endif
02969 #ifdef BUTTON2_PRESSED
02970     /* Document-const: BUTTON2_PRESSED
02971      *
02972      * Mouse event mask:
02973      * mouse button 2 down
02974      *
02975      * See Curses.getmouse
02976      */
02977     rb_curses_define_const(BUTTON2_PRESSED);
02978 #endif
02979 #ifdef BUTTON2_RELEASED
02980     /* Document-const: BUTTON2_RELEASED
02981      *
02982      * Mouse event mask:
02983      * mouse button 2 up
02984      *
02985      * See Curses.getmouse
02986      */
02987     rb_curses_define_const(BUTTON2_RELEASED);
02988 #endif
02989 #ifdef BUTTON2_CLICKED
02990     /* Document-const: BUTTON2_CLICKED
02991      *
02992      * Mouse event mask:
02993      * mouse button 2 clicked
02994      *
02995      * See Curses.getmouse
02996      */
02997     rb_curses_define_const(BUTTON2_CLICKED);
02998 #endif
02999 #ifdef BUTTON2_DOUBLE_CLICKED
03000     /* Document-const: BUTTON2_DOUBLE_CLICKED
03001      *
03002      * Mouse event mask:
03003      * mouse button 2 double clicked
03004      *
03005      * See Curses.getmouse
03006      */
03007     rb_curses_define_const(BUTTON2_DOUBLE_CLICKED);
03008 #endif
03009 #ifdef BUTTON2_TRIPLE_CLICKED
03010     /* Document-const: BUTTON2_TRIPLE_CLICKED
03011      *
03012      * Mouse event mask:
03013      * mouse button 2 triple clicked
03014      *
03015      * See Curses.getmouse
03016      */
03017     rb_curses_define_const(BUTTON2_TRIPLE_CLICKED);
03018 #endif
03019 #ifdef BUTTON3_PRESSED
03020     /* Document-const: BUTTON3_PRESSED
03021      *
03022      * Mouse event mask:
03023      * mouse button 3 down
03024      *
03025      * See Curses.getmouse
03026      */
03027     rb_curses_define_const(BUTTON3_PRESSED);
03028 #endif
03029 #ifdef BUTTON3_RELEASED
03030     /* Document-const: BUTTON3_RELEASED
03031      *
03032      * Mouse event mask:
03033      * mouse button 3 up
03034      *
03035      * See Curses.getmouse
03036      */
03037     rb_curses_define_const(BUTTON3_RELEASED);
03038 #endif
03039 #ifdef BUTTON3_CLICKED
03040     /* Document-const: BUTTON3_CLICKED
03041      *
03042      * Mouse event mask:
03043      * mouse button 3 clicked
03044      *
03045      * See Curses.getmouse
03046      */
03047     rb_curses_define_const(BUTTON3_CLICKED);
03048 #endif
03049 #ifdef BUTTON3_DOUBLE_CLICKED
03050     /* Document-const: BUTTON3_DOUBLE_CLICKED
03051      *
03052      * Mouse event mask:
03053      * mouse button 3 double clicked
03054      *
03055      * See Curses.getmouse
03056      */
03057     rb_curses_define_const(BUTTON3_DOUBLE_CLICKED);
03058 #endif
03059 #ifdef BUTTON3_TRIPLE_CLICKED
03060     /* Document-const: BUTTON3_TRIPLE_CLICKED
03061      *
03062      * Mouse event mask:
03063      * mouse button 3 triple clicked
03064      *
03065      * See Curses.getmouse
03066      */
03067     rb_curses_define_const(BUTTON3_TRIPLE_CLICKED);
03068 #endif
03069 #ifdef BUTTON4_PRESSED
03070     /* Document-const: BUTTON4_PRESSED
03071      *
03072      * Mouse event mask:
03073      * mouse button 4 down
03074      *
03075      * See Curses.getmouse
03076      */
03077     rb_curses_define_const(BUTTON4_PRESSED);
03078 #endif
03079 #ifdef BUTTON4_RELEASED
03080     /* Document-const: BUTTON4_RELEASED
03081      *
03082      * Mouse event mask:
03083      * mouse button 4 up
03084      *
03085      * See Curses.getmouse
03086      */
03087     rb_curses_define_const(BUTTON4_RELEASED);
03088 #endif
03089 #ifdef BUTTON4_CLICKED
03090     /* Document-const: BUTTON4_CLICKED
03091      *
03092      * Mouse event mask:
03093      * mouse button 4 clicked
03094      *
03095      * See Curses.getmouse
03096      */
03097     rb_curses_define_const(BUTTON4_CLICKED);
03098 #endif
03099 #ifdef BUTTON4_DOUBLE_CLICKED
03100     /* Document-const: BUTTON4_DOUBLE_CLICKED
03101      *
03102      * Mouse event mask:
03103      * mouse button 4 double clicked
03104      *
03105      * See Curses.getmouse
03106      */
03107     rb_curses_define_const(BUTTON4_DOUBLE_CLICKED);
03108 #endif
03109 #ifdef BUTTON4_TRIPLE_CLICKED
03110     /* Document-const: BUTTON4_TRIPLE_CLICKED
03111      *
03112      * Mouse event mask:
03113      * mouse button 4 triple clicked
03114      *
03115      * See Curses.getmouse
03116      */
03117     rb_curses_define_const(BUTTON4_TRIPLE_CLICKED);
03118 #endif
03119 #ifdef BUTTON_SHIFT
03120     /* Document-const: BUTTON_SHIFT
03121      *
03122      * Mouse event mask:
03123      * shift was down during button state change
03124      *
03125      * See Curses.getmouse
03126      */
03127     rb_curses_define_const(BUTTON_SHIFT);
03128 #endif
03129 #ifdef BUTTON_CTRL
03130     /* Document-const: BUTTON_CTRL
03131      *
03132      * Mouse event mask:
03133      * control was down during button state change
03134      *
03135      * See Curses.getmouse
03136      */
03137     rb_curses_define_const(BUTTON_CTRL);
03138 #endif
03139 #ifdef BUTTON_ALT
03140     /* Document-const: BUTTON_ALT
03141      *
03142      * Mouse event mask:
03143      * alt was down during button state change
03144      *
03145      * See Curses.getmouse
03146      */
03147     rb_curses_define_const(BUTTON_ALT);
03148 #endif
03149 #ifdef ALL_MOUSE_EVENTS
03150     /* Document-const: ALL_MOUSE_EVENTS
03151      *
03152      * Mouse event mask:
03153      * report all button state changes
03154      *
03155      * See Curses.getmouse
03156      */
03157     rb_curses_define_const(ALL_MOUSE_EVENTS);
03158 #endif
03159 #ifdef REPORT_MOUSE_POSITION
03160     /* Document-const: REPORT_MOUSE_POSITION
03161      *
03162      * Mouse event mask:
03163      * report mouse movement
03164      *
03165      * See Curses.getmouse
03166      */
03167     rb_curses_define_const(REPORT_MOUSE_POSITION);
03168 #endif
03169 #endif /* USE_MOUSE */
03170 
03171 #if defined(KEY_MOUSE) && defined(USE_MOUSE)
03172     /* Document-const: KEY_MOUSE
03173      * Mouse event read
03174      */
03175     /* Document-const: MOUSE
03176      * Mouse event read
03177      */
03178     rb_curses_define_const(KEY_MOUSE);
03179     rb_define_const(mKey, "MOUSE", INT2NUM(KEY_MOUSE));
03180 #endif
03181 #ifdef KEY_MIN
03182     /* Document-const: KEY_MIN
03183      * The minimum allowed curses key value.
03184      */
03185     /* Document-const: MIN
03186      * The minimum allowed curses key value.
03187      */
03188     rb_curses_define_const(KEY_MIN);
03189     rb_define_const(mKey, "MIN", INT2NUM(KEY_MIN));
03190 #endif
03191 #ifdef KEY_BREAK
03192     /* Document-const: KEY_BREAK
03193      * Break key
03194      */
03195     /* Document-const: BREAK
03196      * Break key
03197      */
03198     rb_curses_define_const(KEY_BREAK);
03199     rb_define_const(mKey, "BREAK", INT2NUM(KEY_BREAK));
03200 #endif
03201 #ifdef KEY_DOWN
03202     /* Document-const: KEY_DOWN
03203      * the down arrow key
03204      */
03205     /* Document-const: DOWN
03206      * the down arrow key
03207      */
03208     rb_curses_define_const(KEY_DOWN);
03209     rb_define_const(mKey, "DOWN", INT2NUM(KEY_DOWN));
03210 #endif
03211 #ifdef KEY_UP
03212     /* Document-const: KEY_UP
03213      * the up arrow key
03214      */
03215     /* Document-const: UP
03216      * the up arrow key
03217      */
03218     rb_curses_define_const(KEY_UP);
03219     rb_define_const(mKey, "UP", INT2NUM(KEY_UP));
03220 #endif
03221 #ifdef KEY_LEFT
03222     /* Document-const: KEY_LEFT
03223      * the left arrow key
03224      */
03225     /* Document-const: LEFT
03226      * the left arrow key
03227      */
03228     rb_curses_define_const(KEY_LEFT);
03229     rb_define_const(mKey, "LEFT", INT2NUM(KEY_LEFT));
03230 #endif
03231 #ifdef KEY_RIGHT
03232     /* Document-const: KEY_RIGHT
03233      * the right arrow key
03234      */
03235     /* Document-const: RIGHT
03236      * the right arrow key
03237      */
03238     rb_curses_define_const(KEY_RIGHT);
03239     rb_define_const(mKey, "RIGHT", INT2NUM(KEY_RIGHT));
03240 #endif
03241 #ifdef KEY_HOME
03242     /* Document-const: KEY_HOME
03243      * Home key (upward+left arrow)
03244      */
03245     /* Document-const: HOME
03246      * Home key (upward+left arrow)
03247      */
03248     rb_curses_define_const(KEY_HOME);
03249     rb_define_const(mKey, "HOME", INT2NUM(KEY_HOME));
03250 #endif
03251 #ifdef KEY_BACKSPACE
03252     /* Document-const: KEY_BACKSPACE
03253      * Backspace
03254      */
03255     /* Document-const: BACKSPACE
03256      * Backspace
03257      */
03258     rb_curses_define_const(KEY_BACKSPACE);
03259     rb_define_const(mKey, "BACKSPACE", INT2NUM(KEY_BACKSPACE));
03260 #endif
03261 #ifdef KEY_F
03262     /* KEY_F(n) : 0 <= n <= 63 */
03263     {
03264         int i;
03265         char c[8];
03266         for (i=0; i<64; i++) {
03267             sprintf(c, "KEY_F%d", i);
03268             rb_define_const(mCurses, c, INT2NUM(KEY_F(i)));
03269             sprintf(c, "F%d", i);
03270             rb_define_const(mKey, c, INT2NUM(KEY_F(i)));
03271         }
03272     }
03273 #endif
03274 #ifdef KEY_DL
03275     /* Document-const: KEY_DL
03276      * Delete line
03277      */
03278     /* Document-const: DL
03279      * Delete line
03280      */
03281     rb_curses_define_const(KEY_DL);
03282     rb_define_const(mKey, "DL", INT2NUM(KEY_DL));
03283 #endif
03284 #ifdef KEY_IL
03285     /* Document-const: KEY_IL
03286      * Insert line
03287      */
03288     /* Document-const: IL
03289      * Insert line
03290      */
03291     rb_curses_define_const(KEY_IL);
03292     rb_define_const(mKey, "IL", INT2NUM(KEY_IL));
03293 #endif
03294 #ifdef KEY_DC
03295     /* Document-const: KEY_DC
03296      * Delete character
03297      */
03298     /* Document-const: DC
03299      * Delete character
03300      */
03301     rb_curses_define_const(KEY_DC);
03302     rb_define_const(mKey, "DC", INT2NUM(KEY_DC));
03303 #endif
03304 #ifdef KEY_IC
03305     /* Document-const: KEY_IC
03306      * Insert char or enter insert mode
03307      */
03308     /* Document-const: IC
03309      * Insert char or enter insert mode
03310      */
03311     rb_curses_define_const(KEY_IC);
03312     rb_define_const(mKey, "IC", INT2NUM(KEY_IC));
03313 #endif
03314 #ifdef KEY_EIC
03315     /* Document-const: KEY_EIC
03316      * Enter insert char mode
03317      */
03318     /* Document-const: EIC
03319      * Enter insert char mode
03320      */
03321     rb_curses_define_const(KEY_EIC);
03322     rb_define_const(mKey, "EIC", INT2NUM(KEY_EIC));
03323 #endif
03324 #ifdef KEY_CLEAR
03325     /* Document-const: KEY_CLEAR
03326      * Clear Screen
03327      */
03328     /* Document-const: CLEAR
03329      * Clear Screen
03330      */
03331     rb_curses_define_const(KEY_CLEAR);
03332     rb_define_const(mKey, "CLEAR", INT2NUM(KEY_CLEAR));
03333 #endif
03334 #ifdef KEY_EOS
03335     /* Document-const: KEY_EOS
03336      * Clear to end of screen
03337      */
03338     /* Document-const: EOS
03339      * Clear to end of screen
03340      */
03341     rb_curses_define_const(KEY_EOS);
03342     rb_define_const(mKey, "EOS", INT2NUM(KEY_EOS));
03343 #endif
03344 #ifdef KEY_EOL
03345     /* Document-const: KEY_EOL
03346      * Clear to end of line
03347      */
03348     /* Document-const: EOL
03349      * Clear to end of line
03350      */
03351     rb_curses_define_const(KEY_EOL);
03352     rb_define_const(mKey, "EOL", INT2NUM(KEY_EOL));
03353 #endif
03354 #ifdef KEY_SF
03355     /* Document-const: KEY_SF
03356      * Scroll 1 line forward
03357      */
03358     /* Document-const: SF
03359      * Scroll 1 line forward
03360      */
03361     rb_curses_define_const(KEY_SF);
03362     rb_define_const(mKey, "SF", INT2NUM(KEY_SF));
03363 #endif
03364 #ifdef KEY_SR
03365     /* Document-const: KEY_SR
03366      * Scroll 1 line backware (reverse)
03367      */
03368     /* Document-const: SR
03369      * Scroll 1 line backware (reverse)
03370      */
03371     rb_curses_define_const(KEY_SR);
03372     rb_define_const(mKey, "SR", INT2NUM(KEY_SR));
03373 #endif
03374 #ifdef KEY_NPAGE
03375     /* Document-const: KEY_NPAGE
03376      * Next page
03377      */
03378     /* Document-const: NPAGE
03379      * Next page
03380      */
03381     rb_curses_define_const(KEY_NPAGE);
03382     rb_define_const(mKey, "NPAGE", INT2NUM(KEY_NPAGE));
03383 #endif
03384 #ifdef KEY_PPAGE
03385     /* Document-const: KEY_PPAGE
03386      * Previous page
03387      */
03388     /* Document-const: PPAGE
03389      * Previous page
03390      */
03391     rb_curses_define_const(KEY_PPAGE);
03392     rb_define_const(mKey, "PPAGE", INT2NUM(KEY_PPAGE));
03393 #endif
03394 #ifdef KEY_STAB
03395     /* Document-const: KEY_STAB
03396      * Set tab
03397      */
03398     /* Document-const: STAB
03399      * Set tab
03400      */
03401     rb_curses_define_const(KEY_STAB);
03402     rb_define_const(mKey, "STAB", INT2NUM(KEY_STAB));
03403 #endif
03404 #ifdef KEY_CTAB
03405     /* Document-const: KEY_CTAB
03406      * Clear tab
03407      */
03408     /* Document-const: CTAB
03409      * Clear tab
03410      */
03411     rb_curses_define_const(KEY_CTAB);
03412     rb_define_const(mKey, "CTAB", INT2NUM(KEY_CTAB));
03413 #endif
03414 #ifdef KEY_CATAB
03415     /* Document-const: KEY_CATAB
03416      * Clear all tabs
03417      */
03418     /* Document-const: CATAB
03419      * Clear all tabs
03420      */
03421     rb_curses_define_const(KEY_CATAB);
03422     rb_define_const(mKey, "CATAB", INT2NUM(KEY_CATAB));
03423 #endif
03424 #ifdef KEY_ENTER
03425     /* Document-const: KEY_ENTER
03426      * Enter or send
03427      */
03428     /* Document-const: ENTER
03429      * Enter or send
03430      */
03431     rb_curses_define_const(KEY_ENTER);
03432     rb_define_const(mKey, "ENTER", INT2NUM(KEY_ENTER));
03433 #endif
03434 #ifdef KEY_SRESET
03435     /* Document-const: KEY_SRESET
03436      * Soft (partial) reset
03437      */
03438     /* Document-const: SRESET
03439      * Soft (partial) reset
03440      */
03441     rb_curses_define_const(KEY_SRESET);
03442     rb_define_const(mKey, "SRESET", INT2NUM(KEY_SRESET));
03443 #endif
03444 #ifdef KEY_RESET
03445     /* Document-const: KEY_RESET
03446      * Reset or hard reset
03447      */
03448     /* Document-const: RESET
03449      * Reset or hard reset
03450      */
03451     rb_curses_define_const(KEY_RESET);
03452     rb_define_const(mKey, "RESET", INT2NUM(KEY_RESET));
03453 #endif
03454 #ifdef KEY_PRINT
03455     /* Document-const: KEY_PRINT
03456      * Print or copy
03457      */
03458     /* Document-const: PRINT
03459      * Print or copy
03460      */
03461     rb_curses_define_const(KEY_PRINT);
03462     rb_define_const(mKey, "PRINT", INT2NUM(KEY_PRINT));
03463 #endif
03464 #ifdef KEY_LL
03465     /* Document-const: KEY_LL
03466      * Home down or bottom (lower left)
03467      */
03468     /* Document-const: LL
03469      * Home down or bottom (lower left)
03470      */
03471     rb_curses_define_const(KEY_LL);
03472     rb_define_const(mKey, "LL", INT2NUM(KEY_LL));
03473 #endif
03474 #ifdef KEY_A1
03475     /* Document-const: KEY_A1
03476      * Upper left of keypad
03477      */
03478     /* Document-const: A1
03479      * Upper left of keypad
03480      */
03481     rb_curses_define_const(KEY_A1);
03482     rb_define_const(mKey, "A1", INT2NUM(KEY_A1));
03483 #endif
03484 #ifdef KEY_A3
03485     /* Document-const: KEY_A3
03486      * Upper right of keypad
03487      */
03488     /* Document-const: A3
03489      * Upper right of keypad
03490      */
03491     rb_curses_define_const(KEY_A3);
03492     rb_define_const(mKey, "A3", INT2NUM(KEY_A3));
03493 #endif
03494 #ifdef KEY_B2
03495     /* Document-const: KEY_B2
03496      * Center of keypad
03497      */
03498     /* Document-const: B2
03499      * Center of keypad
03500      */
03501     rb_curses_define_const(KEY_B2);
03502     rb_define_const(mKey, "B2", INT2NUM(KEY_B2));
03503 #endif
03504 #ifdef KEY_C1
03505     /* Document-const: KEY_C1
03506      * Lower left of keypad
03507      */
03508     /* Document-const: C1
03509      * Lower left of keypad
03510      */
03511     rb_curses_define_const(KEY_C1);
03512     rb_define_const(mKey, "C1", INT2NUM(KEY_C1));
03513 #endif
03514 #ifdef KEY_C3
03515     /* Document-const: KEY_C3
03516      * Lower right of keypad
03517      */
03518     /* Document-const: C3
03519      * Lower right of keypad
03520      */
03521     rb_curses_define_const(KEY_C3);
03522     rb_define_const(mKey, "C3", INT2NUM(KEY_C3));
03523 #endif
03524 #ifdef KEY_BTAB
03525     /* Document-const: BTAB
03526      * Back tab key
03527      */
03528     /* Document-const: KEY_BTAB
03529      * Back tab key
03530      */
03531     rb_curses_define_const(KEY_BTAB);
03532     rb_define_const(mKey, "BTAB", INT2NUM(KEY_BTAB));
03533 #endif
03534 #ifdef KEY_BEG
03535     /* Document-const: KEY_BEG
03536      * Beginning key
03537      */
03538     /* Document-const: BEG
03539      * Beginning key
03540      */
03541     rb_curses_define_const(KEY_BEG);
03542     rb_define_const(mKey, "BEG", INT2NUM(KEY_BEG));
03543 #endif
03544 #ifdef KEY_CANCEL
03545     /* Document-const: KEY_CANCEL
03546      * Cancel key
03547      */
03548     /* Document-const: CANCEL
03549      * Cancel key
03550      */
03551     rb_curses_define_const(KEY_CANCEL);
03552     rb_define_const(mKey, "CANCEL", INT2NUM(KEY_CANCEL));
03553 #endif
03554 #ifdef KEY_CLOSE
03555     /* Document-const: KEY_CLOSE
03556      * Close key
03557      */
03558     /* Document-const: CLOSE
03559      * Close key
03560      */
03561     rb_curses_define_const(KEY_CLOSE);
03562     rb_define_const(mKey, "CLOSE", INT2NUM(KEY_CLOSE));
03563 #endif
03564 #ifdef KEY_COMMAND
03565     /* Document-const: KEY_COMMAND
03566      * Cmd (command) key
03567      */
03568     /* Document-const: COMMAND
03569      * Cmd (command) key
03570      */
03571     rb_curses_define_const(KEY_COMMAND);
03572     rb_define_const(mKey, "COMMAND", INT2NUM(KEY_COMMAND));
03573 #endif
03574 #ifdef KEY_COPY
03575     /* Document-const: KEY_COPY
03576      * Copy key
03577      */
03578     /* Document-const: COPY
03579      * Copy key
03580      */
03581     rb_curses_define_const(KEY_COPY);
03582     rb_define_const(mKey, "COPY", INT2NUM(KEY_COPY));
03583 #endif
03584 #ifdef KEY_CREATE
03585     /* Document-const: KEY_CREATE
03586      * Create key
03587      */
03588     /* Document-const: CREATE
03589      * Create key
03590      */
03591     rb_curses_define_const(KEY_CREATE);
03592     rb_define_const(mKey, "CREATE", INT2NUM(KEY_CREATE));
03593 #endif
03594 #ifdef KEY_END
03595     /* Document-const: KEY_END
03596      * End key
03597      */
03598     /* Document-const: END
03599      * End key
03600      */
03601     rb_curses_define_const(KEY_END);
03602     rb_define_const(mKey, "END", INT2NUM(KEY_END));
03603 #endif
03604 #ifdef KEY_EXIT
03605     /* Document-const: KEY_EXIT
03606      * Exit key
03607      */
03608     /* Document-const: EXIT
03609      * Exit key
03610      */
03611     rb_curses_define_const(KEY_EXIT);
03612     rb_define_const(mKey, "EXIT", INT2NUM(KEY_EXIT));
03613 #endif
03614 #ifdef KEY_FIND
03615     /* Document-const: KEY_FIND
03616      * Find key
03617      */
03618     /* Document-const: FIND
03619      * Find key
03620      */
03621     rb_curses_define_const(KEY_FIND);
03622     rb_define_const(mKey, "FIND", INT2NUM(KEY_FIND));
03623 #endif
03624 #ifdef KEY_HELP
03625     /* Document-const: KEY_HELP
03626      * Help key
03627      */
03628     /* Document-const: HELP
03629      * Help key
03630      */
03631     rb_curses_define_const(KEY_HELP);
03632     rb_define_const(mKey, "HELP", INT2NUM(KEY_HELP));
03633 #endif
03634 #ifdef KEY_MARK
03635     /* Document-const: KEY_MARK
03636      * Mark key
03637      */
03638     /* Document-const: MARK
03639      * Mark key
03640      */
03641     rb_curses_define_const(KEY_MARK);
03642     rb_define_const(mKey, "MARK", INT2NUM(KEY_MARK));
03643 #endif
03644 #ifdef KEY_MESSAGE
03645     /* Document-const: KEY_MESSAGE
03646      * Message key
03647      */
03648     /* Document-const: MESSAGE
03649      * Message key
03650      */
03651     rb_curses_define_const(KEY_MESSAGE);
03652     rb_define_const(mKey, "MESSAGE", INT2NUM(KEY_MESSAGE));
03653 #endif
03654 #ifdef KEY_MOVE
03655     /* Document-const: KEY_MOVE
03656      * Move key
03657      */
03658     /* Document-const: MOVE
03659      * Move key
03660      */
03661     rb_curses_define_const(KEY_MOVE);
03662     rb_define_const(mKey, "MOVE", INT2NUM(KEY_MOVE));
03663 #endif
03664 #ifdef KEY_NEXT
03665     /* Document-const: KEY_NEXT
03666      * Next object key
03667      */
03668     /* Document-const: NEXT
03669      * Next object key
03670      */
03671     rb_curses_define_const(KEY_NEXT);
03672     rb_define_const(mKey, "NEXT", INT2NUM(KEY_NEXT));
03673 #endif
03674 #ifdef KEY_OPEN
03675     /* Document-const: KEY_OPEN
03676      * Open key
03677      */
03678     /* Document-const: OPEN
03679      * Open key
03680      */
03681     rb_curses_define_const(KEY_OPEN);
03682     rb_define_const(mKey, "OPEN", INT2NUM(KEY_OPEN));
03683 #endif
03684 #ifdef KEY_OPTIONS
03685     /* Document-const: KEY_OPTIONS
03686      * Options key
03687      */
03688     /* Document-const: OPTIONS
03689      * Options key
03690      */
03691     rb_curses_define_const(KEY_OPTIONS);
03692     rb_define_const(mKey, "OPTIONS", INT2NUM(KEY_OPTIONS));
03693 #endif
03694 #ifdef KEY_PREVIOUS
03695     /* Document-const: KEY_PREVIOUS
03696      * Previous object key
03697      */
03698     /* Document-const: PREVIOUS
03699      * Previous object key
03700      */
03701     rb_curses_define_const(KEY_PREVIOUS);
03702     rb_define_const(mKey, "PREVIOUS", INT2NUM(KEY_PREVIOUS));
03703 #endif
03704 #ifdef KEY_REDO
03705     /* Document-const: KEY_REDO
03706      * Redo key
03707      */
03708     /* Document-const: REDO
03709      * Redo key
03710      */
03711     rb_curses_define_const(KEY_REDO);
03712     rb_define_const(mKey, "REDO", INT2NUM(KEY_REDO));
03713 #endif
03714 #ifdef KEY_REFERENCE
03715     /* Document-const: KEY_REFERENCE
03716      * Reference key
03717      */
03718     /* Document-const: REFERENCE
03719      * Reference key
03720      */
03721     rb_curses_define_const(KEY_REFERENCE);
03722     rb_define_const(mKey, "REFERENCE", INT2NUM(KEY_REFERENCE));
03723 #endif
03724 #ifdef KEY_REFRESH
03725     /* Document-const: KEY_REFRESH
03726      * Refresh key
03727      */
03728     /* Document-const: REFRESH
03729      * Refresh key
03730      */
03731     rb_curses_define_const(KEY_REFRESH);
03732     rb_define_const(mKey, "REFRESH", INT2NUM(KEY_REFRESH));
03733 #endif
03734 #ifdef KEY_REPLACE
03735     /* Document-const: KEY_REPLACE
03736      * Replace key
03737      */
03738     /* Document-const: REPLACE
03739      * Replace key
03740      */
03741     rb_curses_define_const(KEY_REPLACE);
03742     rb_define_const(mKey, "REPLACE", INT2NUM(KEY_REPLACE));
03743 #endif
03744 #ifdef KEY_RESTART
03745     /* Document-const: KEY_RESTART
03746      * Restart key
03747      */
03748     /* Document-const: RESTART
03749      * Restart key
03750      */
03751     rb_curses_define_const(KEY_RESTART);
03752     rb_define_const(mKey, "RESTART", INT2NUM(KEY_RESTART));
03753 #endif
03754 #ifdef KEY_RESUME
03755     /* Document-const: KEY_RESUME
03756      * Resume key
03757      */
03758     /* Document-const: RESUME
03759      * Resume key
03760      */
03761     rb_curses_define_const(KEY_RESUME);
03762     rb_define_const(mKey, "RESUME", INT2NUM(KEY_RESUME));
03763 #endif
03764 #ifdef KEY_SAVE
03765     /* Document-const: KEY_SAVE
03766      * Save key
03767      */
03768     /* Document-const: SAVE
03769      * Save key
03770      */
03771     rb_curses_define_const(KEY_SAVE);
03772     rb_define_const(mKey, "SAVE", INT2NUM(KEY_SAVE));
03773 #endif
03774 #ifdef KEY_SBEG
03775     /* Document-const: KEY_SBEG
03776      * Shifted beginning key
03777      */
03778     /* Document-const: SBEG
03779      * Shifted beginning key
03780      */
03781     rb_curses_define_const(KEY_SBEG);
03782     rb_define_const(mKey, "SBEG", INT2NUM(KEY_SBEG));
03783 #endif
03784 #ifdef KEY_SCANCEL
03785     /* Document-const: KEY_SCANCEL
03786      * Shifted cancel key
03787      */
03788     /* Document-const: SCANCEL
03789      * Shifted cancel key
03790      */
03791     rb_curses_define_const(KEY_SCANCEL);
03792     rb_define_const(mKey, "SCANCEL", INT2NUM(KEY_SCANCEL));
03793 #endif
03794 #ifdef KEY_SCOMMAND
03795     /* Document-const: KEY_SCOMMAND
03796      * Shifted command key
03797      */
03798     /* Document-const: SCOMMAND
03799      * Shifted command key
03800      */
03801     rb_curses_define_const(KEY_SCOMMAND);
03802     rb_define_const(mKey, "SCOMMAND", INT2NUM(KEY_SCOMMAND));
03803 #endif
03804 #ifdef KEY_SCOPY
03805     /* Document-const: KEY_SCOPY
03806      * Shifted copy key
03807      */
03808     /* Document-const: SCOPY
03809      * Shifted copy key
03810      */
03811     rb_curses_define_const(KEY_SCOPY);
03812     rb_define_const(mKey, "SCOPY", INT2NUM(KEY_SCOPY));
03813 #endif
03814 #ifdef KEY_SCREATE
03815     /* Document-const: KEY_SCREATE
03816      * Shifted create key
03817      */
03818     /* Document-const: SCREATE
03819      * Shifted create key
03820      */
03821     rb_curses_define_const(KEY_SCREATE);
03822     rb_define_const(mKey, "SCREATE", INT2NUM(KEY_SCREATE));
03823 #endif
03824 #ifdef KEY_SDC
03825     /* Document-const: KEY_SDC
03826      * Shifted delete char key
03827      */
03828     /* Document-const: SDC
03829      * Shifted delete char key
03830      */
03831     rb_curses_define_const(KEY_SDC);
03832     rb_define_const(mKey, "SDC", INT2NUM(KEY_SDC));
03833 #endif
03834 #ifdef KEY_SDL
03835     /* Document-const: KEY_SDL
03836      * Shifted delete line key
03837      */
03838     /* Document-const: SDL
03839      * Shifted delete line key
03840      */
03841     rb_curses_define_const(KEY_SDL);
03842     rb_define_const(mKey, "SDL", INT2NUM(KEY_SDL));
03843 #endif
03844 #ifdef KEY_SELECT
03845     /* Document-const: KEY_SELECT
03846      * Select key
03847      */
03848     /* Document-const: SELECT
03849      * Select key
03850      */
03851     rb_curses_define_const(KEY_SELECT);
03852     rb_define_const(mKey, "SELECT", INT2NUM(KEY_SELECT));
03853 #endif
03854 #ifdef KEY_SEND
03855     /* Document-const: KEY_SEND
03856      * Shifted end key
03857      */
03858     /* Document-const: SEND
03859      * Shifted end key
03860      */
03861     rb_curses_define_const(KEY_SEND);
03862     rb_define_const(mKey, "SEND", INT2NUM(KEY_SEND));
03863 #endif
03864 #ifdef KEY_SEOL
03865     /* Document-const: KEY_SEOL
03866      * Shifted clear line key
03867      */
03868     /* Document-const: SEOL
03869      * Shifted clear line key
03870      */
03871     rb_curses_define_const(KEY_SEOL);
03872     rb_define_const(mKey, "SEOL", INT2NUM(KEY_SEOL));
03873 #endif
03874 #ifdef KEY_SEXIT
03875     /* Document-const: KEY_SEXIT
03876      * Shifted exit key
03877      */
03878     /* Document-const: SEXIT
03879      * Shifted exit key
03880      */
03881     rb_curses_define_const(KEY_SEXIT);
03882     rb_define_const(mKey, "SEXIT", INT2NUM(KEY_SEXIT));
03883 #endif
03884 #ifdef KEY_SFIND
03885     /* Document-const: KEY_SFIND
03886      * Shifted find key
03887      */
03888     /* Document-const: SFIND
03889      * Shifted find key
03890      */
03891     rb_curses_define_const(KEY_SFIND);
03892     rb_define_const(mKey, "SFIND", INT2NUM(KEY_SFIND));
03893 #endif
03894 #ifdef KEY_SHELP
03895     /* Document-const: KEY_SHELP
03896      * Shifted help key
03897      */
03898     /* Document-const: SHELP
03899      * Shifted help key
03900      */
03901     rb_curses_define_const(KEY_SHELP);
03902     rb_define_const(mKey, "SHELP", INT2NUM(KEY_SHELP));
03903 #endif
03904 #ifdef KEY_SHOME
03905     /* Document-const: KEY_SHOME
03906      * Shifted home key
03907      */
03908     /* Document-const: SHOME
03909      * Shifted home key
03910      */
03911     rb_curses_define_const(KEY_SHOME);
03912     rb_define_const(mKey, "SHOME", INT2NUM(KEY_SHOME));
03913 #endif
03914 #ifdef KEY_SIC
03915     /* Document-const: KEY_SIC
03916      * Shifted input key
03917      */
03918     /* Document-const: SIC
03919      * Shifted input key
03920      */
03921     rb_curses_define_const(KEY_SIC);
03922     rb_define_const(mKey, "SIC", INT2NUM(KEY_SIC));
03923 #endif
03924 #ifdef KEY_SLEFT
03925     /* Document-const: KEY_SLEFT
03926      * Shifted left arrow key
03927      */
03928     /* Document-const: SLEFT
03929      * Shifted left arrow key
03930      */
03931     rb_curses_define_const(KEY_SLEFT);
03932     rb_define_const(mKey, "SLEFT", INT2NUM(KEY_SLEFT));
03933 #endif
03934 #ifdef KEY_SMESSAGE
03935     /* Document-const: KEY_SMESSAGE
03936      * Shifted message key
03937      */
03938     /* Document-const: SMESSAGE
03939      * Shifted message key
03940      */
03941     rb_curses_define_const(KEY_SMESSAGE);
03942     rb_define_const(mKey, "SMESSAGE", INT2NUM(KEY_SMESSAGE));
03943 #endif
03944 #ifdef KEY_SMOVE
03945     /* Document-const: KEY_SMOVE
03946      * Shifted move key
03947      */
03948     /* Document-const: SMOVE
03949      * Shifted move key
03950      */
03951     rb_curses_define_const(KEY_SMOVE);
03952     rb_define_const(mKey, "SMOVE", INT2NUM(KEY_SMOVE));
03953 #endif
03954 #ifdef KEY_SNEXT
03955     /* Document-const: KEY_SNEXT
03956      * Shifted next key
03957      */
03958     /* Document-const: SNEXT
03959      * Shifted next key
03960      */
03961     rb_curses_define_const(KEY_SNEXT);
03962     rb_define_const(mKey, "SNEXT", INT2NUM(KEY_SNEXT));
03963 #endif
03964 #ifdef KEY_SOPTIONS
03965     /* Document-const: KEY_SOPTIONS
03966      * Shifted options key
03967      */
03968     /* Document-const: SOPTIONS
03969      * Shifted options key
03970      */
03971     rb_curses_define_const(KEY_SOPTIONS);
03972     rb_define_const(mKey, "SOPTIONS", INT2NUM(KEY_SOPTIONS));
03973 #endif
03974 #ifdef KEY_SPREVIOUS
03975     /* Document-const: KEY_SPREVIOUS
03976      * Shifted previous key
03977      */
03978     /* Document-const: SPREVIOUS
03979      * Shifted previous key
03980      */
03981     rb_curses_define_const(KEY_SPREVIOUS);
03982     rb_define_const(mKey, "SPREVIOUS", INT2NUM(KEY_SPREVIOUS));
03983 #endif
03984 #ifdef KEY_SPRINT
03985     /* Document-const: KEY_SPRINT
03986      * Shifted print key
03987      */
03988     /* Document-const: SPRINT
03989      * Shifted print key
03990      */
03991     rb_curses_define_const(KEY_SPRINT);
03992     rb_define_const(mKey, "SPRINT", INT2NUM(KEY_SPRINT));
03993 #endif
03994 #ifdef KEY_SREDO
03995     /* Document-const: KEY_SREDO
03996      * Shifted redo key
03997      */
03998     /* Document-const: SREDO
03999      * Shifted redo key
04000      */
04001     rb_curses_define_const(KEY_SREDO);
04002     rb_define_const(mKey, "SREDO", INT2NUM(KEY_SREDO));
04003 #endif
04004 #ifdef KEY_SREPLACE
04005     /* Document-const: KEY_SREPLACE
04006      * Shifted replace key
04007      */
04008     /* Document-const: SREPLACE
04009      * Shifted replace key
04010      */
04011     rb_curses_define_const(KEY_SREPLACE);
04012     rb_define_const(mKey, "SREPLACE", INT2NUM(KEY_SREPLACE));
04013 #endif
04014 #ifdef KEY_SRIGHT
04015     /* Document-const: KEY_SRIGHT
04016      * Shifted right arrow key
04017      */
04018     /* Document-const: SRIGHT
04019      * Shifted right arrow key
04020      */
04021     rb_curses_define_const(KEY_SRIGHT);
04022     rb_define_const(mKey, "SRIGHT", INT2NUM(KEY_SRIGHT));
04023 #endif
04024 #ifdef KEY_SRSUME
04025     /* Document-const: KEY_SRSUME
04026      * Shifted resume key
04027      */
04028     /* Document-const: SRSUME
04029      * Shifted resume key
04030      */
04031     rb_curses_define_const(KEY_SRSUME);
04032     rb_define_const(mKey, "SRSUME", INT2NUM(KEY_SRSUME));
04033 #endif
04034 #ifdef KEY_SSAVE
04035     /* Document-const: KEY_SSAVE
04036      * Shifted save key
04037      */
04038     /* Document-const: SSAVE
04039      * Shifted save key
04040      */
04041     rb_curses_define_const(KEY_SSAVE);
04042     rb_define_const(mKey, "SSAVE", INT2NUM(KEY_SSAVE));
04043 #endif
04044 #ifdef KEY_SSUSPEND
04045     /* Document-const: KEY_SSUSPEND
04046      * Shifted suspend key
04047      */
04048     /* Document-const: SSUSPEND
04049      * Shifted suspend key
04050      */
04051     rb_curses_define_const(KEY_SSUSPEND);
04052     rb_define_const(mKey, "SSUSPEND", INT2NUM(KEY_SSUSPEND));
04053 #endif
04054 #ifdef KEY_SUNDO
04055     /* Document-const: KEY_SUNDO
04056      * Shifted undo key
04057      */
04058     /* Document-const: SUNDO
04059      * Shifted undo key
04060      */
04061     rb_curses_define_const(KEY_SUNDO);
04062     rb_define_const(mKey, "SUNDO", INT2NUM(KEY_SUNDO));
04063 #endif
04064 #ifdef KEY_SUSPEND
04065     /* Document-const: KEY_SUSPEND
04066      * Suspend key
04067      */
04068     /* Document-const: SUSPEND
04069      * Suspend key
04070      */
04071     rb_curses_define_const(KEY_SUSPEND);
04072     rb_define_const(mKey, "SUSPEND", INT2NUM(KEY_SUSPEND));
04073 #endif
04074 #ifdef KEY_UNDO
04075     /* Document-const: KEY_UNDO
04076      * Undo key
04077      */
04078     /* Document-const: UNDO
04079      * Undo key
04080      */
04081     rb_curses_define_const(KEY_UNDO);
04082     rb_define_const(mKey, "UNDO", INT2NUM(KEY_UNDO));
04083 #endif
04084 #ifdef KEY_RESIZE
04085     /* Document-const: KEY_RESIZE
04086      * Screen Resized
04087      */
04088     /* Document-const: RESIZE
04089      * Screen Resized
04090      */
04091     rb_curses_define_const(KEY_RESIZE);
04092     rb_define_const(mKey, "RESIZE", INT2NUM(KEY_RESIZE));
04093 #endif
04094 #ifdef KEY_MAX
04095     /* Document-const: KEY_MAX
04096      * The maximum allowed curses key value.
04097      */
04098     /* Document-const: MAX
04099      * The maximum allowed curses key value.
04100      */
04101     rb_curses_define_const(KEY_MAX);
04102     rb_define_const(mKey, "MAX", INT2NUM(KEY_MAX));
04103 #endif
04104     {
04105         int c;
04106         char name[] = "KEY_CTRL_x";
04107         for (c = 'A'; c <= 'Z'; c++) {
04108             name[sizeof(name) - 2] = c;
04109             rb_define_const(mCurses, name, INT2FIX(c - 'A' + 1));
04110         }
04111     }
04112 #undef rb_curses_define_const
04113 
04114     rb_set_end_proc(curses_finalize, 0);
04115 }
04116