1/* -*- C -*- 2 * $Id: curses.c 40388 2013-04-19 17:39:44Z nagachika $ 3 * 4 * ext/curses/curses.c 5 * 6 * by MAEDA Shugo (ender@pic-internet.or.jp) 7 * modified by Yukihiro Matsumoto (matz@netlab.co.jp), 8 * Toki Yoshinori, 9 * Hitoshi Takahashi, 10 * and Takaaki Tateishi (ttate@kt.jaist.ac.jp) 11 * 12 * maintainers: 13 * - Takaaki Tateishi (ttate@kt.jaist.ac.jp) 14 * 15 * doumentation: 16 * - Vincent Batts (vbatts@hashbangbash.com) 17 */ 18 19#include "ruby.h" 20#include "ruby/io.h" 21#include "ruby/thread.h" 22 23#if defined(HAVE_NCURSES_H) 24# include <ncurses.h> 25#elif defined(HAVE_NCURSES_CURSES_H) 26# include <ncurses/curses.h> 27#elif defined(HAVE_CURSES_COLR_CURSES_H) 28# ifdef HAVE_STDARG_PROTOTYPES 29# include <stdarg.h> 30# else 31# include <varargs.h> 32# endif 33# include <curses_colr/curses.h> 34#else 35# include <curses.h> 36# if defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__) 37# if !defined(_maxx) 38# define _maxx maxx 39# endif 40# if !defined(_maxy) 41# define _maxy maxy 42# endif 43# if !defined(_begx) 44# define _begx begx 45# endif 46# if !defined(_begy) 47# define _begy begy 48# endif 49# endif 50#endif 51 52#ifdef HAVE_INIT_COLOR 53# define USE_COLOR 1 54#endif 55 56/* supports only ncurses mouse routines */ 57#ifdef NCURSES_MOUSE_VERSION 58# define USE_MOUSE 1 59#endif 60 61#define NUM2CH NUM2CHR 62#define CH2FIX CHR2FIX 63 64static VALUE mCurses; 65static VALUE mKey; 66static VALUE cWindow; 67static VALUE cPad; 68#ifdef USE_MOUSE 69static VALUE cMouseEvent; 70#endif 71 72static VALUE rb_stdscr; 73 74struct windata { 75 WINDOW *window; 76}; 77 78static VALUE window_attroff(VALUE obj, VALUE attrs); 79static VALUE window_attron(VALUE obj, VALUE attrs); 80static VALUE window_attrset(VALUE obj, VALUE attrs); 81 82static void 83no_window(void) 84{ 85 rb_raise(rb_eRuntimeError, "already closed window"); 86} 87 88#define GetWINDOW(obj, winp) do {\ 89 if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\ 90 rb_raise(rb_eSecurityError, "Insecure: operation on untainted window");\ 91 TypedData_Get_Struct((obj), struct windata, &windata_type, (winp));\ 92 if ((winp)->window == 0) no_window();\ 93} while (0) 94 95static void 96window_free(void *p) 97{ 98 struct windata *winp = p; 99 if (winp->window && winp->window != stdscr) delwin(winp->window); 100 winp->window = 0; 101 xfree(winp); 102} 103 104static size_t 105window_memsize(const void *p) 106{ 107 const struct windata *winp = p; 108 size_t size = sizeof(*winp); 109 if (!winp) return 0; 110 if (winp->window && winp->window != stdscr) size += sizeof(winp->window); 111 return size; 112} 113 114static const rb_data_type_t windata_type = { 115 "windata", 116 {0, window_free, window_memsize,} 117}; 118 119static VALUE 120prep_window(VALUE class, WINDOW *window) 121{ 122 VALUE obj; 123 struct windata *winp; 124 125 if (window == NULL) { 126 rb_raise(rb_eRuntimeError, "failed to create window"); 127 } 128 129 obj = rb_obj_alloc(class); 130 TypedData_Get_Struct(obj, struct windata, &windata_type, winp); 131 winp->window = window; 132 133 return obj; 134} 135 136/*-------------------------- module Curses --------------------------*/ 137 138/* 139 * Document-method: Curses.init_screen 140 * 141 * Initialize a standard screen 142 * 143 * see also Curses.stdscr 144 */ 145static VALUE 146curses_init_screen(void) 147{ 148 rb_secure(4); 149 if (rb_stdscr) return rb_stdscr; 150 initscr(); 151 if (stdscr == 0) { 152 rb_raise(rb_eRuntimeError, "can't initialize curses"); 153 } 154 clear(); 155 rb_stdscr = prep_window(cWindow, stdscr); 156 return rb_stdscr; 157} 158 159/* 160 * Document-method: Curses.stdscr 161 * 162 * The Standard Screen. 163 * 164 * Upon initializing curses, a default window called stdscr, 165 * which is the size of the terminal screen, is created. 166 * 167 * Many curses functions use this window. 168 */ 169#define curses_stdscr curses_init_screen 170 171/* 172 * Document-method: Curses.close_screen 173 * 174 * A program should always call Curses.close_screen before exiting or 175 * escaping from curses mode temporarily. This routine 176 * restores tty modes, moves the cursor to the lower 177 * left-hand corner of the screen and resets the terminal 178 * into the proper non-visual mode. 179 * 180 * Calling Curses.refresh or Curses.doupdate after a temporary 181 * escape causes the program to resume visual mode. 182 * 183 */ 184static VALUE 185curses_close_screen(void) 186{ 187 curses_stdscr(); 188#ifdef HAVE_ISENDWIN 189 if (!isendwin()) 190#endif 191 endwin(); 192 rb_stdscr = 0; 193 return Qnil; 194} 195 196/* 197 * This is no runtime method, 198 * but a function called before the proc ends 199 * 200 * Similar to Curses.close_screen, except that it also 201 * garbage collects/unregisters the Curses.stdscr 202 */ 203static void 204curses_finalize(VALUE dummy) 205{ 206 if (stdscr 207#ifdef HAVE_ISENDWIN 208 && !isendwin() 209#endif 210 ) 211 endwin(); 212 rb_stdscr = 0; 213 rb_gc_unregister_address(&rb_stdscr); 214} 215 216#ifdef HAVE_ISENDWIN 217/* 218 * Document-method: Curses.closed? 219 * 220 * Returns +true+ if the window/screen has been closed, 221 * without any subsequent Curses.refresh calls, 222 * returns +false+ otherwise. 223 */ 224static VALUE 225curses_closed(void) 226{ 227 curses_stdscr(); 228 if (isendwin()) { 229 return Qtrue; 230 } 231 return Qfalse; 232} 233#else 234#define curses_closed rb_f_notimplement 235#endif 236 237/* 238 * Document-method: Curses.clear 239 * 240 * Clears every position on the screen completely, 241 * so that a subsequent call by Curses.refresh for the screen/window 242 * will be repainted from scratch. 243 */ 244static VALUE 245curses_clear(VALUE obj) 246{ 247 curses_stdscr(); 248 wclear(stdscr); 249 return Qnil; 250} 251 252/* 253 * Document-method: Curses.clrtoeol 254 * 255 * Clears to the end of line, that the cursor is currently on. 256 */ 257static VALUE 258curses_clrtoeol(void) 259{ 260 curses_stdscr(); 261 clrtoeol(); 262 return Qnil; 263} 264 265/* 266 * Document-method: Curses.refresh 267 * 268 * Refreshes the windows and lines. 269 * 270 */ 271static VALUE 272curses_refresh(VALUE obj) 273{ 274 curses_stdscr(); 275 refresh(); 276 return Qnil; 277} 278 279/* 280 * Document-method: Curses.doupdate 281 * 282 * Refreshes the windows and lines. 283 * 284 * Curses.doupdate allows multiple updates with 285 * more efficiency than Curses.refresh alone. 286 */ 287static VALUE 288curses_doupdate(VALUE obj) 289{ 290 curses_stdscr(); 291#ifdef HAVE_DOUPDATE 292 doupdate(); 293#else 294 refresh(); 295#endif 296 return Qnil; 297} 298 299/* 300 * Document-method: Curses.echo 301 * 302 * Enables characters typed by the user 303 * to be echoed by Curses.getch as they are typed. 304 */ 305static VALUE 306curses_echo(VALUE obj) 307{ 308 curses_stdscr(); 309 echo(); 310 return Qnil; 311} 312 313/* 314 * Document-method: Curses.noecho 315 * 316 * Disables characters typed by the user 317 * to be echoed by Curses.getch as they are typed. 318 */ 319static VALUE 320curses_noecho(VALUE obj) 321{ 322 curses_stdscr(); 323 noecho(); 324 return Qnil; 325} 326 327/* 328 * Document-method: Curses.raw 329 * 330 * Put the terminal into raw mode. 331 * 332 * Raw mode is similar to Curses.cbreak mode, in that characters typed 333 * are immediately passed through to the user program. 334 * 335 * The differences are that in raw mode, the interrupt, quit, 336 * suspend, and flow control characters are all passed through 337 * uninterpreted, instead of generating a signal. The behavior 338 * of the BREAK key depends on other bits in the tty driver 339 * that are not set by curses. 340 */ 341static VALUE 342curses_raw(VALUE obj) 343{ 344 curses_stdscr(); 345 raw(); 346 return Qnil; 347} 348 349/* 350 * Document-method: Curses.noraw 351 * 352 * Put the terminal out of raw mode. 353 * 354 * see Curses.raw for more detail 355 */ 356static VALUE 357curses_noraw(VALUE obj) 358{ 359 curses_stdscr(); 360 noraw(); 361 return Qnil; 362} 363 364/* 365 * Document-method: Curses.cbreak 366 * 367 * Put the terminal into cbreak mode. 368 * 369 * Normally, the tty driver buffers typed characters until 370 * a newline or carriage return is typed. The Curses.cbreak 371 * routine disables line buffering and erase/kill 372 * character-processing (interrupt and flow control characters 373 * are unaffected), making characters typed by the user 374 * immediately available to the program. 375 * 376 * The Curses.nocbreak routine returns the terminal to normal (cooked) mode. 377 * 378 * Initially the terminal may or may not be in cbreak mode, 379 * as the mode is inherited; therefore, a program should 380 * call Curses.cbreak or Curses.nocbreak explicitly. 381 * Most interactive programs using curses set the cbreak mode. 382 * Note that Curses.cbreak overrides Curses.raw. 383 * 384 * see also Curses.raw 385 */ 386static VALUE 387curses_cbreak(VALUE obj) 388{ 389 curses_stdscr(); 390 cbreak(); 391 return Qnil; 392} 393 394/* 395 * Document-method: Curses.nocbreak 396 * 397 * Put the terminal into normal mode (out of cbreak mode). 398 * 399 * See Curses.cbreak for more detail. 400 */ 401static VALUE 402curses_nocbreak(VALUE obj) 403{ 404 curses_stdscr(); 405 nocbreak(); 406 return Qnil; 407} 408 409/* 410 * Document-method: Curses.nl 411 * 412 * Enable the underlying display device to translate 413 * the return key into newline on input, and whether it 414 * translates newline into return and line-feed on output 415 * (in either case, the call Curses.addch('\n') does the 416 * equivalent of return and line feed on the virtual screen). 417 * 418 * Initially, these translations do occur. If you disable 419 * them using Curses.nonl, curses will be able to make better use 420 * of the line-feed capability, resulting in faster cursor 421 * motion. Also, curses will then be able to detect the return key. 422 */ 423static VALUE 424curses_nl(VALUE obj) 425{ 426 curses_stdscr(); 427 nl(); 428 return Qnil; 429} 430 431/* 432 * Document-method: Curses.nl 433 * 434 * Disable the underlying display device to translate 435 * the return key into newline on input 436 * 437 * See Curses.nl for more detail 438 */ 439static VALUE 440curses_nonl(VALUE obj) 441{ 442 curses_stdscr(); 443 nonl(); 444 return Qnil; 445} 446 447/* 448 * Document-method: Curses.beep 449 * 450 * Sounds an audible alarm on the terminal, if possible; 451 * otherwise it flashes the screen (visual bell). 452 * 453 * see also Curses.flash 454 */ 455static VALUE 456curses_beep(VALUE obj) 457{ 458#ifdef HAVE_BEEP 459 curses_stdscr(); 460 beep(); 461#endif 462 return Qnil; 463} 464 465/* 466 * Document-method: Curses.flash 467 * 468 * Flashs the screen, for visual alarm on the terminal, if possible; 469 * otherwise it sounds the alert. 470 * 471 * see also Curses.beep 472 */ 473static VALUE 474curses_flash(VALUE obj) 475{ 476#ifdef HAVE_FLASH 477 curses_stdscr(); 478 flash(); 479#endif 480 return Qnil; 481} 482 483static int 484curses_char(VALUE c) 485{ 486 if (FIXNUM_P(c)) { 487 return NUM2INT(c); 488 } 489 else { 490 int cc; 491 492 StringValue(c); 493 if (RSTRING_LEN(c) == 0 || RSTRING_LEN(c) > 1) { 494 rb_raise(rb_eArgError, "string not corresponding a character"); 495 } 496 cc = RSTRING_PTR(c)[0]; 497 if (cc > 0x7f) { 498 rb_raise(rb_eArgError, "no multibyte string supported (yet)"); 499 } 500 return cc; 501 } 502} 503 504#ifdef HAVE_UNGETCH 505/* 506 * Document-method: Curses.ungetch 507 * call-seq: ungetch(ch) 508 * 509 * Places +ch+ back onto the input queue to be returned by 510 * the next call to Curses.getch. 511 * 512 * There is just one input queue for all windows. 513 */ 514static VALUE 515curses_ungetch(VALUE obj, VALUE ch) 516{ 517 int c = curses_char(ch); 518 curses_stdscr(); 519 ungetch(c); 520 return Qnil; 521} 522#else 523#define curses_ungetch rb_f_notimplement 524#endif 525 526/* 527 * Document-method: Curses.setpos 528 * call-seq: setpos(y, x) 529 * 530 * A setter for the position of the cursor, 531 * using coordinates +x+ and +y+ 532 * 533 */ 534static VALUE 535curses_setpos(VALUE obj, VALUE y, VALUE x) 536{ 537 curses_stdscr(); 538 move(NUM2INT(y), NUM2INT(x)); 539 return Qnil; 540} 541 542/* 543 * Document-method: Curses.standout 544 * 545 * Enables the best highlighting mode of the terminal. 546 * 547 * This is equivalent to Curses:Window.attron(A_STANDOUT) 548 * 549 * see also Curses::Window.attrset additional information 550 */ 551static VALUE 552curses_standout(VALUE obj) 553{ 554 curses_stdscr(); 555 standout(); 556 return Qnil; 557} 558 559/* 560 * Document-method: Curses.standend 561 * 562 * Enables the Normal display (no highlight) 563 * 564 * This is equivalent to Curses.attron(A_NORMAL) 565 * 566 * see also Curses::Window.attrset for additional information. 567 */ 568static VALUE 569curses_standend(VALUE obj) 570{ 571 curses_stdscr(); 572 standend(); 573 return Qnil; 574} 575 576/* 577 * Document-method: Curses.inch 578 * 579 * Returns the character at the current position. 580 */ 581static VALUE 582curses_inch(VALUE obj) 583{ 584 curses_stdscr(); 585 return CH2FIX(inch()); 586} 587 588/* 589 * Document-method: Curses.addch 590 * call-seq: addch(ch) 591 * 592 * Add a character +ch+, with attributes, then advance the cursor. 593 * 594 * see also the system manual for curs_addch(3) 595 */ 596static VALUE 597curses_addch(VALUE obj, VALUE ch) 598{ 599 curses_stdscr(); 600 addch(NUM2CH(ch)); 601 return Qnil; 602} 603 604/* 605 * Document-method: Curses.insch 606 * call-seq: insch(ch) 607 * 608 * Insert a character +ch+, before the cursor. 609 * 610 */ 611static VALUE 612curses_insch(VALUE obj, VALUE ch) 613{ 614 curses_stdscr(); 615 insch(NUM2CH(ch)); 616 return Qnil; 617} 618 619/* 620 * Document-method: Curses.addstr 621 * call-seq: addstr(str) 622 * 623 * add a string of characters +str+, to the window and advance cursor 624 * 625 */ 626static VALUE 627curses_addstr(VALUE obj, VALUE str) 628{ 629 StringValue(str); 630 str = rb_str_export_locale(str); 631 curses_stdscr(); 632 if (!NIL_P(str)) { 633 addstr(StringValueCStr(str)); 634 } 635 return Qnil; 636} 637 638static void * 639getch_func(void *arg) 640{ 641 int *ip = (int *)arg; 642 *ip = getch(); 643 return 0; 644} 645 646/* 647 * Document-method: Curses.getch 648 * 649 * Read and returns a character from the window. 650 * 651 * See Curses::Key to all the function KEY_* available 652 * 653 */ 654static VALUE 655curses_getch(VALUE obj) 656{ 657 int c; 658 659 curses_stdscr(); 660 rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0); 661 if (c == EOF) return Qnil; 662 if (rb_isprint(c)) { 663 char ch = (char)c; 664 665 return rb_locale_str_new(&ch, 1); 666 } 667 return UINT2NUM(c); 668} 669 670/* This should be big enough.. I hope */ 671#define GETSTR_BUF_SIZE 1024 672 673static void * 674getstr_func(void *arg) 675{ 676 char *rtn = (char *)arg; 677#if defined(HAVE_GETNSTR) 678 getnstr(rtn,GETSTR_BUF_SIZE-1); 679#else 680 getstr(rtn); 681#endif 682 return 0; 683} 684 685/* 686 * Document-method: Curses.getstr 687 * 688 * This is equivalent to a series f Curses::Window.getch calls 689 * 690 */ 691static VALUE 692curses_getstr(VALUE obj) 693{ 694 char rtn[GETSTR_BUF_SIZE]; 695 696 curses_stdscr(); 697 rb_thread_call_without_gvl(getstr_func, rtn, RUBY_UBF_IO, 0); 698 return rb_locale_str_new_cstr(rtn); 699} 700 701/* 702 * Document-method: Curses.delch 703 * 704 * Delete the character under the cursor 705 * 706 */ 707static VALUE 708curses_delch(VALUE obj) 709{ 710 curses_stdscr(); 711 delch(); 712 return Qnil; 713} 714 715/* 716 * Document-method: Curses.deleteln 717 * 718 * Delete the line under the cursor. 719 * 720 */ 721static VALUE 722curses_deleteln(VALUE obj) 723{ 724 curses_stdscr(); 725#if defined(HAVE_DELETELN) || defined(deleteln) 726 deleteln(); 727#endif 728 return Qnil; 729} 730 731/* 732 * Document-method: Curses.insertln 733 * 734 * Inserts a line above the cursor, and the bottom line is lost 735 * 736 */ 737static VALUE 738curses_insertln(VALUE obj) 739{ 740 curses_stdscr(); 741#if defined(HAVE_INSERTLN) || defined(insertln) 742 insertln(); 743#endif 744 return Qnil; 745} 746 747/* 748 * Document-method: Curses.keyname 749 * call-seq: keyname(c) 750 * 751 * Returns the character string corresponding to key +c+ 752 */ 753static VALUE 754curses_keyname(VALUE obj, VALUE c) 755{ 756#ifdef HAVE_KEYNAME 757 int cc = curses_char(c); 758 const char *name; 759 760 curses_stdscr(); 761 name = keyname(cc); 762 if (name) { 763 return rb_str_new_cstr(name); 764 } 765 else { 766 return Qnil; 767 } 768#else 769 return Qnil; 770#endif 771} 772 773/* 774 * Document-method: Curses.lines 775 * 776 * Returns the number of lines on the screen 777 */ 778static VALUE 779curses_lines(void) 780{ 781 return INT2FIX(LINES); 782} 783 784/* 785 * Document-method: Curses.cols 786 * 787 * Returns the number of columns on the screen 788 */ 789static VALUE 790curses_cols(void) 791{ 792 return INT2FIX(COLS); 793} 794 795/* 796 * Document-method: Curses.curs_set 797 * call-seq: curs_set(visibility) 798 * 799 * Sets Cursor Visibility. 800 * 0: invisible 801 * 1: visible 802 * 2: very visible 803 */ 804static VALUE 805curses_curs_set(VALUE obj, VALUE visibility) 806{ 807#ifdef HAVE_CURS_SET 808 int n; 809 curses_stdscr(); 810 return (n = curs_set(NUM2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil; 811#else 812 return Qnil; 813#endif 814} 815 816/* 817 * Document-method: Curses.scrl 818 * call-seq: scrl(num) 819 * 820 * Scrolls the current window Fixnum +num+ lines. 821 * The current cursor position is not changed. 822 * 823 * For positive +num+, it scrolls up. 824 * 825 * For negative +num+, it scrolls down. 826 * 827 */ 828static VALUE 829curses_scrl(VALUE obj, VALUE n) 830{ 831 /* may have to raise exception on ERR */ 832#ifdef HAVE_SCRL 833 curses_stdscr(); 834 return (scrl(NUM2INT(n)) == OK) ? Qtrue : Qfalse; 835#else 836 return Qfalse; 837#endif 838} 839 840/* 841 * Document-method: Curses.setscrreg 842 * 843 * call-seq: 844 * setscrreg(top, bottom) 845 * 846 * Set a software scrolling region in a window. 847 * +top+ and +bottom+ are lines numbers of the margin. 848 * 849 * If this option and Curses.scrollok are enabled, an attempt to move off 850 * the bottom margin line causes all lines in the scrolling region 851 * to scroll one line in the direction of the first line. 852 * Only the text of the window is scrolled. 853 * 854 */ 855static VALUE 856curses_setscrreg(VALUE obj, VALUE top, VALUE bottom) 857{ 858 /* may have to raise exception on ERR */ 859#ifdef HAVE_SETSCRREG 860 curses_stdscr(); 861 return (setscrreg(NUM2INT(top), NUM2INT(bottom)) == OK) ? Qtrue : Qfalse; 862#else 863 return Qfalse; 864#endif 865} 866 867/* 868 * Document-method: Curses.attroff 869 * call-seq: attroff(attrs) 870 * 871 * Turns on the named attributes +attrs+ without affecting any others. 872 * 873 * See also Curses::Window.attrset for additional information. 874 */ 875static VALUE 876curses_attroff(VALUE obj, VALUE attrs) 877{ 878 curses_stdscr(); 879 return window_attroff(rb_stdscr,attrs); 880 /* return INT2FIX(attroff(NUM2INT(attrs))); */ 881} 882 883/* 884 * Document-method: Curses.attron 885 * call-seq: attron(attrs) 886 * 887 * Turns off the named attributes +attrs+ 888 * without turning any other attributes on or off. 889 * 890 * See also Curses::Window.attrset for additional information. 891 */ 892static VALUE 893curses_attron(VALUE obj, VALUE attrs) 894{ 895 curses_stdscr(); 896 return window_attron(rb_stdscr,attrs); 897 /* return INT2FIX(attroff(NUM2INT(attrs))); */ 898} 899 900/* 901 * Document-method: Curses.attrset 902 * call-seq: attrset(attrs) 903 * 904 * Sets the current attributes of the given window to +attrs+. 905 * 906 * see also Curses::Window.attrset 907 * 908 */ 909static VALUE 910curses_attrset(VALUE obj, VALUE attrs) 911{ 912 curses_stdscr(); 913 return window_attrset(rb_stdscr,attrs); 914 /* return INT2FIX(attroff(NUM2INT(attrs))); */ 915} 916 917/* 918 * Document-method: Curses.bkgdset 919 * call-seq: bkgdset(ch) 920 * 921 * Manipulate the background of the named window 922 * with character Integer +ch+ 923 * 924 * The background becomes a property of the character 925 * and moves with the character through any scrolling 926 * and insert/delete line/character operations. 927 * 928 * see also the system manual for curs_bkgd(3) 929 */ 930static VALUE 931curses_bkgdset(VALUE obj, VALUE ch) 932{ 933#ifdef HAVE_BKGDSET 934 curses_stdscr(); 935 bkgdset(NUM2CH(ch)); 936#endif 937 return Qnil; 938} 939 940/* 941 * call-seq: bkgd(ch) 942 * 943 * Window background manipulation routines. 944 * 945 * Set the background property of the current 946 * and then apply the character Integer +ch+ setting 947 * to every character position in that window. 948 * 949 * see also the system manual for curs_bkgd(3) 950 */ 951static VALUE 952curses_bkgd(VALUE obj, VALUE ch) 953{ 954#ifdef HAVE_BKGD 955 curses_stdscr(); 956 return (bkgd(NUM2CH(ch)) == OK) ? Qtrue : Qfalse; 957#else 958 return Qfalse; 959#endif 960} 961 962#if defined(HAVE_USE_DEFAULT_COLORS) 963/* 964 * tells the curses library to use terminal's default colors. 965 * 966 * see also the system manual for default_colors(3) 967 */ 968static VALUE 969curses_use_default_colors(VALUE obj) 970{ 971 curses_stdscr(); 972 use_default_colors(); 973 return Qnil; 974} 975#else 976#define curses_use_default_colors rb_f_notimplement 977#endif 978 979#if defined(HAVE_TABSIZE) 980/* 981 * Document-method: Curses.TABSIZE= 982 * call-seq: TABSIZE=(value) 983 * 984 * Sets the TABSIZE to Integer +value+ 985 */ 986static VALUE 987curses_tabsize_set(VALUE obj, VALUE val) 988{ 989 TABSIZE = NUM2INT(val); 990 return INT2NUM(TABSIZE); 991} 992#else 993#define curses_tabsize_set rb_f_notimplement 994#endif 995 996#if defined(HAVE_TABSIZE) 997/* 998 * Returns the number of positions in a tab. 999 */ 1000static VALUE 1001curses_tabsize_get(VALUE ojb) 1002{ 1003 return INT2NUM(TABSIZE); 1004} 1005#else 1006#define curses_tabsize_get rb_f_notimplement 1007#endif 1008 1009#if defined(HAVE_ESCDELAY) 1010/* 1011 * call-seq: Curses.ESCDELAY=(value) 1012 * 1013 * Sets the ESCDELAY to Integer +value+ 1014 */ 1015static VALUE 1016curses_escdelay_set(VALUE obj, VALUE val) 1017{ 1018 ESCDELAY = NUM2INT(val); 1019 return INT2NUM(ESCDELAY); 1020} 1021#else 1022#define curses_escdelay_set rb_f_notimplement 1023#endif 1024 1025#if defined(HAVE_ESCDELAY) 1026/* 1027 * Returns the total time, in milliseconds, for which 1028 * curses will await a character sequence, e.g., a function key 1029 */ 1030static VALUE 1031curses_escdelay_get(VALUE obj) 1032{ 1033 return INT2NUM(ESCDELAY); 1034} 1035#else 1036#define curses_escdelay_get rb_f_notimplement 1037#endif 1038 1039/* 1040 * Document-method: Curses.resize 1041 * call-seq: resize(lines, cols) 1042 * 1043 * alias for Curses.resizeterm 1044 * 1045 */ 1046 1047/* 1048 * Document-method: Curses.resizeterm 1049 * call-seq: resizeterm(lines, cols) 1050 * 1051 * Resize the current term to Fixnum +lines+ and Fixnum +cols+ 1052 * 1053 */ 1054static VALUE 1055curses_resizeterm(VALUE obj, VALUE lin, VALUE col) 1056{ 1057#if defined(HAVE_RESIZETERM) 1058 curses_stdscr(); 1059 return (resizeterm(NUM2INT(lin),NUM2INT(col)) == OK) ? Qtrue : Qfalse; 1060#else 1061 return Qnil; 1062#endif 1063} 1064 1065#ifdef USE_COLOR 1066/* 1067 * Document-method: Curses.start_color 1068 * 1069 * Initializes the color attributes, for terminals that support it. 1070 * 1071 * This must be called, in order to use color attributes. 1072 * It is good practice to call it just after Curses.init_screen 1073 */ 1074static VALUE 1075curses_start_color(VALUE obj) 1076{ 1077 /* may have to raise exception on ERR */ 1078 curses_stdscr(); 1079 return (start_color() == OK) ? Qtrue : Qfalse; 1080} 1081 1082/* 1083 * Document-method: Curses.init_pair 1084 * call-seq: init_pair(pair, f, b) 1085 * 1086 * Changes the definition of a color-pair. 1087 * 1088 * It takes three arguments: the number of the color-pair to be changed +pair+, 1089 * the foreground color number +f+, and the background color number +b+. 1090 * 1091 * If the color-pair was previously initialized, the screen is 1092 * refreshed and all occurrences of that color-pair are changed 1093 * to the new definition. 1094 * 1095 */ 1096static VALUE 1097curses_init_pair(VALUE obj, VALUE pair, VALUE f, VALUE b) 1098{ 1099 /* may have to raise exception on ERR */ 1100 curses_stdscr(); 1101 return (init_pair(NUM2INT(pair),NUM2INT(f),NUM2INT(b)) == OK) ? Qtrue : Qfalse; 1102} 1103 1104/* 1105 * Document-method: Curses.init_color 1106 * call-seq: init_color(color, r, g, b) 1107 * 1108 * Changes the definition of a color. It takes four arguments: 1109 * * the number of the color to be changed, +color+ 1110 * * the amount of red, +r+ 1111 * * the amount of green, +g+ 1112 * * the amount of blue, +b+ 1113 * 1114 * The value of the first argument must be between 0 and COLORS. 1115 * (See the section Colors for the default color index.) Each 1116 * of the last three arguments must be a value between 0 and 1000. 1117 * When Curses.init_color is used, all occurrences of that color 1118 * on the screen immediately change to the new definition. 1119 */ 1120static VALUE 1121curses_init_color(VALUE obj, VALUE color, VALUE r, VALUE g, VALUE b) 1122{ 1123 /* may have to raise exception on ERR */ 1124 curses_stdscr(); 1125 return (init_color(NUM2INT(color),NUM2INT(r), 1126 NUM2INT(g),NUM2INT(b)) == OK) ? Qtrue : Qfalse; 1127} 1128 1129/* 1130 * Document-method: Curses.has_colors? 1131 * 1132 * Returns +true+ or +false+ depending on whether the terminal has color capbilities. 1133 */ 1134static VALUE 1135curses_has_colors(VALUE obj) 1136{ 1137 curses_stdscr(); 1138 return has_colors() ? Qtrue : Qfalse; 1139} 1140 1141/* 1142 * Document-method: Curses.can_change_color? 1143 * 1144 * Returns +true+ or +false+ depending on whether the terminal can change color attributes 1145 */ 1146static VALUE 1147curses_can_change_color(VALUE obj) 1148{ 1149 curses_stdscr(); 1150 return can_change_color() ? Qtrue : Qfalse; 1151} 1152 1153#if defined(HAVE_COLORS) 1154/* 1155 * Document-method: Curses.color 1156 * 1157 * returns COLORS 1158 */ 1159static VALUE 1160curses_colors(VALUE obj) 1161{ 1162 return INT2FIX(COLORS); 1163} 1164#else 1165#define curses_colors rb_f_notimplement 1166#endif 1167 1168/* 1169 * Document-method: Curses.color_content 1170 * call-seq: color_content(color) 1171 * 1172 * Returns an 3 item Array of the RGB values in +color+ 1173 */ 1174static VALUE 1175curses_color_content(VALUE obj, VALUE color) 1176{ 1177 short r,g,b; 1178 1179 curses_stdscr(); 1180 color_content(NUM2INT(color),&r,&g,&b); 1181 return rb_ary_new3(3,INT2FIX(r),INT2FIX(g),INT2FIX(b)); 1182} 1183 1184 1185#if defined(HAVE_COLOR_PAIRS) 1186/* 1187 * Document-method: Curses.color_pairs 1188 * 1189 * Returns the COLOR_PAIRS available, if the curses library supports it. 1190 */ 1191static VALUE 1192curses_color_pairs(VALUE obj) 1193{ 1194 return INT2FIX(COLOR_PAIRS); 1195} 1196#else 1197#define curses_color_pairs rb_f_notimplement 1198#endif 1199 1200/* 1201 * Document-method: Curses.pair_content 1202 * call-seq: pair_content(pair) 1203 * 1204 * Returns a 2 item Array, with the foreground and 1205 * background color, in +pair+ 1206 */ 1207static VALUE 1208curses_pair_content(VALUE obj, VALUE pair) 1209{ 1210 short f,b; 1211 1212 curses_stdscr(); 1213 pair_content(NUM2INT(pair),&f,&b); 1214 return rb_ary_new3(2,INT2FIX(f),INT2FIX(b)); 1215} 1216 1217/* 1218 * Document-method: Curses.color_pair 1219 * call-seq: color_pair(attrs) 1220 * 1221 * Sets the color pair attributes to +attrs+. 1222 * 1223 * This should be equivalent to Curses.attrset(COLOR_PAIR(+attrs+)) 1224 * 1225 * TODO: validate that equivalency 1226 */ 1227static VALUE 1228curses_color_pair(VALUE obj, VALUE attrs) 1229{ 1230 return INT2FIX(COLOR_PAIR(NUM2INT(attrs))); 1231} 1232 1233/* 1234 * Document-method: Curses.pair_number 1235 * call-seq: pair_number(attrs) 1236 * 1237 * Returns the Fixnum color pair number of attributes +attrs+. 1238 */ 1239static VALUE 1240curses_pair_number(VALUE obj, VALUE attrs) 1241{ 1242 curses_stdscr(); 1243 return INT2FIX(PAIR_NUMBER(NUM2LONG(attrs))); 1244} 1245#endif /* USE_COLOR */ 1246 1247#ifdef USE_MOUSE 1248struct mousedata { 1249 MEVENT *mevent; 1250}; 1251 1252static void 1253no_mevent(void) 1254{ 1255 rb_raise(rb_eRuntimeError, "no such mouse event"); 1256} 1257 1258#define GetMOUSE(obj, data) do {\ 1259 if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\ 1260 rb_raise(rb_eSecurityError, "Insecure: operation on untainted mouse");\ 1261 TypedData_Get_Struct((obj), struct mousedata, &mousedata_type, (data));\ 1262 if ((data)->mevent == 0) no_mevent();\ 1263} while (0) 1264 1265static void 1266curses_mousedata_free(void *p) 1267{ 1268 struct mousedata *mdata = p; 1269 if (mdata->mevent) 1270 xfree(mdata->mevent); 1271} 1272 1273static size_t 1274curses_mousedata_memsize(const void *p) 1275{ 1276 const struct mousedata *mdata = p; 1277 size_t size = sizeof(*mdata); 1278 if (!mdata) return 0; 1279 if (mdata->mevent) size += sizeof(mdata->mevent); 1280 return size; 1281} 1282 1283static const rb_data_type_t mousedata_type = { 1284 "mousedata", 1285 {0, curses_mousedata_free, curses_mousedata_memsize,} 1286}; 1287 1288/* 1289 * Document-method: Curses.getmouse 1290 * 1291 * Returns coordinates of the mouse. 1292 * 1293 * This will read and pop the mouse event data off the queue 1294 * 1295 * See the BUTTON*, ALL_MOUSE_EVENTS and REPORT_MOUSE_POSITION constants, to examine the mask of the event 1296 */ 1297static VALUE 1298curses_getmouse(VALUE obj) 1299{ 1300 struct mousedata *mdata; 1301 VALUE val; 1302 1303 curses_stdscr(); 1304 val = TypedData_Make_Struct(cMouseEvent,struct mousedata, 1305 &mousedata_type,mdata); 1306 mdata->mevent = (MEVENT*)xmalloc(sizeof(MEVENT)); 1307 return (getmouse(mdata->mevent) == OK) ? val : Qnil; 1308} 1309 1310/* 1311 * Document-method: Curses.ungetmouse 1312 * 1313 * It pushes a KEY_MOUSE event onto the input queue, and associates with that 1314 * event the given state data and screen-relative character-cell coordinates. 1315 * 1316 * The Curses.ungetmouse function behaves analogously to Curses.ungetch. 1317 */ 1318static VALUE 1319curses_ungetmouse(VALUE obj, VALUE mevent) 1320{ 1321 struct mousedata *mdata; 1322 1323 curses_stdscr(); 1324 GetMOUSE(mevent,mdata); 1325 return (ungetmouse(mdata->mevent) == OK) ? Qtrue : Qfalse; 1326} 1327 1328/* 1329 * Document-method: Curses.mouseinterval 1330 * call-seq: mouseinterval(interval) 1331 * 1332 * The Curses.mouseinterval function sets the maximum time 1333 * (in thousands of a second) that can elapse between press 1334 * and release events for them to be recognized as a click. 1335 * 1336 * Use Curses.mouseinterval(0) to disable click resolution. 1337 * This function returns the previous interval value. 1338 * 1339 * Use Curses.mouseinterval(-1) to obtain the interval without 1340 * altering it. 1341 * 1342 * The default is one sixth of a second. 1343 */ 1344static VALUE 1345curses_mouseinterval(VALUE obj, VALUE interval) 1346{ 1347 curses_stdscr(); 1348 return mouseinterval(NUM2INT(interval)) ? Qtrue : Qfalse; 1349} 1350 1351/* 1352 * Document-method: Curses.mousemask 1353 * call-seq: mousemask(mask) 1354 * 1355 * Returns the +mask+ of the reportable events 1356 */ 1357static VALUE 1358curses_mousemask(VALUE obj, VALUE mask) 1359{ 1360 curses_stdscr(); 1361 return INT2NUM(mousemask(NUM2UINT(mask),NULL)); 1362} 1363 1364#define DEFINE_MOUSE_GET_MEMBER(func_name,mem) \ 1365static VALUE func_name (VALUE mouse) \ 1366{ \ 1367 struct mousedata *mdata; \ 1368 GetMOUSE(mouse, mdata); \ 1369 return (UINT2NUM(mdata->mevent -> mem)); \ 1370} 1371 1372/* 1373 * Document-method: Curses::MouseEvent.eid 1374 * 1375 * Returns the current mouse id 1376 */ 1377DEFINE_MOUSE_GET_MEMBER(curs_mouse_id, id) 1378/* 1379 * Document-method: Curses::MouseEvent.x 1380 * 1381 * Returns the current mouse's X coordinate 1382 */ 1383DEFINE_MOUSE_GET_MEMBER(curs_mouse_x, x) 1384/* 1385 * Document-method: Curses::MouseEvent.y 1386 * 1387 * Returns the current mouse's Y coordinate 1388 */ 1389DEFINE_MOUSE_GET_MEMBER(curs_mouse_y, y) 1390/* 1391 * Document-method: Curses::MouseEvent.z 1392 * 1393 * Returns the current mouse's Z coordinate 1394 */ 1395DEFINE_MOUSE_GET_MEMBER(curs_mouse_z, z) 1396/* 1397 * Document-method: Curses::MouseEvent.bstate 1398 * 1399 * Returns the current mouse's button state. Use this with the button state 1400 * constants to determine which buttons were pressed. 1401 */ 1402DEFINE_MOUSE_GET_MEMBER(curs_mouse_bstate, bstate) 1403#undef define_curs_mouse_member 1404#endif /* USE_MOUSE */ 1405 1406#ifdef HAVE_TIMEOUT 1407/* 1408 * Document-method: Curses.timeout= 1409 * call-seq: timeout=(delay) 1410 * 1411 * Sets block and non-blocking reads for the window. 1412 * - If delay is negative, blocking read is used (i.e., waits indefinitely for input). 1413 * - If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting). 1414 * - If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input. 1415 * 1416 */ 1417static VALUE 1418curses_timeout(VALUE obj, VALUE delay) 1419{ 1420 curses_stdscr(); 1421 timeout(NUM2INT(delay)); 1422 return Qnil; 1423} 1424#else 1425#define curses_timeout rb_f_notimplement 1426#endif 1427 1428#ifdef HAVE_DEF_PROG_MODE 1429/* 1430 * Document-method: Curses.def_prog_mode 1431 * 1432 * Save the current terminal modes as the "program" 1433 * state for use by the Curses.reset_prog_mode 1434 * 1435 * This is done automatically by Curses.init_screen 1436 */ 1437static VALUE 1438curses_def_prog_mode(VALUE obj) 1439{ 1440 curses_stdscr(); 1441 return def_prog_mode() == OK ? Qtrue : Qfalse; 1442} 1443#else 1444#define curses_def_prog_mode rb_f_notimplement 1445#endif 1446 1447#ifdef HAVE_RESET_PROG_MODE 1448/* 1449 * Document-method: Curses.reset_prog_mode 1450 * 1451 * Reset the current terminal modes to the saved state 1452 * by the Curses.def_prog_mode 1453 * 1454 * This is done automatically by Curses.close_screen 1455 */ 1456static VALUE 1457curses_reset_prog_mode(VALUE obj) 1458{ 1459 curses_stdscr(); 1460 return reset_prog_mode() == OK ? Qtrue : Qfalse; 1461} 1462#else 1463#define curses_reset_prog_mode rb_f_notimplement 1464#endif 1465 1466/*-------------------------- class Window --------------------------*/ 1467 1468/* returns a Curses::Window object */ 1469static VALUE 1470window_s_allocate(VALUE class) 1471{ 1472 struct windata *winp; 1473 1474 return TypedData_Make_Struct(class, struct windata, &windata_type, winp); 1475} 1476 1477/* 1478 * Document-method: Curses::Window.new 1479 * call-seq: new(height, width, top, left) 1480 * 1481 * Contruct a new Curses::Window with constraints of 1482 * +height+ lines, +width+ columns, begin at +top+ line, and begin +left+ most column. 1483 * 1484 * A new window using full screen is called as 1485 * Curses::Window.new(0,0,0,0) 1486 * 1487 */ 1488static VALUE 1489window_initialize(VALUE obj, VALUE h, VALUE w, VALUE top, VALUE left) 1490{ 1491 struct windata *winp; 1492 WINDOW *window; 1493 1494 rb_secure(4); 1495 curses_init_screen(); 1496 TypedData_Get_Struct(obj, struct windata, &windata_type, winp); 1497 if (winp->window) delwin(winp->window); 1498 window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left)); 1499 wclear(window); 1500 winp->window = window; 1501 1502 return obj; 1503} 1504 1505/* 1506 * Document-method: Curses::Window.subwin 1507 * call-seq: subwin(height, width, top, left) 1508 * 1509 * Contruct a new subwindow with constraints of 1510 * +height+ lines, +width+ columns, begin at +top+ line, and begin +left+ most column. 1511 * 1512 */ 1513static VALUE 1514window_subwin(VALUE obj, VALUE height, VALUE width, VALUE top, VALUE left) 1515{ 1516 struct windata *winp; 1517 WINDOW *window; 1518 VALUE win; 1519 int h, w, t, l; 1520 1521 h = NUM2INT(height); 1522 w = NUM2INT(width); 1523 t = NUM2INT(top); 1524 l = NUM2INT(left); 1525 GetWINDOW(obj, winp); 1526 window = subwin(winp->window, h, w, t, l); 1527 win = prep_window(rb_obj_class(obj), window); 1528 1529 return win; 1530} 1531 1532/* 1533 * Document-method: Curses::Window.close 1534 * 1535 * Deletes the window, and frees the memory 1536 */ 1537static VALUE 1538window_close(VALUE obj) 1539{ 1540 struct windata *winp; 1541 1542 GetWINDOW(obj, winp); 1543 delwin(winp->window); 1544 winp->window = 0; 1545 1546 return Qnil; 1547} 1548 1549/* 1550 * Document-method: Curses::Window.clear 1551 * 1552 * Clear the window. 1553 */ 1554static VALUE 1555window_clear(VALUE obj) 1556{ 1557 struct windata *winp; 1558 1559 GetWINDOW(obj, winp); 1560 wclear(winp->window); 1561 1562 return Qnil; 1563} 1564 1565/* 1566 * Document-method: Curses::Window.clrtoeol 1567 * 1568 * Clear the window to the end of line, that the cursor is currently on. 1569 */ 1570static VALUE 1571window_clrtoeol(VALUE obj) 1572{ 1573 struct windata *winp; 1574 1575 GetWINDOW(obj, winp); 1576 wclrtoeol(winp->window); 1577 1578 return Qnil; 1579} 1580 1581/* 1582 * Document-method: Curses::Window.refresh 1583 * 1584 * Refreshes the windows and lines. 1585 * 1586 */ 1587static VALUE 1588window_refresh(VALUE obj) 1589{ 1590 struct windata *winp; 1591 1592 GetWINDOW(obj, winp); 1593 wrefresh(winp->window); 1594 1595 return Qnil; 1596} 1597 1598/* 1599 * Document-method: Curses::Window.noutrefresh 1600 * 1601 * Refreshes the windows and lines. 1602 * 1603 * Curses::Window.noutrefresh allows multiple updates with 1604 * more efficiency than Curses::Window.refresh alone. 1605 */ 1606static VALUE 1607window_noutrefresh(VALUE obj) 1608{ 1609 struct windata *winp; 1610 1611 GetWINDOW(obj, winp); 1612#ifdef HAVE_DOUPDATE 1613 wnoutrefresh(winp->window); 1614#else 1615 wrefresh(winp->window); 1616#endif 1617 1618 return Qnil; 1619} 1620 1621/* 1622 * Document-method: Curses::Window.move 1623 * call-seq: move(y,x) 1624 * 1625 * Moves the window so that the upper left-hand corner is at position (+y+, +x+) 1626 */ 1627static VALUE 1628window_move(VALUE obj, VALUE y, VALUE x) 1629{ 1630 struct windata *winp; 1631 1632 GetWINDOW(obj, winp); 1633 mvwin(winp->window, NUM2INT(y), NUM2INT(x)); 1634 1635 return Qnil; 1636} 1637 1638/* 1639 * Document-method: Curses::Window.setpos 1640 * call-seq: setpos(y, x) 1641 * 1642 * A setter for the position of the cursor 1643 * in the current window, 1644 * using coordinates +x+ and +y+ 1645 * 1646 */ 1647static VALUE 1648window_setpos(VALUE obj, VALUE y, VALUE x) 1649{ 1650 struct windata *winp; 1651 1652 GetWINDOW(obj, winp); 1653 wmove(winp->window, NUM2INT(y), NUM2INT(x)); 1654 return Qnil; 1655} 1656 1657/* 1658 * Document-method: Curses::Window.cury 1659 * 1660 * A getter for the current line (Y coord) of the window 1661 */ 1662static VALUE 1663window_cury(VALUE obj) 1664{ 1665 struct windata *winp; 1666 int RB_UNUSED_VAR(x), y; 1667 1668 GetWINDOW(obj, winp); 1669 getyx(winp->window, y, x); 1670 return INT2FIX(y); 1671} 1672 1673/* 1674 * Document-method: Curses::Window.curx 1675 * 1676 * A getter for the current column (X coord) of the window 1677 */ 1678static VALUE 1679window_curx(VALUE obj) 1680{ 1681 struct windata *winp; 1682 int x, RB_UNUSED_VAR(y); 1683 1684 GetWINDOW(obj, winp); 1685 getyx(winp->window, y, x); 1686 return INT2FIX(x); 1687} 1688 1689/* 1690 * Document-method: Curses::Window.maxy 1691 * 1692 * A getter for the maximum lines for the window 1693 */ 1694static VALUE 1695window_maxy(VALUE obj) 1696{ 1697 struct windata *winp; 1698 1699 GetWINDOW(obj, winp); 1700#if defined(getmaxy) 1701 return INT2FIX(getmaxy(winp->window)); 1702#elif defined(getmaxyx) 1703 { 1704 int x, y; 1705 getmaxyx(winp->window, y, x); 1706 return INT2FIX(y); 1707 } 1708#else 1709 return INT2FIX(winp->window->_maxy+1); 1710#endif 1711} 1712 1713/* 1714 * Document-method: Curses::Window.maxx 1715 * 1716 * A getter for the maximum columns for the window 1717 */ 1718static VALUE 1719window_maxx(VALUE obj) 1720{ 1721 struct windata *winp; 1722 1723 GetWINDOW(obj, winp); 1724#if defined(getmaxx) 1725 return INT2FIX(getmaxx(winp->window)); 1726#elif defined(getmaxyx) 1727 { 1728 int x, y; 1729 getmaxyx(winp->window, y, x); 1730 return INT2FIX(x); 1731 } 1732#else 1733 return INT2FIX(winp->window->_maxx+1); 1734#endif 1735} 1736 1737/* 1738 * Document-method: Curses::Window.begy 1739 * 1740 * A getter for the beginning line (Y coord) of the window 1741 */ 1742static VALUE 1743window_begy(VALUE obj) 1744{ 1745 struct windata *winp; 1746 int RB_UNUSED_VAR(x), y; 1747 1748 GetWINDOW(obj, winp); 1749#ifdef getbegyx 1750 getbegyx(winp->window, y, x); 1751#else 1752 y = winp->window->_begy; 1753#endif 1754 return INT2FIX(y); 1755} 1756 1757/* 1758 * Document-method: Curses::Window.begx 1759 * 1760 * A getter for the beginning column (X coord) of the window 1761 */ 1762static VALUE 1763window_begx(VALUE obj) 1764{ 1765 struct windata *winp; 1766 int x, RB_UNUSED_VAR(y); 1767 1768 GetWINDOW(obj, winp); 1769#ifdef getbegyx 1770 getbegyx(winp->window, y, x); 1771#else 1772 x = winp->window->_begx; 1773#endif 1774 return INT2FIX(x); 1775} 1776 1777/* 1778 * Document-method: Curses::Window.box 1779 * call-seq: box(vert, hor) 1780 * 1781 * set the characters to frame the window in. 1782 * The vertical +vert+ and horizontal +hor+ character. 1783 * 1784 * win = Curses::Window.new(5,5,5,5) 1785 * win.box(?|, ?-) 1786 * 1787 */ 1788static VALUE 1789window_box(int argc, VALUE *argv, VALUE self) 1790{ 1791 struct windata *winp; 1792 VALUE vert, hor, corn; 1793 1794 rb_scan_args(argc, argv, "21", &vert, &hor, &corn); 1795 1796 GetWINDOW(self, winp); 1797 box(winp->window, NUM2CH(vert), NUM2CH(hor)); 1798 1799 if (!NIL_P(corn)) { 1800 int cur_x, cur_y, x, y; 1801 chtype c; 1802 1803 c = NUM2CH(corn); 1804 getyx(winp->window, cur_y, cur_x); 1805 x = NUM2INT(window_maxx(self)) - 1; 1806 y = NUM2INT(window_maxy(self)) - 1; 1807 wmove(winp->window, 0, 0); 1808 waddch(winp->window, c); 1809 wmove(winp->window, y, 0); 1810 waddch(winp->window, c); 1811 wmove(winp->window, y, x); 1812 waddch(winp->window, c); 1813 wmove(winp->window, 0, x); 1814 waddch(winp->window, c); 1815 wmove(winp->window, cur_y, cur_x); 1816 } 1817 1818 return Qnil; 1819} 1820 1821/* 1822 * Document-method: Curses::Window.standout 1823 * 1824 * Enables the best highlighting mode of the terminal. 1825 * 1826 * This is equivalent to Curses::Window.attron(A_STANDOUT) 1827 * 1828 * see also Curses::Window.attrset 1829 */ 1830static VALUE 1831window_standout(VALUE obj) 1832{ 1833 struct windata *winp; 1834 1835 GetWINDOW(obj, winp); 1836 wstandout(winp->window); 1837 return Qnil; 1838} 1839 1840/* 1841 * Document-method: Curses::Window.standend 1842 * 1843 * Enables the Normal display (no highlight) 1844 * 1845 * This is equivalent to Curses::Window.attron(A_NORMAL) 1846 * 1847 * see also Curses::Window.attrset 1848 */ 1849static VALUE 1850window_standend(VALUE obj) 1851{ 1852 struct windata *winp; 1853 1854 GetWINDOW(obj, winp); 1855 wstandend(winp->window); 1856 return Qnil; 1857} 1858 1859/* 1860 * Document-method: Curses::Window.inch 1861 * 1862 * Returns the character at the current position of the window. 1863 */ 1864static VALUE 1865window_inch(VALUE obj) 1866{ 1867 struct windata *winp; 1868 1869 GetWINDOW(obj, winp); 1870 return CH2FIX(winch(winp->window)); 1871} 1872 1873/* 1874 * Document-method: Curses::Window.addch 1875 * call-seq: addch(ch) 1876 * 1877 * Add a character +ch+, with attributes, to the window, then advance the cursor. 1878 * 1879 * see also the system manual for curs_addch(3) 1880 */ 1881static VALUE 1882window_addch(VALUE obj, VALUE ch) 1883{ 1884 struct windata *winp; 1885 1886 GetWINDOW(obj, winp); 1887 waddch(winp->window, NUM2CH(ch)); 1888 1889 return Qnil; 1890} 1891 1892/* 1893 * Document-method: Curses::Window.insch 1894 * call-seq: insch(ch) 1895 * 1896 * Insert a character +ch+, before the cursor, in the current window 1897 * 1898 */ 1899static VALUE 1900window_insch(VALUE obj, VALUE ch) 1901{ 1902 struct windata *winp; 1903 1904 GetWINDOW(obj, winp); 1905 winsch(winp->window, NUM2CH(ch)); 1906 1907 return Qnil; 1908} 1909 1910/* 1911 * Document-method: Curses::Window.addstr 1912 * call-seq: addstr(str) 1913 * 1914 * add a string of characters +str+, to the window and advance cursor 1915 * 1916 */ 1917static VALUE 1918window_addstr(VALUE obj, VALUE str) 1919{ 1920 if (!NIL_P(str)) { 1921 struct windata *winp; 1922 1923 StringValue(str); 1924 str = rb_str_export_locale(str); 1925 GetWINDOW(obj, winp); 1926 waddstr(winp->window, StringValueCStr(str)); 1927 } 1928 return Qnil; 1929} 1930 1931/* 1932 * Document-method: Curses::Window.<< 1933 * 1934 * call-seq: 1935 * <<(str) 1936 * 1937 * Add String +str+ to the current string. 1938 * 1939 * See also Curses::Window.addstr 1940 */ 1941static VALUE 1942window_addstr2(VALUE obj, VALUE str) 1943{ 1944 window_addstr(obj, str); 1945 return obj; 1946} 1947 1948struct wgetch_arg { 1949 WINDOW *win; 1950 int c; 1951}; 1952 1953static void * 1954wgetch_func(void *_arg) 1955{ 1956 struct wgetch_arg *arg = (struct wgetch_arg *)_arg; 1957 arg->c = wgetch(arg->win); 1958 return 0; 1959} 1960 1961/* 1962 * Document-method: Curses::Window.getch 1963 * 1964 * Read and returns a character from the window. 1965 * 1966 * See Curses::Key to all the function KEY_* available 1967 * 1968 */ 1969static VALUE 1970window_getch(VALUE obj) 1971{ 1972 struct windata *winp; 1973 struct wgetch_arg arg; 1974 int c; 1975 1976 GetWINDOW(obj, winp); 1977 arg.win = winp->window; 1978 rb_thread_call_without_gvl(wgetch_func, (void *)&arg, RUBY_UBF_IO, 0); 1979 c = arg.c; 1980 if (c == EOF) return Qnil; 1981 if (rb_isprint(c)) { 1982 char ch = (char)c; 1983 1984 return rb_locale_str_new(&ch, 1); 1985 } 1986 return UINT2NUM(c); 1987} 1988 1989struct wgetstr_arg { 1990 WINDOW *win; 1991 char rtn[GETSTR_BUF_SIZE]; 1992}; 1993 1994static void * 1995wgetstr_func(void *_arg) 1996{ 1997 struct wgetstr_arg *arg = (struct wgetstr_arg *)_arg; 1998#if defined(HAVE_WGETNSTR) 1999 wgetnstr(arg->win, arg->rtn, GETSTR_BUF_SIZE-1); 2000#else 2001 wgetstr(arg->win, arg->rtn); 2002#endif 2003 return 0; 2004} 2005 2006/* 2007 * Document-method: Curses::Window.getstr 2008 * 2009 * This is equivalent to a series f Curses::Window.getch calls 2010 * 2011 */ 2012static VALUE 2013window_getstr(VALUE obj) 2014{ 2015 struct windata *winp; 2016 struct wgetstr_arg arg; 2017 2018 GetWINDOW(obj, winp); 2019 arg.win = winp->window; 2020 rb_thread_call_without_gvl(wgetstr_func, (void *)&arg, RUBY_UBF_IO, 0); 2021 return rb_locale_str_new_cstr(arg.rtn); 2022} 2023 2024/* 2025 * Document-method: Curses::Window.delch 2026 * 2027 * Delete the character under the cursor 2028 * 2029 */ 2030static VALUE 2031window_delch(VALUE obj) 2032{ 2033 struct windata *winp; 2034 2035 GetWINDOW(obj, winp); 2036 wdelch(winp->window); 2037 return Qnil; 2038} 2039 2040/* 2041 * Document-method: Curses::Window.deleteln 2042 * 2043 * Delete the line under the cursor. 2044 * 2045 */ 2046static VALUE 2047window_deleteln(VALUE obj) 2048{ 2049#if defined(HAVE_WDELETELN) || defined(wdeleteln) 2050 struct windata *winp; 2051 2052 GetWINDOW(obj, winp); 2053 wdeleteln(winp->window); 2054#endif 2055 return Qnil; 2056} 2057 2058/* 2059 * Document-method: Curses::Window.insertln 2060 * 2061 * Inserts a line above the cursor, and the bottom line is lost 2062 * 2063 */ 2064static VALUE 2065window_insertln(VALUE obj) 2066{ 2067#if defined(HAVE_WINSERTLN) || defined(winsertln) 2068 struct windata *winp; 2069 2070 GetWINDOW(obj, winp); 2071 winsertln(winp->window); 2072#endif 2073 return Qnil; 2074} 2075 2076/* 2077 * Document-method: Curses::Window.scrollok 2078 * call-seq: scrollok(bool) 2079 * 2080 * Controls what happens when the cursor of a window 2081 * is moved off the edge of the window or scrolling region, 2082 * either as a result of a newline action on the bottom line, 2083 * or typing the last character of the last line. 2084 * 2085 * If disabled, (+bool+ is false), the cursor is left on the bottom line. 2086 * 2087 * If enabled, (+bool+ is true), the window is scrolled up one line 2088 * (Note that to get the physical scrolling effect on the terminal, 2089 * it is also necessary to call Curses::Window.idlok) 2090 */ 2091static VALUE 2092window_scrollok(VALUE obj, VALUE bf) 2093{ 2094 struct windata *winp; 2095 2096 GetWINDOW(obj, winp); 2097 scrollok(winp->window, RTEST(bf) ? TRUE : FALSE); 2098 return Qnil; 2099} 2100 2101/* 2102 * Document-method: Curses::Window.idlok 2103 * call-seq: idlok(bool) 2104 * 2105 * If +bool+ is +true+ curses considers using the hardware insert/delete 2106 * line feature of terminals so equipped. 2107 * 2108 * If +bool+ is +false+, disables use of line insertion and deletion. 2109 * This option should be enabled only if the application needs insert/delete 2110 * line, for example, for a screen editor. 2111 * 2112 * It is disabled by default because insert/delete line tends to be visually 2113 * annoying when used in applications where it is not really needed. 2114 * If insert/delete line cannot be used, curses redraws the changed portions of all lines. 2115 * 2116 */ 2117static VALUE 2118window_idlok(VALUE obj, VALUE bf) 2119{ 2120 struct windata *winp; 2121 2122 GetWINDOW(obj, winp); 2123 idlok(winp->window, RTEST(bf) ? TRUE : FALSE); 2124 return Qnil; 2125} 2126 2127/* 2128 * Document-method: Curses::Window.setscrreg 2129 * call-seq: 2130 * setscrreg(top, bottom) 2131 * 2132 * Set a software scrolling region in a window. 2133 * +top+ and +bottom+ are lines numbers of the margin. 2134 * 2135 * If this option and Curses::Window.scrollok are enabled, an attempt to move 2136 * off the bottom margin line causes all lines in the scrolling region to 2137 * scroll one line in the direction of the first line. Only the text of the 2138 * window is scrolled. 2139 * 2140 */ 2141static VALUE 2142window_setscrreg(VALUE obj, VALUE top, VALUE bottom) 2143{ 2144#ifdef HAVE_WSETSCRREG 2145 struct windata *winp; 2146 int res; 2147 2148 GetWINDOW(obj, winp); 2149 res = wsetscrreg(winp->window, NUM2INT(top), NUM2INT(bottom)); 2150 /* may have to raise exception on ERR */ 2151 return (res == OK) ? Qtrue : Qfalse; 2152#else 2153 return Qfalse; 2154#endif 2155} 2156 2157#if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET) 2158/* 2159 * Document-method: Curses::Window.color_set 2160 * call-seq: color_set(col) 2161 * 2162 * Sets the current color of the given window to the 2163 * foreground/background combination described by the Fixnum +col+. 2164 */ 2165static VALUE 2166window_color_set(VALUE obj, VALUE col) 2167{ 2168 struct windata *winp; 2169 int res; 2170 2171 GetWINDOW(obj, winp); 2172 res = wcolor_set(winp->window, NUM2INT(col), NULL); 2173 return (res == OK) ? Qtrue : Qfalse; 2174} 2175#endif /* defined(USE_COLOR) && defined(HAVE_WCOLOR_SET) */ 2176 2177/* 2178 * Document-method: Curses::Window.scroll 2179 * 2180 * Scrolls the current window up one line. 2181 */ 2182static VALUE 2183window_scroll(VALUE obj) 2184{ 2185 struct windata *winp; 2186 2187 GetWINDOW(obj, winp); 2188 /* may have to raise exception on ERR */ 2189 return (scroll(winp->window) == OK) ? Qtrue : Qfalse; 2190} 2191 2192/* 2193 * Document-method: Curses::Window.scrl 2194 * call-seq: scrl(num) 2195 * 2196 * Scrolls the current window Fixnum +num+ lines. 2197 * The current cursor position is not changed. 2198 * 2199 * For positive +num+, it scrolls up. 2200 * 2201 * For negative +num+, it scrolls down. 2202 * 2203 */ 2204static VALUE 2205window_scrl(VALUE obj, VALUE n) 2206{ 2207#ifdef HAVE_WSCRL 2208 struct windata *winp; 2209 2210 GetWINDOW(obj, winp); 2211 /* may have to raise exception on ERR */ 2212 return (wscrl(winp->window,NUM2INT(n)) == OK) ? Qtrue : Qfalse; 2213#else 2214 return Qfalse; 2215#endif 2216} 2217 2218/* 2219 * Document-method: Curses::Window.attroff 2220 * call-seq: attroff(attrs) 2221 * 2222 * Turns on the named attributes +attrs+ without affecting any others. 2223 * 2224 * See also Curses::Window.attrset 2225 */ 2226static VALUE 2227window_attroff(VALUE obj, VALUE attrs) 2228{ 2229#ifdef HAVE_WATTROFF 2230 struct windata *winp; 2231 2232 GetWINDOW(obj,winp); 2233 return INT2FIX(wattroff(winp->window,NUM2INT(attrs))); 2234#else 2235 return Qtrue; 2236#endif 2237} 2238 2239/* 2240 * Document-method: Curses::Window.attron 2241 * call-seq: attron(attrs) 2242 * 2243 * Turns off the named attributes +attrs+ 2244 * without turning any other attributes on or off. 2245 * 2246 * See also Curses::Window.attrset 2247 */ 2248static VALUE 2249window_attron(VALUE obj, VALUE attrs) 2250{ 2251#ifdef HAVE_WATTRON 2252 struct windata *winp; 2253 VALUE val; 2254 2255 GetWINDOW(obj,winp); 2256 val = INT2FIX(wattron(winp->window,NUM2INT(attrs))); 2257 if (rb_block_given_p()) { 2258 rb_yield(val); 2259 wattroff(winp->window,NUM2INT(attrs)); 2260 return val; 2261 } 2262 else{ 2263 return val; 2264 } 2265#else 2266 return Qtrue; 2267#endif 2268} 2269 2270/* 2271 * Document-method: Curses::Window.attrset 2272 * call-seq: attrset(attrs) 2273 * 2274 * Sets the current attributes of the given window to +attrs+. 2275 * 2276 * The following video attributes, defined in <curses.h>, can 2277 * be passed to the routines Curses::Window.attron, Curses::Window.attroff, 2278 * and Curses::Window.attrset, or OR'd with the characters passed to addch. 2279 * A_NORMAL Normal display (no highlight) 2280 * A_STANDOUT Best highlighting mode of the terminal. 2281 * A_UNDERLINE Underlining 2282 * A_REVERSE Reverse video 2283 * A_BLINK Blinking 2284 * A_DIM Half bright 2285 * A_BOLD Extra bright or bold 2286 * A_PROTECT Protected mode 2287 * A_INVIS Invisible or blank mode 2288 * A_ALTCHARSET Alternate character set 2289 * A_CHARTEXT Bit-mask to extract a character 2290 * COLOR_PAIR(n) Color-pair number n 2291 * 2292 * TODO: provide some examples here. 2293 * 2294 * see also system manual curs_attr(3) 2295 */ 2296static VALUE 2297window_attrset(VALUE obj, VALUE attrs) 2298{ 2299#ifdef HAVE_WATTRSET 2300 struct windata *winp; 2301 2302 GetWINDOW(obj,winp); 2303 return INT2FIX(wattrset(winp->window,NUM2INT(attrs))); 2304#else 2305 return Qtrue; 2306#endif 2307} 2308 2309/* 2310 * Document-method: Curses::Window.bkgdset 2311 * call-seq: bkgdset(ch) 2312 * 2313 * Manipulate the background of the current window 2314 * with character Integer +ch+ 2315 * 2316 * see also Curses.bkgdset 2317 */ 2318static VALUE 2319window_bkgdset(VALUE obj, VALUE ch) 2320{ 2321#ifdef HAVE_WBKGDSET 2322 struct windata *winp; 2323 2324 GetWINDOW(obj,winp); 2325 wbkgdset(winp->window, NUM2CH(ch)); 2326#endif 2327 return Qnil; 2328} 2329 2330/* 2331 * Document-method: Curses::Window.bkgd 2332 * call-seq: bkgd(ch) 2333 * 2334 * Set the background of the current window 2335 * and apply character Integer +ch+ to every character. 2336 * 2337 * see also Curses.bkgd 2338 */ 2339static VALUE 2340window_bkgd(VALUE obj, VALUE ch) 2341{ 2342#ifdef HAVE_WBKGD 2343 struct windata *winp; 2344 2345 GetWINDOW(obj,winp); 2346 return (wbkgd(winp->window, NUM2CH(ch)) == OK) ? Qtrue : Qfalse; 2347#else 2348 return Qfalse; 2349#endif 2350} 2351 2352/* 2353 * Document-method: Curses::Window.getbkgd 2354 * 2355 * Returns an Interer (+ch+) for the character property in the current window. 2356 */ 2357static VALUE 2358window_getbkgd(VALUE obj) 2359{ 2360#ifdef HAVE_WGETBKGD 2361 chtype c; 2362 struct windata *winp; 2363 2364 GetWINDOW(obj,winp); 2365 return (c = getbkgd(winp->window) != ERR) ? CH2FIX(c) : Qnil; 2366#else 2367 return Qnil; 2368#endif 2369} 2370 2371/* 2372 * Document-method: Curses::Window.resize 2373 * call-seq: resize(lines, cols) 2374 * 2375 * Resize the current window to Fixnum +lines+ and Fixnum +cols+ 2376 * 2377 */ 2378static VALUE 2379window_resize(VALUE obj, VALUE lin, VALUE col) 2380{ 2381#if defined(HAVE_WRESIZE) 2382 struct windata *winp; 2383 2384 GetWINDOW(obj,winp); 2385 return wresize(winp->window, NUM2INT(lin), NUM2INT(col)) == OK ? Qtrue : Qfalse; 2386#else 2387 return Qnil; 2388#endif 2389} 2390 2391 2392#ifdef HAVE_KEYPAD 2393/* 2394 * Document-method: Curses::Window.keypad= 2395 * call-seq: 2396 * keypad=(bool) 2397 * 2398 * See Curses::Window.keypad 2399 */ 2400 2401/* 2402 * Document-method: Curses::Window.keypad 2403 * call-seq: 2404 * keypad(bool) 2405 * 2406 * Enables the keypad of the user's terminal. 2407 * 2408 * If enabled (+bool+ is +true+), the user can press a function key 2409 * (such as an arrow key) and wgetch returns a single value representing 2410 * the function key, as in KEY_LEFT. If disabled (+bool+ is +false+), 2411 * curses does not treat function keys specially and the program has to 2412 * interpret the escape sequences itself. If the keypad in the terminal 2413 * can be turned on (made to transmit) and off (made to work locally), 2414 * turning on this option causes the terminal keypad to be turned on when 2415 * Curses::Window.getch is called. 2416 * 2417 * The default value for keypad is false. 2418 * 2419 */ 2420static VALUE 2421window_keypad(VALUE obj, VALUE val) 2422{ 2423 struct windata *winp; 2424 2425 GetWINDOW(obj,winp); 2426 /* keypad() of NetBSD's libcurses returns no value */ 2427#if defined(__NetBSD__) && !defined(NCURSES_VERSION) 2428 keypad(winp->window,(RTEST(val) ? TRUE : FALSE)); 2429 return Qnil; 2430#else 2431 /* may have to raise exception on ERR */ 2432 return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ? 2433 Qtrue : Qfalse; 2434#endif 2435} 2436#else 2437#define window_keypad rb_f_notimplement 2438#endif 2439 2440#ifdef HAVE_NODELAY 2441/* 2442 * Document-method: Curses::Window.nodelay 2443 * call-seq: 2444 * window.nodelay = bool 2445 * 2446 * When in no-delay mode Curses::Window#getch is a non-blocking call. If no 2447 * input is ready #getch returns ERR. 2448 * 2449 * When in delay mode (+bool+ is +false+ which is the default), 2450 * Curses::Window#getch blocks until a key is pressed. 2451 * 2452 */ 2453static VALUE 2454window_nodelay(VALUE obj, VALUE val) 2455{ 2456 struct windata *winp; 2457 GetWINDOW(obj,winp); 2458 2459 /* nodelay() of NetBSD's libcurses returns no value */ 2460#if defined(__NetBSD__) && !defined(NCURSES_VERSION) 2461 nodelay(winp->window, RTEST(val) ? TRUE : FALSE); 2462 return Qnil; 2463#else 2464 return nodelay(winp->window,RTEST(val) ? TRUE : FALSE) == OK ? Qtrue : Qfalse; 2465#endif 2466} 2467#else 2468#define window_nodelay rb_f_notimplement 2469#endif 2470 2471#ifdef HAVE_WTIMEOUT 2472/* 2473 * Document-method: Curses::Window.timeout= 2474 * call-seq: timeout=(delay) 2475 * 2476 * Sets block and non-blocking reads for the window. 2477 * - If delay is negative, blocking read is used (i.e., waits indefinitely for input). 2478 * - If delay is zero, then non-blocking read is used (i.e., read returns ERR if no input is waiting). 2479 * - If delay is positive, then read blocks for delay milliseconds, and returns ERR if there is still no input. 2480 * 2481 */ 2482static VALUE 2483window_timeout(VALUE obj, VALUE delay) 2484{ 2485 struct windata *winp; 2486 GetWINDOW(obj,winp); 2487 2488 wtimeout(winp->window,NUM2INT(delay)); 2489 return Qnil; 2490} 2491#else 2492#define window_timeout rb_f_notimplement 2493#endif 2494 2495/*--------------------------- class Pad ----------------------------*/ 2496 2497#ifdef HAVE_NEWPAD 2498/* 2499 * Document-method: Curses::Pad.new 2500 * 2501 * call-seq: 2502 * new(height, width) 2503 * 2504 * Contruct a new Curses::Pad with constraints of +height+ lines, +width+ 2505 * columns 2506 * 2507 */ 2508static VALUE 2509pad_initialize(VALUE obj, VALUE h, VALUE w) 2510{ 2511 struct windata *padp; 2512 WINDOW *window; 2513 2514 rb_secure(4); 2515 curses_init_screen(); 2516 TypedData_Get_Struct(obj, struct windata, &windata_type, padp); 2517 if (padp->window) delwin(padp->window); 2518 window = newpad(NUM2INT(h), NUM2INT(w)); 2519 wclear(window); 2520 padp->window = window; 2521 2522 return obj; 2523} 2524 2525#if 1 2526#define pad_subpad window_subwin 2527#else 2528/* 2529 * Document-method: Curses::Pad.subpad 2530 * call-seq: 2531 * subpad(height, width, begin_x, begin_y) 2532 * 2533 * Contruct a new subpad with constraints of +height+ lines, +width+ columns, 2534 * begin at +begin_x+ line, and +begin_y+ columns on the pad. 2535 * 2536 */ 2537static VALUE 2538pad_subpad(VALUE obj, VALUE height, VALUE width, VALUE begin_x, VALUE begin_y) 2539{ 2540 struct windata *padp; 2541 WINDOW *subpad; 2542 VALUE pad; 2543 int h, w, x, y; 2544 2545 h = NUM2INT(height); 2546 w = NUM2INT(width); 2547 x = NUM2INT(begin_x); 2548 y = NUM2INT(begin_y); 2549 GetWINDOW(obj, padp); 2550 subpad = subwin(padp->window, h, w, x, y); 2551 pad = prep_window(rb_obj_class(obj), subpad); 2552 2553 return pad; 2554} 2555#endif 2556 2557/* 2558 * Document-method: Curses::Pad.refresh 2559 * 2560 * call-seq: 2561 * pad.refresh(pad_minrow, pad_mincol, screen_minrow, screen_mincol, screen_maxrow, screen_maxcol) 2562 * 2563 * Refreshes the pad. +pad_minrow+ and pad_mincol+ define the upper-left 2564 * corner of the rectangle to be displayed. +screen_minrow+, +screen_mincol+, 2565 * +screen_maxrow+, +screen_maxcol+ define the edges of the rectangle to be 2566 * displayed on the screen. 2567 * 2568 */ 2569static VALUE 2570pad_refresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow, 2571 VALUE smincol, VALUE smaxrow, VALUE smaxcol) 2572{ 2573 struct windata *padp; 2574 int pmr, pmc, smr, smc, sxr, sxc; 2575 2576 pmr = NUM2INT(pminrow); 2577 pmc = NUM2INT(pmincol); 2578 smr = NUM2INT(sminrow); 2579 smc = NUM2INT(smincol); 2580 sxr = NUM2INT(smaxrow); 2581 sxc = NUM2INT(smaxcol); 2582 2583 GetWINDOW(obj, padp); 2584 prefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc); 2585 2586 return Qnil; 2587} 2588 2589/* 2590 * Document-method: Curses::Pad.noutrefresh 2591 * 2592 * call-seq: 2593 * pad.noutrefresh(pad_minrow, pad_mincol, screen_minrow, screen_mincol, screen_maxrow, screen_maxcol) 2594 * 2595 * Refreshes the pad. +pad_minrow+ and pad_mincol+ define the upper-left 2596 * corner of the rectangle to be displayed. +screen_minrow+, +screen_mincol+, 2597 * +screen_maxrow+, +screen_maxcol+ define the edges of the rectangle to be 2598 * displayed on the screen. 2599 * 2600 */ 2601static VALUE 2602pad_noutrefresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow, 2603 VALUE smincol, VALUE smaxrow, VALUE smaxcol) 2604{ 2605 struct windata *padp; 2606 int pmr, pmc, smr, smc, sxr, sxc; 2607 2608 pmr = NUM2INT(pminrow); 2609 pmc = NUM2INT(pmincol); 2610 smr = NUM2INT(sminrow); 2611 smc = NUM2INT(smincol); 2612 sxr = NUM2INT(smaxrow); 2613 sxc = NUM2INT(smaxcol); 2614 2615 GetWINDOW(obj, padp); 2616#ifdef HAVE_DOUPDATE 2617 pnoutrefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc); 2618#else 2619 prefresh(padp->window, pmr, pmc, smr, smc, sxr, sxc); 2620#endif 2621 2622 return Qnil; 2623} 2624#endif /* HAVE_NEWPAD */ 2625 2626/*------------------------- Initialization -------------------------*/ 2627 2628/* 2629 * Document-module: Curses 2630 * 2631 * == Description 2632 * An implementation of the CRT screen handling and optimization library. 2633 * 2634 * == Structures and such 2635 * 2636 * === Classes 2637 * 2638 * * Curses::Window - class with the means to draw a window or box 2639 * * Curses::MouseEvent - class for collecting mouse events 2640 * 2641 * === Modules 2642 * 2643 * Curses:: The curses implementation 2644 * Curses::Key:: Collection of constants for keypress events 2645 * 2646 * == Examples 2647 * 2648 * * hello.rb 2649 * :include: hello.rb 2650 * 2651 * 2652 * * rain.rb 2653 * :include: rain.rb 2654 * 2655 * 2656 */ 2657void 2658Init_curses(void) 2659{ 2660 mCurses = rb_define_module("Curses"); 2661 2662 /* 2663 * Document-module: Curses::Key 2664 * 2665 * 2666 * a container for the KEY_* values. 2667 * 2668 * See also system manual for getch(3) 2669 * 2670 */ 2671 mKey = rb_define_module_under(mCurses, "Key"); 2672 2673 rb_gc_register_address(&rb_stdscr); 2674 2675#ifdef USE_MOUSE 2676 /* 2677 * Document-class: Curses::MouseEvent 2678 * 2679 * == Description 2680 * 2681 * Curses::MouseEvent 2682 * 2683 * == Example 2684 * 2685 * * mouse.rb 2686 * :include: mouse.rb 2687 * 2688 */ 2689 cMouseEvent = rb_define_class_under(mCurses,"MouseEvent",rb_cObject); 2690 rb_undef_method(CLASS_OF(cMouseEvent),"new"); 2691 rb_define_method(cMouseEvent, "eid", curs_mouse_id, 0); 2692 rb_define_method(cMouseEvent, "x", curs_mouse_x, 0); 2693 rb_define_method(cMouseEvent, "y", curs_mouse_y, 0); 2694 rb_define_method(cMouseEvent, "z", curs_mouse_z, 0); 2695 rb_define_method(cMouseEvent, "bstate", curs_mouse_bstate, 0); 2696#endif /* USE_MOUSE */ 2697 2698 rb_define_module_function(mCurses, "ESCDELAY=", curses_escdelay_set, 1); 2699 rb_define_module_function(mCurses, "ESCDELAY", curses_escdelay_get, 0); 2700 rb_define_module_function(mCurses, "TABSIZE", curses_tabsize_get, 0); 2701 rb_define_module_function(mCurses, "TABSIZE=", curses_tabsize_set, 1); 2702 2703 rb_define_module_function(mCurses, "use_default_colors", curses_use_default_colors, 0); 2704 rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0); 2705 rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0); 2706 rb_define_module_function(mCurses, "closed?", curses_closed, 0); 2707 rb_define_module_function(mCurses, "stdscr", curses_stdscr, 0); 2708 rb_define_module_function(mCurses, "refresh", curses_refresh, 0); 2709 rb_define_module_function(mCurses, "doupdate", curses_doupdate, 0); 2710 rb_define_module_function(mCurses, "clear", curses_clear, 0); 2711 rb_define_module_function(mCurses, "clrtoeol", curses_clrtoeol, 0); 2712 rb_define_module_function(mCurses, "echo", curses_echo, 0); 2713 rb_define_module_function(mCurses, "noecho", curses_noecho, 0); 2714 rb_define_module_function(mCurses, "raw", curses_raw, 0); 2715 rb_define_module_function(mCurses, "noraw", curses_noraw, 0); 2716 rb_define_module_function(mCurses, "cbreak", curses_cbreak, 0); 2717 rb_define_module_function(mCurses, "nocbreak", curses_nocbreak, 0); 2718 rb_define_module_function(mCurses, "crmode", curses_cbreak, 0); 2719 rb_define_module_function(mCurses, "nocrmode", curses_nocbreak, 0); 2720 rb_define_module_function(mCurses, "nl", curses_nl, 0); 2721 rb_define_module_function(mCurses, "nonl", curses_nonl, 0); 2722 rb_define_module_function(mCurses, "beep", curses_beep, 0); 2723 rb_define_module_function(mCurses, "flash", curses_flash, 0); 2724 rb_define_module_function(mCurses, "ungetch", curses_ungetch, 1); 2725 rb_define_module_function(mCurses, "setpos", curses_setpos, 2); 2726 rb_define_module_function(mCurses, "standout", curses_standout, 0); 2727 rb_define_module_function(mCurses, "standend", curses_standend, 0); 2728 rb_define_module_function(mCurses, "inch", curses_inch, 0); 2729 rb_define_module_function(mCurses, "addch", curses_addch, 1); 2730 rb_define_module_function(mCurses, "insch", curses_insch, 1); 2731 rb_define_module_function(mCurses, "addstr", curses_addstr, 1); 2732 rb_define_module_function(mCurses, "getch", curses_getch, 0); 2733 rb_define_module_function(mCurses, "getstr", curses_getstr, 0); 2734 rb_define_module_function(mCurses, "delch", curses_delch, 0); 2735 rb_define_module_function(mCurses, "deleteln", curses_deleteln, 0); 2736 rb_define_module_function(mCurses, "insertln", curses_insertln, 0); 2737 rb_define_module_function(mCurses, "keyname", curses_keyname, 1); 2738 rb_define_module_function(mCurses, "lines", curses_lines, 0); 2739 rb_define_module_function(mCurses, "cols", curses_cols, 0); 2740 rb_define_module_function(mCurses, "curs_set", curses_curs_set, 1); 2741 rb_define_module_function(mCurses, "scrl", curses_scrl, 1); 2742 rb_define_module_function(mCurses, "setscrreg", curses_setscrreg, 2); 2743 rb_define_module_function(mCurses, "attroff", curses_attroff, 1); 2744 rb_define_module_function(mCurses, "attron", curses_attron, 1); 2745 rb_define_module_function(mCurses, "attrset", curses_attrset, 1); 2746 rb_define_module_function(mCurses, "bkgdset", curses_bkgdset, 1); 2747 rb_define_module_function(mCurses, "bkgd", curses_bkgd, 1); 2748 rb_define_module_function(mCurses, "resizeterm", curses_resizeterm, 2); 2749 rb_define_module_function(mCurses, "resize", curses_resizeterm, 2); 2750#ifdef USE_COLOR 2751 rb_define_module_function(mCurses, "start_color", curses_start_color, 0); 2752 rb_define_module_function(mCurses, "init_pair", curses_init_pair, 3); 2753 rb_define_module_function(mCurses, "init_color", curses_init_color, 4); 2754 rb_define_module_function(mCurses, "has_colors?", curses_has_colors, 0); 2755 rb_define_module_function(mCurses, "can_change_color?", 2756 curses_can_change_color, 0); 2757 rb_define_module_function(mCurses, "colors", curses_colors, 0); 2758 rb_define_module_function(mCurses, "color_content", curses_color_content, 1); 2759 rb_define_module_function(mCurses, "color_pairs", curses_color_pairs, 0); 2760 rb_define_module_function(mCurses, "pair_content", curses_pair_content, 1); 2761 rb_define_module_function(mCurses, "color_pair", curses_color_pair, 1); 2762 rb_define_module_function(mCurses, "pair_number", curses_pair_number, 1); 2763#endif /* USE_COLOR */ 2764#ifdef USE_MOUSE 2765 rb_define_module_function(mCurses, "getmouse", curses_getmouse, 0); 2766 rb_define_module_function(mCurses, "ungetmouse", curses_ungetmouse, 1); 2767 rb_define_module_function(mCurses, "mouseinterval", curses_mouseinterval, 1); 2768 rb_define_module_function(mCurses, "mousemask", curses_mousemask, 1); 2769#endif /* USE_MOUSE */ 2770 2771 rb_define_module_function(mCurses, "timeout=", curses_timeout, 1); 2772 rb_define_module_function(mCurses, "def_prog_mode", curses_def_prog_mode, 0); 2773 rb_define_module_function(mCurses, "reset_prog_mode", curses_reset_prog_mode, 0); 2774 2775 { 2776 VALUE version; 2777#if defined(HAVE_FUNC_CURSES_VERSION) 2778 /* ncurses and PDcurses */ 2779 version = rb_str_new2(curses_version()); 2780#elif defined(HAVE_VAR_CURSES_VERSION) 2781 /* SVR4 curses has an undocumented and undeclared variable, curses_version. 2782 * It contains a string, "SVR4". */ 2783 RUBY_EXTERN char *curses_version; 2784 version = rb_sprintf("curses (%s)", curses_version); 2785#else 2786 /* BSD curses, perhaps. NetBSD 5 still use it. */ 2787 version = rb_str_new2("curses (unknown)"); 2788#endif 2789 /* 2790 * Identifies curses library version. 2791 * 2792 * - "ncurses 5.9.20110404" 2793 * - "PDCurses 3.4 - Public Domain 2008" 2794 * - "curses (SVR4)" (System V curses) 2795 * - "curses (unknown)" (The original BSD curses? NetBSD maybe.) 2796 * 2797 */ 2798 rb_define_const(mCurses, "VERSION", version); 2799 } 2800 2801 /* 2802 * Document-class: Curses::Window 2803 * 2804 * == Description 2805 * 2806 * The means by which to create and manage frames or windows. 2807 * While there may be more than one window at a time, only one window 2808 * will receive input. 2809 * 2810 * == Usage 2811 * 2812 * require 'curses' 2813 * 2814 * Curses.init_screen() 2815 * 2816 * my_str = "LOOK! PONIES!" 2817 * win = Curses::Window.new( 8, (my_str.length + 10), 2818 * (Curses.lines - 8) / 2, 2819 * (Curses.cols - (my_str.length + 10)) / 2 ) 2820 * win.box("|", "-") 2821 * win.setpos(2,3) 2822 * win.addstr(my_str) 2823 * # or even 2824 * win << "\nORLY" 2825 * win << "\nYES!! " + my_str 2826 * win.refresh 2827 * win.getch 2828 * win.close 2829 * 2830 */ 2831 cWindow = rb_define_class_under(mCurses, "Window", rb_cData); 2832 rb_define_alloc_func(cWindow, window_s_allocate); 2833 rb_define_method(cWindow, "initialize", window_initialize, 4); 2834 rb_define_method(cWindow, "subwin", window_subwin, 4); 2835 rb_define_method(cWindow, "close", window_close, 0); 2836 rb_define_method(cWindow, "clear", window_clear, 0); 2837 rb_define_method(cWindow, "clrtoeol", window_clrtoeol, 0); 2838 rb_define_method(cWindow, "refresh", window_refresh, 0); 2839 rb_define_method(cWindow, "noutrefresh", window_noutrefresh, 0); 2840 rb_define_method(cWindow, "box", window_box, -1); 2841 rb_define_method(cWindow, "move", window_move, 2); 2842 rb_define_method(cWindow, "setpos", window_setpos, 2); 2843#if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET) 2844 rb_define_method(cWindow, "color_set", window_color_set, 1); 2845#endif /* USE_COLOR && HAVE_WCOLOR_SET */ 2846 rb_define_method(cWindow, "cury", window_cury, 0); 2847 rb_define_method(cWindow, "curx", window_curx, 0); 2848 rb_define_method(cWindow, "maxy", window_maxy, 0); 2849 rb_define_method(cWindow, "maxx", window_maxx, 0); 2850 rb_define_method(cWindow, "begy", window_begy, 0); 2851 rb_define_method(cWindow, "begx", window_begx, 0); 2852 rb_define_method(cWindow, "standout", window_standout, 0); 2853 rb_define_method(cWindow, "standend", window_standend, 0); 2854 rb_define_method(cWindow, "inch", window_inch, 0); 2855 rb_define_method(cWindow, "addch", window_addch, 1); 2856 rb_define_method(cWindow, "insch", window_insch, 1); 2857 rb_define_method(cWindow, "addstr", window_addstr, 1); 2858 rb_define_method(cWindow, "<<", window_addstr2, 1); 2859 rb_define_method(cWindow, "getch", window_getch, 0); 2860 rb_define_method(cWindow, "getstr", window_getstr, 0); 2861 rb_define_method(cWindow, "delch", window_delch, 0); 2862 rb_define_method(cWindow, "deleteln", window_deleteln, 0); 2863 rb_define_method(cWindow, "insertln", window_insertln, 0); 2864 rb_define_method(cWindow, "scroll", window_scroll, 0); 2865 rb_define_method(cWindow, "scrollok", window_scrollok, 1); 2866 rb_define_method(cWindow, "idlok", window_idlok, 1); 2867 rb_define_method(cWindow, "setscrreg", window_setscrreg, 2); 2868 rb_define_method(cWindow, "scrl", window_scrl, 1); 2869 rb_define_method(cWindow, "resize", window_resize, 2); 2870 rb_define_method(cWindow, "keypad", window_keypad, 1); 2871 rb_define_method(cWindow, "keypad=", window_keypad, 1); 2872 2873 rb_define_method(cWindow, "attroff", window_attroff, 1); 2874 rb_define_method(cWindow, "attron", window_attron, 1); 2875 rb_define_method(cWindow, "attrset", window_attrset, 1); 2876 rb_define_method(cWindow, "bkgdset", window_bkgdset, 1); 2877 rb_define_method(cWindow, "bkgd", window_bkgd, 1); 2878 rb_define_method(cWindow, "getbkgd", window_getbkgd, 0); 2879 2880 rb_define_method(cWindow, "nodelay=", window_nodelay, 1); 2881 rb_define_method(cWindow, "timeout=", window_timeout, 1); 2882 2883#ifdef HAVE_NEWPAD 2884 /* 2885 * Document-class: Curses::Pad 2886 * 2887 * == Description 2888 * 2889 * A Pad is like a Window but allows for scrolling of contents that cannot 2890 * fit on the screen. Pads do not refresh automatically, use Pad#refresh 2891 * or Pad#noutrefresh instead. 2892 * 2893 */ 2894 cPad = rb_define_class_under(mCurses, "Pad", cWindow); 2895 /* inherits alloc_func from cWindow */ 2896 rb_define_method(cPad, "initialize", pad_initialize, 2); 2897 rb_define_method(cPad, "subpad", pad_subpad, 4); 2898 rb_define_method(cPad, "refresh", pad_refresh, 6); 2899 rb_define_method(cPad, "noutrefresh", pad_noutrefresh, 6); 2900 rb_undef_method(cPad, "subwin"); 2901#endif 2902 2903#define rb_curses_define_const(c) rb_define_const(mCurses,#c,UINT2NUM(c)) 2904 2905#ifdef USE_COLOR 2906 /* Document-const: A_ATTRIBUTES 2907 * 2908 * Character attribute mask: 2909 * Bit-mask to extract attributes 2910 * 2911 * See Curses.inch or Curses::Window.inch 2912 */ 2913 rb_curses_define_const(A_ATTRIBUTES); 2914#ifdef A_NORMAL 2915 /* Document-const: A_NORMAL 2916 * 2917 * Attribute mask: 2918 * Normal display (no highlight) 2919 * 2920 * See Curses.attrset 2921 */ 2922 rb_curses_define_const(A_NORMAL); 2923#endif 2924 /* Document-const: A_STANDOUT 2925 * 2926 * Attribute mask: 2927 * Best highlighting mode of the terminal. 2928 * 2929 * See Curses.attrset 2930 */ 2931 rb_curses_define_const(A_STANDOUT); 2932 /* Document-const: A_UNDERLINE 2933 * 2934 * Attribute mask: 2935 * Underlining 2936 * 2937 * See Curses.attrset 2938 */ 2939 rb_curses_define_const(A_UNDERLINE); 2940 /* Document-const: A_REVERSE 2941 * 2942 * Attribute mask: 2943 * Reverse video 2944 * 2945 * See Curses.attrset 2946 */ 2947 rb_curses_define_const(A_REVERSE); 2948 /* Document-const: A_BLINK 2949 * 2950 * Attribute mask: 2951 * Blinking 2952 * 2953 * See Curses.attrset 2954 */ 2955 rb_curses_define_const(A_BLINK); 2956 /* Document-const: A_DIM 2957 * 2958 * Attribute mask: 2959 * Half bright 2960 * 2961 * See Curses.attrset 2962 */ 2963 rb_curses_define_const(A_DIM); 2964 /* Document-const: A_BOLD 2965 * 2966 * Attribute mask: 2967 * Extra bright or bold 2968 * 2969 * See Curses.attrset 2970 */ 2971 rb_curses_define_const(A_BOLD); 2972 /* Document-const: A_PROTECT 2973 * 2974 * Attribute mask: 2975 * Protected mode 2976 * 2977 * See Curses.attrset 2978 */ 2979 rb_curses_define_const(A_PROTECT); 2980#ifdef A_INVIS /* for NetBSD */ 2981 /* Document-const: A_INVIS 2982 * 2983 * Attribute mask: 2984 * Invisible or blank mode 2985 * 2986 * See Curses.attrset 2987 */ 2988 rb_curses_define_const(A_INVIS); 2989#endif 2990 /* Document-const: A_ALTCHARSET 2991 * 2992 * Attribute mask: 2993 * Alternate character set 2994 * 2995 * See Curses.attrset 2996 */ 2997 rb_curses_define_const(A_ALTCHARSET); 2998 /* Document-const: A_CHARTEXT 2999 * 3000 * Attribute mask: 3001 * Bit-mask to extract a character 3002 * 3003 * See Curses.attrset 3004 */ 3005 rb_curses_define_const(A_CHARTEXT); 3006#ifdef A_HORIZONTAL 3007 /* Document-const: A_HORIZONTAL 3008 * 3009 * Attribute mask: 3010 * horizontal highlight 3011 * 3012 * Check system curs_attr(3x) for support 3013 */ 3014 rb_curses_define_const(A_HORIZONTAL); 3015#endif 3016#ifdef A_LEFT 3017 /* Document-const: A_LEFT 3018 * 3019 * Attribute mask: 3020 * left highlight 3021 * 3022 * Check system curs_attr(3x) for support 3023 */ 3024 rb_curses_define_const(A_LEFT); 3025#endif 3026#ifdef A_LOW 3027 /* Document-const: A_LOW 3028 * 3029 * Attribute mask: 3030 * low highlight 3031 * 3032 * Check system curs_attr(3x) for support 3033 */ 3034 rb_curses_define_const(A_LOW); 3035#endif 3036#ifdef A_RIGHT 3037 /* Document-const: A_RIGHT 3038 * 3039 * Attribute mask: 3040 * right highlight 3041 * 3042 * Check system curs_attr(3x) for support 3043 */ 3044 rb_curses_define_const(A_RIGHT); 3045#endif 3046#ifdef A_TOP 3047 /* Document-const: A_TOP 3048 * 3049 * Attribute mask: 3050 * top highlight 3051 * 3052 * Check system curs_attr(3x) for support 3053 */ 3054 rb_curses_define_const(A_TOP); 3055#endif 3056#ifdef A_VERTICAL 3057 /* Document-const: A_VERTICAL 3058 * 3059 * Attribute mask: 3060 * vertical highlight 3061 * 3062 * Check system curs_attr(3x) for support 3063 */ 3064 rb_curses_define_const(A_VERTICAL); 3065#endif 3066 /* Document-const: A_COLOR 3067 * 3068 * Character attribute mask: 3069 * Bit-mask to extract color-pair field information 3070 * 3071 * See Curses.inch or Curses::Window.inch 3072 */ 3073 rb_curses_define_const(A_COLOR); 3074 3075#ifdef COLORS 3076 /* 3077 * Document-const: Curses::COLORS 3078 * 3079 * Number of the colors available 3080 */ 3081 rb_curses_define_const(COLORS); 3082#endif 3083 /* 3084 * Document-const: Curses::COLOR_BLACK 3085 * 3086 * Value of the color black 3087 */ 3088 rb_curses_define_const(COLOR_BLACK); 3089 /* 3090 * Document-const: COLOR_RED 3091 * 3092 * Value of the color red 3093 */ 3094 rb_curses_define_const(COLOR_RED); 3095 /* 3096 * Document-const: COLOR_GREEN 3097 * 3098 * Value of the color green 3099 */ 3100 rb_curses_define_const(COLOR_GREEN); 3101 /* 3102 * Document-const: COLOR_YELLOW 3103 * 3104 * Value of the color yellow 3105 */ 3106 rb_curses_define_const(COLOR_YELLOW); 3107 /* 3108 * Document-const: COLOR_BLUE 3109 * 3110 * Value of the color blue 3111 */ 3112 rb_curses_define_const(COLOR_BLUE); 3113 /* 3114 * Document-const: COLOR_MAGENTA 3115 * 3116 * Value of the color magenta 3117 */ 3118 rb_curses_define_const(COLOR_MAGENTA); 3119 /* 3120 * Document-const: COLOR_CYAN 3121 * 3122 * Value of the color cyan 3123 */ 3124 rb_curses_define_const(COLOR_CYAN); 3125 /* 3126 * Document-const: COLOR_WHITE 3127 * 3128 * Value of the color white 3129 */ 3130 rb_curses_define_const(COLOR_WHITE); 3131#endif /* USE_COLOR */ 3132#ifdef USE_MOUSE 3133#ifdef BUTTON1_PRESSED 3134 /* Document-const: BUTTON1_PRESSED 3135 * 3136 * Mouse event mask: 3137 * mouse button 1 down 3138 * 3139 * See Curses.getmouse 3140 */ 3141 rb_curses_define_const(BUTTON1_PRESSED); 3142#endif 3143#ifdef BUTTON1_RELEASED 3144 /* Document-const: BUTTON1_RELEASED 3145 * 3146 * Mouse event mask: 3147 * mouse button 1 up 3148 * 3149 * See Curses.getmouse 3150 */ 3151 rb_curses_define_const(BUTTON1_RELEASED); 3152#endif 3153#ifdef BUTTON1_CLICKED 3154 /* Document-const: BUTTON1_CLICKED 3155 * 3156 * Mouse event mask: 3157 * mouse button 1 clicked 3158 * 3159 * See Curses.getmouse 3160 */ 3161 rb_curses_define_const(BUTTON1_CLICKED); 3162#endif 3163#ifdef BUTTON1_DOUBLE_CLICKED 3164 /* Document-const: BUTTON1_DOUBLE_CLICKED 3165 * 3166 * Mouse event mask: 3167 * mouse button 1 double clicked 3168 * 3169 * See Curses.getmouse 3170 */ 3171 rb_curses_define_const(BUTTON1_DOUBLE_CLICKED); 3172#endif 3173#ifdef BUTTON1_TRIPLE_CLICKED 3174 /* Document-const: BUTTON1_TRIPLE_CLICKED 3175 * 3176 * Mouse event mask: 3177 * mouse button 1 triple clicked 3178 * 3179 * See Curses.getmouse 3180 */ 3181 rb_curses_define_const(BUTTON1_TRIPLE_CLICKED); 3182#endif 3183#ifdef BUTTON2_PRESSED 3184 /* Document-const: BUTTON2_PRESSED 3185 * 3186 * Mouse event mask: 3187 * mouse button 2 down 3188 * 3189 * See Curses.getmouse 3190 */ 3191 rb_curses_define_const(BUTTON2_PRESSED); 3192#endif 3193#ifdef BUTTON2_RELEASED 3194 /* Document-const: BUTTON2_RELEASED 3195 * 3196 * Mouse event mask: 3197 * mouse button 2 up 3198 * 3199 * See Curses.getmouse 3200 */ 3201 rb_curses_define_const(BUTTON2_RELEASED); 3202#endif 3203#ifdef BUTTON2_CLICKED 3204 /* Document-const: BUTTON2_CLICKED 3205 * 3206 * Mouse event mask: 3207 * mouse button 2 clicked 3208 * 3209 * See Curses.getmouse 3210 */ 3211 rb_curses_define_const(BUTTON2_CLICKED); 3212#endif 3213#ifdef BUTTON2_DOUBLE_CLICKED 3214 /* Document-const: BUTTON2_DOUBLE_CLICKED 3215 * 3216 * Mouse event mask: 3217 * mouse button 2 double clicked 3218 * 3219 * See Curses.getmouse 3220 */ 3221 rb_curses_define_const(BUTTON2_DOUBLE_CLICKED); 3222#endif 3223#ifdef BUTTON2_TRIPLE_CLICKED 3224 /* Document-const: BUTTON2_TRIPLE_CLICKED 3225 * 3226 * Mouse event mask: 3227 * mouse button 2 triple clicked 3228 * 3229 * See Curses.getmouse 3230 */ 3231 rb_curses_define_const(BUTTON2_TRIPLE_CLICKED); 3232#endif 3233#ifdef BUTTON3_PRESSED 3234 /* Document-const: BUTTON3_PRESSED 3235 * 3236 * Mouse event mask: 3237 * mouse button 3 down 3238 * 3239 * See Curses.getmouse 3240 */ 3241 rb_curses_define_const(BUTTON3_PRESSED); 3242#endif 3243#ifdef BUTTON3_RELEASED 3244 /* Document-const: BUTTON3_RELEASED 3245 * 3246 * Mouse event mask: 3247 * mouse button 3 up 3248 * 3249 * See Curses.getmouse 3250 */ 3251 rb_curses_define_const(BUTTON3_RELEASED); 3252#endif 3253#ifdef BUTTON3_CLICKED 3254 /* Document-const: BUTTON3_CLICKED 3255 * 3256 * Mouse event mask: 3257 * mouse button 3 clicked 3258 * 3259 * See Curses.getmouse 3260 */ 3261 rb_curses_define_const(BUTTON3_CLICKED); 3262#endif 3263#ifdef BUTTON3_DOUBLE_CLICKED 3264 /* Document-const: BUTTON3_DOUBLE_CLICKED 3265 * 3266 * Mouse event mask: 3267 * mouse button 3 double clicked 3268 * 3269 * See Curses.getmouse 3270 */ 3271 rb_curses_define_const(BUTTON3_DOUBLE_CLICKED); 3272#endif 3273#ifdef BUTTON3_TRIPLE_CLICKED 3274 /* Document-const: BUTTON3_TRIPLE_CLICKED 3275 * 3276 * Mouse event mask: 3277 * mouse button 3 triple clicked 3278 * 3279 * See Curses.getmouse 3280 */ 3281 rb_curses_define_const(BUTTON3_TRIPLE_CLICKED); 3282#endif 3283#ifdef BUTTON4_PRESSED 3284 /* Document-const: BUTTON4_PRESSED 3285 * 3286 * Mouse event mask: 3287 * mouse button 4 down 3288 * 3289 * See Curses.getmouse 3290 */ 3291 rb_curses_define_const(BUTTON4_PRESSED); 3292#endif 3293#ifdef BUTTON4_RELEASED 3294 /* Document-const: BUTTON4_RELEASED 3295 * 3296 * Mouse event mask: 3297 * mouse button 4 up 3298 * 3299 * See Curses.getmouse 3300 */ 3301 rb_curses_define_const(BUTTON4_RELEASED); 3302#endif 3303#ifdef BUTTON4_CLICKED 3304 /* Document-const: BUTTON4_CLICKED 3305 * 3306 * Mouse event mask: 3307 * mouse button 4 clicked 3308 * 3309 * See Curses.getmouse 3310 */ 3311 rb_curses_define_const(BUTTON4_CLICKED); 3312#endif 3313#ifdef BUTTON4_DOUBLE_CLICKED 3314 /* Document-const: BUTTON4_DOUBLE_CLICKED 3315 * 3316 * Mouse event mask: 3317 * mouse button 4 double clicked 3318 * 3319 * See Curses.getmouse 3320 */ 3321 rb_curses_define_const(BUTTON4_DOUBLE_CLICKED); 3322#endif 3323#ifdef BUTTON4_TRIPLE_CLICKED 3324 /* Document-const: BUTTON4_TRIPLE_CLICKED 3325 * 3326 * Mouse event mask: 3327 * mouse button 4 triple clicked 3328 * 3329 * See Curses.getmouse 3330 */ 3331 rb_curses_define_const(BUTTON4_TRIPLE_CLICKED); 3332#endif 3333#ifdef BUTTON_SHIFT 3334 /* Document-const: BUTTON_SHIFT 3335 * 3336 * Mouse event mask: 3337 * shift was down during button state change 3338 * 3339 * See Curses.getmouse 3340 */ 3341 rb_curses_define_const(BUTTON_SHIFT); 3342#endif 3343#ifdef BUTTON_CTRL 3344 /* Document-const: BUTTON_CTRL 3345 * 3346 * Mouse event mask: 3347 * control was down during button state change 3348 * 3349 * See Curses.getmouse 3350 */ 3351 rb_curses_define_const(BUTTON_CTRL); 3352#endif 3353#ifdef BUTTON_ALT 3354 /* Document-const: BUTTON_ALT 3355 * 3356 * Mouse event mask: 3357 * alt was down during button state change 3358 * 3359 * See Curses.getmouse 3360 */ 3361 rb_curses_define_const(BUTTON_ALT); 3362#endif 3363#ifdef ALL_MOUSE_EVENTS 3364 /* Document-const: ALL_MOUSE_EVENTS 3365 * 3366 * Mouse event mask: 3367 * report all button state changes 3368 * 3369 * See Curses.getmouse 3370 */ 3371 rb_curses_define_const(ALL_MOUSE_EVENTS); 3372#endif 3373#ifdef REPORT_MOUSE_POSITION 3374 /* Document-const: REPORT_MOUSE_POSITION 3375 * 3376 * Mouse event mask: 3377 * report mouse movement 3378 * 3379 * See Curses.getmouse 3380 */ 3381 rb_curses_define_const(REPORT_MOUSE_POSITION); 3382#endif 3383#endif /* USE_MOUSE */ 3384 3385#if defined(KEY_MOUSE) && defined(USE_MOUSE) 3386 /* Document-const: KEY_MOUSE 3387 * Mouse event read 3388 */ 3389 /* Document-const: MOUSE 3390 * Mouse event read 3391 */ 3392 rb_curses_define_const(KEY_MOUSE); 3393 rb_define_const(mKey, "MOUSE", INT2NUM(KEY_MOUSE)); 3394#endif 3395#ifdef KEY_MIN 3396 /* Document-const: KEY_MIN 3397 * The minimum allowed curses key value. 3398 */ 3399 /* Document-const: MIN 3400 * The minimum allowed curses key value. 3401 */ 3402 rb_curses_define_const(KEY_MIN); 3403 rb_define_const(mKey, "MIN", INT2NUM(KEY_MIN)); 3404#endif 3405#ifdef KEY_BREAK 3406 /* Document-const: KEY_BREAK 3407 * Break key 3408 */ 3409 /* Document-const: BREAK 3410 * Break key 3411 */ 3412 rb_curses_define_const(KEY_BREAK); 3413 rb_define_const(mKey, "BREAK", INT2NUM(KEY_BREAK)); 3414#endif 3415#ifdef KEY_DOWN 3416 /* Document-const: KEY_DOWN 3417 * the down arrow key 3418 */ 3419 /* Document-const: DOWN 3420 * the down arrow key 3421 */ 3422 rb_curses_define_const(KEY_DOWN); 3423 rb_define_const(mKey, "DOWN", INT2NUM(KEY_DOWN)); 3424#endif 3425#ifdef KEY_UP 3426 /* Document-const: KEY_UP 3427 * the up arrow key 3428 */ 3429 /* Document-const: UP 3430 * the up arrow key 3431 */ 3432 rb_curses_define_const(KEY_UP); 3433 rb_define_const(mKey, "UP", INT2NUM(KEY_UP)); 3434#endif 3435#ifdef KEY_LEFT 3436 /* Document-const: KEY_LEFT 3437 * the left arrow key 3438 */ 3439 /* Document-const: LEFT 3440 * the left arrow key 3441 */ 3442 rb_curses_define_const(KEY_LEFT); 3443 rb_define_const(mKey, "LEFT", INT2NUM(KEY_LEFT)); 3444#endif 3445#ifdef KEY_RIGHT 3446 /* Document-const: KEY_RIGHT 3447 * the right arrow key 3448 */ 3449 /* Document-const: RIGHT 3450 * the right arrow key 3451 */ 3452 rb_curses_define_const(KEY_RIGHT); 3453 rb_define_const(mKey, "RIGHT", INT2NUM(KEY_RIGHT)); 3454#endif 3455#ifdef KEY_HOME 3456 /* Document-const: KEY_HOME 3457 * Home key (upward+left arrow) 3458 */ 3459 /* Document-const: HOME 3460 * Home key (upward+left arrow) 3461 */ 3462 rb_curses_define_const(KEY_HOME); 3463 rb_define_const(mKey, "HOME", INT2NUM(KEY_HOME)); 3464#endif 3465#ifdef KEY_BACKSPACE 3466 /* Document-const: KEY_BACKSPACE 3467 * Backspace 3468 */ 3469 /* Document-const: BACKSPACE 3470 * Backspace 3471 */ 3472 rb_curses_define_const(KEY_BACKSPACE); 3473 rb_define_const(mKey, "BACKSPACE", INT2NUM(KEY_BACKSPACE)); 3474#endif 3475#ifdef KEY_F 3476 /* KEY_F(n) : 0 <= n <= 63 */ 3477 { 3478 int i; 3479 char c[8]; 3480 for (i=0; i<64; i++) { 3481 sprintf(c, "KEY_F%d", i); 3482 rb_define_const(mCurses, c, INT2NUM(KEY_F(i))); 3483 sprintf(c, "F%d", i); 3484 rb_define_const(mKey, c, INT2NUM(KEY_F(i))); 3485 } 3486 } 3487#endif 3488#ifdef KEY_DL 3489 /* Document-const: KEY_DL 3490 * Delete line 3491 */ 3492 /* Document-const: DL 3493 * Delete line 3494 */ 3495 rb_curses_define_const(KEY_DL); 3496 rb_define_const(mKey, "DL", INT2NUM(KEY_DL)); 3497#endif 3498#ifdef KEY_IL 3499 /* Document-const: KEY_IL 3500 * Insert line 3501 */ 3502 /* Document-const: IL 3503 * Insert line 3504 */ 3505 rb_curses_define_const(KEY_IL); 3506 rb_define_const(mKey, "IL", INT2NUM(KEY_IL)); 3507#endif 3508#ifdef KEY_DC 3509 /* Document-const: KEY_DC 3510 * Delete character 3511 */ 3512 /* Document-const: DC 3513 * Delete character 3514 */ 3515 rb_curses_define_const(KEY_DC); 3516 rb_define_const(mKey, "DC", INT2NUM(KEY_DC)); 3517#endif 3518#ifdef KEY_IC 3519 /* Document-const: KEY_IC 3520 * Insert char or enter insert mode 3521 */ 3522 /* Document-const: IC 3523 * Insert char or enter insert mode 3524 */ 3525 rb_curses_define_const(KEY_IC); 3526 rb_define_const(mKey, "IC", INT2NUM(KEY_IC)); 3527#endif 3528#ifdef KEY_EIC 3529 /* Document-const: KEY_EIC 3530 * Enter insert char mode 3531 */ 3532 /* Document-const: EIC 3533 * Enter insert char mode 3534 */ 3535 rb_curses_define_const(KEY_EIC); 3536 rb_define_const(mKey, "EIC", INT2NUM(KEY_EIC)); 3537#endif 3538#ifdef KEY_CLEAR 3539 /* Document-const: KEY_CLEAR 3540 * Clear Screen 3541 */ 3542 /* Document-const: CLEAR 3543 * Clear Screen 3544 */ 3545 rb_curses_define_const(KEY_CLEAR); 3546 rb_define_const(mKey, "CLEAR", INT2NUM(KEY_CLEAR)); 3547#endif 3548#ifdef KEY_EOS 3549 /* Document-const: KEY_EOS 3550 * Clear to end of screen 3551 */ 3552 /* Document-const: EOS 3553 * Clear to end of screen 3554 */ 3555 rb_curses_define_const(KEY_EOS); 3556 rb_define_const(mKey, "EOS", INT2NUM(KEY_EOS)); 3557#endif 3558#ifdef KEY_EOL 3559 /* Document-const: KEY_EOL 3560 * Clear to end of line 3561 */ 3562 /* Document-const: EOL 3563 * Clear to end of line 3564 */ 3565 rb_curses_define_const(KEY_EOL); 3566 rb_define_const(mKey, "EOL", INT2NUM(KEY_EOL)); 3567#endif 3568#ifdef KEY_SF 3569 /* Document-const: KEY_SF 3570 * Scroll 1 line forward 3571 */ 3572 /* Document-const: SF 3573 * Scroll 1 line forward 3574 */ 3575 rb_curses_define_const(KEY_SF); 3576 rb_define_const(mKey, "SF", INT2NUM(KEY_SF)); 3577#endif 3578#ifdef KEY_SR 3579 /* Document-const: KEY_SR 3580 * Scroll 1 line backware (reverse) 3581 */ 3582 /* Document-const: SR 3583 * Scroll 1 line backware (reverse) 3584 */ 3585 rb_curses_define_const(KEY_SR); 3586 rb_define_const(mKey, "SR", INT2NUM(KEY_SR)); 3587#endif 3588#ifdef KEY_NPAGE 3589 /* Document-const: KEY_NPAGE 3590 * Next page 3591 */ 3592 /* Document-const: NPAGE 3593 * Next page 3594 */ 3595 rb_curses_define_const(KEY_NPAGE); 3596 rb_define_const(mKey, "NPAGE", INT2NUM(KEY_NPAGE)); 3597#endif 3598#ifdef KEY_PPAGE 3599 /* Document-const: KEY_PPAGE 3600 * Previous page 3601 */ 3602 /* Document-const: PPAGE 3603 * Previous page 3604 */ 3605 rb_curses_define_const(KEY_PPAGE); 3606 rb_define_const(mKey, "PPAGE", INT2NUM(KEY_PPAGE)); 3607#endif 3608#ifdef KEY_STAB 3609 /* Document-const: KEY_STAB 3610 * Set tab 3611 */ 3612 /* Document-const: STAB 3613 * Set tab 3614 */ 3615 rb_curses_define_const(KEY_STAB); 3616 rb_define_const(mKey, "STAB", INT2NUM(KEY_STAB)); 3617#endif 3618#ifdef KEY_CTAB 3619 /* Document-const: KEY_CTAB 3620 * Clear tab 3621 */ 3622 /* Document-const: CTAB 3623 * Clear tab 3624 */ 3625 rb_curses_define_const(KEY_CTAB); 3626 rb_define_const(mKey, "CTAB", INT2NUM(KEY_CTAB)); 3627#endif 3628#ifdef KEY_CATAB 3629 /* Document-const: KEY_CATAB 3630 * Clear all tabs 3631 */ 3632 /* Document-const: CATAB 3633 * Clear all tabs 3634 */ 3635 rb_curses_define_const(KEY_CATAB); 3636 rb_define_const(mKey, "CATAB", INT2NUM(KEY_CATAB)); 3637#endif 3638#ifdef KEY_ENTER 3639 /* Document-const: KEY_ENTER 3640 * Enter or send 3641 */ 3642 /* Document-const: ENTER 3643 * Enter or send 3644 */ 3645 rb_curses_define_const(KEY_ENTER); 3646 rb_define_const(mKey, "ENTER", INT2NUM(KEY_ENTER)); 3647#endif 3648#ifdef KEY_SRESET 3649 /* Document-const: KEY_SRESET 3650 * Soft (partial) reset 3651 */ 3652 /* Document-const: SRESET 3653 * Soft (partial) reset 3654 */ 3655 rb_curses_define_const(KEY_SRESET); 3656 rb_define_const(mKey, "SRESET", INT2NUM(KEY_SRESET)); 3657#endif 3658#ifdef KEY_RESET 3659 /* Document-const: KEY_RESET 3660 * Reset or hard reset 3661 */ 3662 /* Document-const: RESET 3663 * Reset or hard reset 3664 */ 3665 rb_curses_define_const(KEY_RESET); 3666 rb_define_const(mKey, "RESET", INT2NUM(KEY_RESET)); 3667#endif 3668#ifdef KEY_PRINT 3669 /* Document-const: KEY_PRINT 3670 * Print or copy 3671 */ 3672 /* Document-const: PRINT 3673 * Print or copy 3674 */ 3675 rb_curses_define_const(KEY_PRINT); 3676 rb_define_const(mKey, "PRINT", INT2NUM(KEY_PRINT)); 3677#endif 3678#ifdef KEY_LL 3679 /* Document-const: KEY_LL 3680 * Home down or bottom (lower left) 3681 */ 3682 /* Document-const: LL 3683 * Home down or bottom (lower left) 3684 */ 3685 rb_curses_define_const(KEY_LL); 3686 rb_define_const(mKey, "LL", INT2NUM(KEY_LL)); 3687#endif 3688#ifdef KEY_A1 3689 /* Document-const: KEY_A1 3690 * Upper left of keypad 3691 */ 3692 /* Document-const: A1 3693 * Upper left of keypad 3694 */ 3695 rb_curses_define_const(KEY_A1); 3696 rb_define_const(mKey, "A1", INT2NUM(KEY_A1)); 3697#endif 3698#ifdef KEY_A3 3699 /* Document-const: KEY_A3 3700 * Upper right of keypad 3701 */ 3702 /* Document-const: A3 3703 * Upper right of keypad 3704 */ 3705 rb_curses_define_const(KEY_A3); 3706 rb_define_const(mKey, "A3", INT2NUM(KEY_A3)); 3707#endif 3708#ifdef KEY_B2 3709 /* Document-const: KEY_B2 3710 * Center of keypad 3711 */ 3712 /* Document-const: B2 3713 * Center of keypad 3714 */ 3715 rb_curses_define_const(KEY_B2); 3716 rb_define_const(mKey, "B2", INT2NUM(KEY_B2)); 3717#endif 3718#ifdef KEY_C1 3719 /* Document-const: KEY_C1 3720 * Lower left of keypad 3721 */ 3722 /* Document-const: C1 3723 * Lower left of keypad 3724 */ 3725 rb_curses_define_const(KEY_C1); 3726 rb_define_const(mKey, "C1", INT2NUM(KEY_C1)); 3727#endif 3728#ifdef KEY_C3 3729 /* Document-const: KEY_C3 3730 * Lower right of keypad 3731 */ 3732 /* Document-const: C3 3733 * Lower right of keypad 3734 */ 3735 rb_curses_define_const(KEY_C3); 3736 rb_define_const(mKey, "C3", INT2NUM(KEY_C3)); 3737#endif 3738#ifdef KEY_BTAB 3739 /* Document-const: BTAB 3740 * Back tab key 3741 */ 3742 /* Document-const: KEY_BTAB 3743 * Back tab key 3744 */ 3745 rb_curses_define_const(KEY_BTAB); 3746 rb_define_const(mKey, "BTAB", INT2NUM(KEY_BTAB)); 3747#endif 3748#ifdef KEY_BEG 3749 /* Document-const: KEY_BEG 3750 * Beginning key 3751 */ 3752 /* Document-const: BEG 3753 * Beginning key 3754 */ 3755 rb_curses_define_const(KEY_BEG); 3756 rb_define_const(mKey, "BEG", INT2NUM(KEY_BEG)); 3757#endif 3758#ifdef KEY_CANCEL 3759 /* Document-const: KEY_CANCEL 3760 * Cancel key 3761 */ 3762 /* Document-const: CANCEL 3763 * Cancel key 3764 */ 3765 rb_curses_define_const(KEY_CANCEL); 3766 rb_define_const(mKey, "CANCEL", INT2NUM(KEY_CANCEL)); 3767#endif 3768#ifdef KEY_CLOSE 3769 /* Document-const: KEY_CLOSE 3770 * Close key 3771 */ 3772 /* Document-const: CLOSE 3773 * Close key 3774 */ 3775 rb_curses_define_const(KEY_CLOSE); 3776 rb_define_const(mKey, "CLOSE", INT2NUM(KEY_CLOSE)); 3777#endif 3778#ifdef KEY_COMMAND 3779 /* Document-const: KEY_COMMAND 3780 * Cmd (command) key 3781 */ 3782 /* Document-const: COMMAND 3783 * Cmd (command) key 3784 */ 3785 rb_curses_define_const(KEY_COMMAND); 3786 rb_define_const(mKey, "COMMAND", INT2NUM(KEY_COMMAND)); 3787#endif 3788#ifdef KEY_COPY 3789 /* Document-const: KEY_COPY 3790 * Copy key 3791 */ 3792 /* Document-const: COPY 3793 * Copy key 3794 */ 3795 rb_curses_define_const(KEY_COPY); 3796 rb_define_const(mKey, "COPY", INT2NUM(KEY_COPY)); 3797#endif 3798#ifdef KEY_CREATE 3799 /* Document-const: KEY_CREATE 3800 * Create key 3801 */ 3802 /* Document-const: CREATE 3803 * Create key 3804 */ 3805 rb_curses_define_const(KEY_CREATE); 3806 rb_define_const(mKey, "CREATE", INT2NUM(KEY_CREATE)); 3807#endif 3808#ifdef KEY_END 3809 /* Document-const: KEY_END 3810 * End key 3811 */ 3812 /* Document-const: END 3813 * End key 3814 */ 3815 rb_curses_define_const(KEY_END); 3816 rb_define_const(mKey, "END", INT2NUM(KEY_END)); 3817#endif 3818#ifdef KEY_EXIT 3819 /* Document-const: KEY_EXIT 3820 * Exit key 3821 */ 3822 /* Document-const: EXIT 3823 * Exit key 3824 */ 3825 rb_curses_define_const(KEY_EXIT); 3826 rb_define_const(mKey, "EXIT", INT2NUM(KEY_EXIT)); 3827#endif 3828#ifdef KEY_FIND 3829 /* Document-const: KEY_FIND 3830 * Find key 3831 */ 3832 /* Document-const: FIND 3833 * Find key 3834 */ 3835 rb_curses_define_const(KEY_FIND); 3836 rb_define_const(mKey, "FIND", INT2NUM(KEY_FIND)); 3837#endif 3838#ifdef KEY_HELP 3839 /* Document-const: KEY_HELP 3840 * Help key 3841 */ 3842 /* Document-const: HELP 3843 * Help key 3844 */ 3845 rb_curses_define_const(KEY_HELP); 3846 rb_define_const(mKey, "HELP", INT2NUM(KEY_HELP)); 3847#endif 3848#ifdef KEY_MARK 3849 /* Document-const: KEY_MARK 3850 * Mark key 3851 */ 3852 /* Document-const: MARK 3853 * Mark key 3854 */ 3855 rb_curses_define_const(KEY_MARK); 3856 rb_define_const(mKey, "MARK", INT2NUM(KEY_MARK)); 3857#endif 3858#ifdef KEY_MESSAGE 3859 /* Document-const: KEY_MESSAGE 3860 * Message key 3861 */ 3862 /* Document-const: MESSAGE 3863 * Message key 3864 */ 3865 rb_curses_define_const(KEY_MESSAGE); 3866 rb_define_const(mKey, "MESSAGE", INT2NUM(KEY_MESSAGE)); 3867#endif 3868#ifdef KEY_MOVE 3869 /* Document-const: KEY_MOVE 3870 * Move key 3871 */ 3872 /* Document-const: MOVE 3873 * Move key 3874 */ 3875 rb_curses_define_const(KEY_MOVE); 3876 rb_define_const(mKey, "MOVE", INT2NUM(KEY_MOVE)); 3877#endif 3878#ifdef KEY_NEXT 3879 /* Document-const: KEY_NEXT 3880 * Next object key 3881 */ 3882 /* Document-const: NEXT 3883 * Next object key 3884 */ 3885 rb_curses_define_const(KEY_NEXT); 3886 rb_define_const(mKey, "NEXT", INT2NUM(KEY_NEXT)); 3887#endif 3888#ifdef KEY_OPEN 3889 /* Document-const: KEY_OPEN 3890 * Open key 3891 */ 3892 /* Document-const: OPEN 3893 * Open key 3894 */ 3895 rb_curses_define_const(KEY_OPEN); 3896 rb_define_const(mKey, "OPEN", INT2NUM(KEY_OPEN)); 3897#endif 3898#ifdef KEY_OPTIONS 3899 /* Document-const: KEY_OPTIONS 3900 * Options key 3901 */ 3902 /* Document-const: OPTIONS 3903 * Options key 3904 */ 3905 rb_curses_define_const(KEY_OPTIONS); 3906 rb_define_const(mKey, "OPTIONS", INT2NUM(KEY_OPTIONS)); 3907#endif 3908#ifdef KEY_PREVIOUS 3909 /* Document-const: KEY_PREVIOUS 3910 * Previous object key 3911 */ 3912 /* Document-const: PREVIOUS 3913 * Previous object key 3914 */ 3915 rb_curses_define_const(KEY_PREVIOUS); 3916 rb_define_const(mKey, "PREVIOUS", INT2NUM(KEY_PREVIOUS)); 3917#endif 3918#ifdef KEY_REDO 3919 /* Document-const: KEY_REDO 3920 * Redo key 3921 */ 3922 /* Document-const: REDO 3923 * Redo key 3924 */ 3925 rb_curses_define_const(KEY_REDO); 3926 rb_define_const(mKey, "REDO", INT2NUM(KEY_REDO)); 3927#endif 3928#ifdef KEY_REFERENCE 3929 /* Document-const: KEY_REFERENCE 3930 * Reference key 3931 */ 3932 /* Document-const: REFERENCE 3933 * Reference key 3934 */ 3935 rb_curses_define_const(KEY_REFERENCE); 3936 rb_define_const(mKey, "REFERENCE", INT2NUM(KEY_REFERENCE)); 3937#endif 3938#ifdef KEY_REFRESH 3939 /* Document-const: KEY_REFRESH 3940 * Refresh key 3941 */ 3942 /* Document-const: REFRESH 3943 * Refresh key 3944 */ 3945 rb_curses_define_const(KEY_REFRESH); 3946 rb_define_const(mKey, "REFRESH", INT2NUM(KEY_REFRESH)); 3947#endif 3948#ifdef KEY_REPLACE 3949 /* Document-const: KEY_REPLACE 3950 * Replace key 3951 */ 3952 /* Document-const: REPLACE 3953 * Replace key 3954 */ 3955 rb_curses_define_const(KEY_REPLACE); 3956 rb_define_const(mKey, "REPLACE", INT2NUM(KEY_REPLACE)); 3957#endif 3958#ifdef KEY_RESTART 3959 /* Document-const: KEY_RESTART 3960 * Restart key 3961 */ 3962 /* Document-const: RESTART 3963 * Restart key 3964 */ 3965 rb_curses_define_const(KEY_RESTART); 3966 rb_define_const(mKey, "RESTART", INT2NUM(KEY_RESTART)); 3967#endif 3968#ifdef KEY_RESUME 3969 /* Document-const: KEY_RESUME 3970 * Resume key 3971 */ 3972 /* Document-const: RESUME 3973 * Resume key 3974 */ 3975 rb_curses_define_const(KEY_RESUME); 3976 rb_define_const(mKey, "RESUME", INT2NUM(KEY_RESUME)); 3977#endif 3978#ifdef KEY_SAVE 3979 /* Document-const: KEY_SAVE 3980 * Save key 3981 */ 3982 /* Document-const: SAVE 3983 * Save key 3984 */ 3985 rb_curses_define_const(KEY_SAVE); 3986 rb_define_const(mKey, "SAVE", INT2NUM(KEY_SAVE)); 3987#endif 3988#ifdef KEY_SBEG 3989 /* Document-const: KEY_SBEG 3990 * Shifted beginning key 3991 */ 3992 /* Document-const: SBEG 3993 * Shifted beginning key 3994 */ 3995 rb_curses_define_const(KEY_SBEG); 3996 rb_define_const(mKey, "SBEG", INT2NUM(KEY_SBEG)); 3997#endif 3998#ifdef KEY_SCANCEL 3999 /* Document-const: KEY_SCANCEL 4000 * Shifted cancel key 4001 */ 4002 /* Document-const: SCANCEL 4003 * Shifted cancel key 4004 */ 4005 rb_curses_define_const(KEY_SCANCEL); 4006 rb_define_const(mKey, "SCANCEL", INT2NUM(KEY_SCANCEL)); 4007#endif 4008#ifdef KEY_SCOMMAND 4009 /* Document-const: KEY_SCOMMAND 4010 * Shifted command key 4011 */ 4012 /* Document-const: SCOMMAND 4013 * Shifted command key 4014 */ 4015 rb_curses_define_const(KEY_SCOMMAND); 4016 rb_define_const(mKey, "SCOMMAND", INT2NUM(KEY_SCOMMAND)); 4017#endif 4018#ifdef KEY_SCOPY 4019 /* Document-const: KEY_SCOPY 4020 * Shifted copy key 4021 */ 4022 /* Document-const: SCOPY 4023 * Shifted copy key 4024 */ 4025 rb_curses_define_const(KEY_SCOPY); 4026 rb_define_const(mKey, "SCOPY", INT2NUM(KEY_SCOPY)); 4027#endif 4028#ifdef KEY_SCREATE 4029 /* Document-const: KEY_SCREATE 4030 * Shifted create key 4031 */ 4032 /* Document-const: SCREATE 4033 * Shifted create key 4034 */ 4035 rb_curses_define_const(KEY_SCREATE); 4036 rb_define_const(mKey, "SCREATE", INT2NUM(KEY_SCREATE)); 4037#endif 4038#ifdef KEY_SDC 4039 /* Document-const: KEY_SDC 4040 * Shifted delete char key 4041 */ 4042 /* Document-const: SDC 4043 * Shifted delete char key 4044 */ 4045 rb_curses_define_const(KEY_SDC); 4046 rb_define_const(mKey, "SDC", INT2NUM(KEY_SDC)); 4047#endif 4048#ifdef KEY_SDL 4049 /* Document-const: KEY_SDL 4050 * Shifted delete line key 4051 */ 4052 /* Document-const: SDL 4053 * Shifted delete line key 4054 */ 4055 rb_curses_define_const(KEY_SDL); 4056 rb_define_const(mKey, "SDL", INT2NUM(KEY_SDL)); 4057#endif 4058#ifdef KEY_SELECT 4059 /* Document-const: KEY_SELECT 4060 * Select key 4061 */ 4062 /* Document-const: SELECT 4063 * Select key 4064 */ 4065 rb_curses_define_const(KEY_SELECT); 4066 rb_define_const(mKey, "SELECT", INT2NUM(KEY_SELECT)); 4067#endif 4068#ifdef KEY_SEND 4069 /* Document-const: KEY_SEND 4070 * Shifted end key 4071 */ 4072 /* Document-const: SEND 4073 * Shifted end key 4074 */ 4075 rb_curses_define_const(KEY_SEND); 4076 rb_define_const(mKey, "SEND", INT2NUM(KEY_SEND)); 4077#endif 4078#ifdef KEY_SEOL 4079 /* Document-const: KEY_SEOL 4080 * Shifted clear line key 4081 */ 4082 /* Document-const: SEOL 4083 * Shifted clear line key 4084 */ 4085 rb_curses_define_const(KEY_SEOL); 4086 rb_define_const(mKey, "SEOL", INT2NUM(KEY_SEOL)); 4087#endif 4088#ifdef KEY_SEXIT 4089 /* Document-const: KEY_SEXIT 4090 * Shifted exit key 4091 */ 4092 /* Document-const: SEXIT 4093 * Shifted exit key 4094 */ 4095 rb_curses_define_const(KEY_SEXIT); 4096 rb_define_const(mKey, "SEXIT", INT2NUM(KEY_SEXIT)); 4097#endif 4098#ifdef KEY_SFIND 4099 /* Document-const: KEY_SFIND 4100 * Shifted find key 4101 */ 4102 /* Document-const: SFIND 4103 * Shifted find key 4104 */ 4105 rb_curses_define_const(KEY_SFIND); 4106 rb_define_const(mKey, "SFIND", INT2NUM(KEY_SFIND)); 4107#endif 4108#ifdef KEY_SHELP 4109 /* Document-const: KEY_SHELP 4110 * Shifted help key 4111 */ 4112 /* Document-const: SHELP 4113 * Shifted help key 4114 */ 4115 rb_curses_define_const(KEY_SHELP); 4116 rb_define_const(mKey, "SHELP", INT2NUM(KEY_SHELP)); 4117#endif 4118#ifdef KEY_SHOME 4119 /* Document-const: KEY_SHOME 4120 * Shifted home key 4121 */ 4122 /* Document-const: SHOME 4123 * Shifted home key 4124 */ 4125 rb_curses_define_const(KEY_SHOME); 4126 rb_define_const(mKey, "SHOME", INT2NUM(KEY_SHOME)); 4127#endif 4128#ifdef KEY_SIC 4129 /* Document-const: KEY_SIC 4130 * Shifted input key 4131 */ 4132 /* Document-const: SIC 4133 * Shifted input key 4134 */ 4135 rb_curses_define_const(KEY_SIC); 4136 rb_define_const(mKey, "SIC", INT2NUM(KEY_SIC)); 4137#endif 4138#ifdef KEY_SLEFT 4139 /* Document-const: KEY_SLEFT 4140 * Shifted left arrow key 4141 */ 4142 /* Document-const: SLEFT 4143 * Shifted left arrow key 4144 */ 4145 rb_curses_define_const(KEY_SLEFT); 4146 rb_define_const(mKey, "SLEFT", INT2NUM(KEY_SLEFT)); 4147#endif 4148#ifdef KEY_SMESSAGE 4149 /* Document-const: KEY_SMESSAGE 4150 * Shifted message key 4151 */ 4152 /* Document-const: SMESSAGE 4153 * Shifted message key 4154 */ 4155 rb_curses_define_const(KEY_SMESSAGE); 4156 rb_define_const(mKey, "SMESSAGE", INT2NUM(KEY_SMESSAGE)); 4157#endif 4158#ifdef KEY_SMOVE 4159 /* Document-const: KEY_SMOVE 4160 * Shifted move key 4161 */ 4162 /* Document-const: SMOVE 4163 * Shifted move key 4164 */ 4165 rb_curses_define_const(KEY_SMOVE); 4166 rb_define_const(mKey, "SMOVE", INT2NUM(KEY_SMOVE)); 4167#endif 4168#ifdef KEY_SNEXT 4169 /* Document-const: KEY_SNEXT 4170 * Shifted next key 4171 */ 4172 /* Document-const: SNEXT 4173 * Shifted next key 4174 */ 4175 rb_curses_define_const(KEY_SNEXT); 4176 rb_define_const(mKey, "SNEXT", INT2NUM(KEY_SNEXT)); 4177#endif 4178#ifdef KEY_SOPTIONS 4179 /* Document-const: KEY_SOPTIONS 4180 * Shifted options key 4181 */ 4182 /* Document-const: SOPTIONS 4183 * Shifted options key 4184 */ 4185 rb_curses_define_const(KEY_SOPTIONS); 4186 rb_define_const(mKey, "SOPTIONS", INT2NUM(KEY_SOPTIONS)); 4187#endif 4188#ifdef KEY_SPREVIOUS 4189 /* Document-const: KEY_SPREVIOUS 4190 * Shifted previous key 4191 */ 4192 /* Document-const: SPREVIOUS 4193 * Shifted previous key 4194 */ 4195 rb_curses_define_const(KEY_SPREVIOUS); 4196 rb_define_const(mKey, "SPREVIOUS", INT2NUM(KEY_SPREVIOUS)); 4197#endif 4198#ifdef KEY_SPRINT 4199 /* Document-const: KEY_SPRINT 4200 * Shifted print key 4201 */ 4202 /* Document-const: SPRINT 4203 * Shifted print key 4204 */ 4205 rb_curses_define_const(KEY_SPRINT); 4206 rb_define_const(mKey, "SPRINT", INT2NUM(KEY_SPRINT)); 4207#endif 4208#ifdef KEY_SREDO 4209 /* Document-const: KEY_SREDO 4210 * Shifted redo key 4211 */ 4212 /* Document-const: SREDO 4213 * Shifted redo key 4214 */ 4215 rb_curses_define_const(KEY_SREDO); 4216 rb_define_const(mKey, "SREDO", INT2NUM(KEY_SREDO)); 4217#endif 4218#ifdef KEY_SREPLACE 4219 /* Document-const: KEY_SREPLACE 4220 * Shifted replace key 4221 */ 4222 /* Document-const: SREPLACE 4223 * Shifted replace key 4224 */ 4225 rb_curses_define_const(KEY_SREPLACE); 4226 rb_define_const(mKey, "SREPLACE", INT2NUM(KEY_SREPLACE)); 4227#endif 4228#ifdef KEY_SRIGHT 4229 /* Document-const: KEY_SRIGHT 4230 * Shifted right arrow key 4231 */ 4232 /* Document-const: SRIGHT 4233 * Shifted right arrow key 4234 */ 4235 rb_curses_define_const(KEY_SRIGHT); 4236 rb_define_const(mKey, "SRIGHT", INT2NUM(KEY_SRIGHT)); 4237#endif 4238#ifdef KEY_SRSUME 4239 /* Document-const: KEY_SRSUME 4240 * Shifted resume key 4241 */ 4242 /* Document-const: SRSUME 4243 * Shifted resume key 4244 */ 4245 rb_curses_define_const(KEY_SRSUME); 4246 rb_define_const(mKey, "SRSUME", INT2NUM(KEY_SRSUME)); 4247#endif 4248#ifdef KEY_SSAVE 4249 /* Document-const: KEY_SSAVE 4250 * Shifted save key 4251 */ 4252 /* Document-const: SSAVE 4253 * Shifted save key 4254 */ 4255 rb_curses_define_const(KEY_SSAVE); 4256 rb_define_const(mKey, "SSAVE", INT2NUM(KEY_SSAVE)); 4257#endif 4258#ifdef KEY_SSUSPEND 4259 /* Document-const: KEY_SSUSPEND 4260 * Shifted suspend key 4261 */ 4262 /* Document-const: SSUSPEND 4263 * Shifted suspend key 4264 */ 4265 rb_curses_define_const(KEY_SSUSPEND); 4266 rb_define_const(mKey, "SSUSPEND", INT2NUM(KEY_SSUSPEND)); 4267#endif 4268#ifdef KEY_SUNDO 4269 /* Document-const: KEY_SUNDO 4270 * Shifted undo key 4271 */ 4272 /* Document-const: SUNDO 4273 * Shifted undo key 4274 */ 4275 rb_curses_define_const(KEY_SUNDO); 4276 rb_define_const(mKey, "SUNDO", INT2NUM(KEY_SUNDO)); 4277#endif 4278#ifdef KEY_SUSPEND 4279 /* Document-const: KEY_SUSPEND 4280 * Suspend key 4281 */ 4282 /* Document-const: SUSPEND 4283 * Suspend key 4284 */ 4285 rb_curses_define_const(KEY_SUSPEND); 4286 rb_define_const(mKey, "SUSPEND", INT2NUM(KEY_SUSPEND)); 4287#endif 4288#ifdef KEY_UNDO 4289 /* Document-const: KEY_UNDO 4290 * Undo key 4291 */ 4292 /* Document-const: UNDO 4293 * Undo key 4294 */ 4295 rb_curses_define_const(KEY_UNDO); 4296 rb_define_const(mKey, "UNDO", INT2NUM(KEY_UNDO)); 4297#endif 4298#ifdef KEY_RESIZE 4299 /* Document-const: KEY_RESIZE 4300 * Screen Resized 4301 */ 4302 /* Document-const: RESIZE 4303 * Screen Resized 4304 */ 4305 rb_curses_define_const(KEY_RESIZE); 4306 rb_define_const(mKey, "RESIZE", INT2NUM(KEY_RESIZE)); 4307#endif 4308#ifdef KEY_MAX 4309 /* Document-const: KEY_MAX 4310 * The maximum allowed curses key value. 4311 */ 4312 /* Document-const: MAX 4313 * The maximum allowed curses key value. 4314 */ 4315 rb_curses_define_const(KEY_MAX); 4316 rb_define_const(mKey, "MAX", INT2NUM(KEY_MAX)); 4317#endif 4318 { 4319 int c; 4320 char name[] = "KEY_CTRL_x"; 4321 for (c = 'A'; c <= 'Z'; c++) { 4322 name[sizeof(name) - 2] = c; 4323 rb_define_const(mCurses, name, INT2FIX(c - 'A' + 1)); 4324 } 4325 } 4326#undef rb_curses_define_const 4327 4328 rb_set_end_proc(curses_finalize, 0); 4329} 4330