$Id: README,v 1.10 2004/05/13 21:54:41 t-peters Exp $

This directory contains a ruby module for accessing the FSF’s ncurses library. © 2002, 2003, 2004 Tobias Peters <[email protected]> © 2004 Simon Kaczor <[email protected]>

This module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this module; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

This wrapper provides access to the functions, macros, global variables and constants of the ncurses library. These are mapped to a Ruby Module named “Ncurses”: Functions and external variables are implemented as singleton functions of the Module Ncurses.

This wrapper can also be used to access the PDCurses library (pdcurses.sourceforge.net/). See README.windows for details.

If you don’t know how to use ncurses from C, then stop reading here, and read an introduction to ncurses. Eric Raymond has written an introduction that should be part of the ncurses development package installed on your computer. If you need a gentler introduction, then you have two options: (1) there is a part of a chapter in “The Linux Programmer’s Guide” dealing with

ncurses, available from www.tldp.org.  It is quite old by now,
but the ncurses interface has not changed since then, regarding the scope
of covered functions, so it is still a very good read.

(2) There is also an up-to-date “NCURSES-Programming-HOWTO” in the HOWTO

collection of the Linux Documentation Project, also available at
www.tldp.org, which is worth a read.

You will also appreciate the extensive man-pages of ncurses.

Installation and Usage

ruby extconf.rb make make install

In your programs: require “ncurses.rb”

If your programs use the scanw functions (most unlikely) you will have to install the scanf library for ruby (www.rubyhacker.com/code/scanf).

Most ncurses functions are only available after either Ncurses.initscr or Ncurses.newterm has returned successfully.

External Variables

External variables are accessed read-only, by module functions taking no arguments. They are spelled exactly like their C counterparts. Sometimes, this leads to module functions beginning with an uppercase letter (e.g. Ncurses.LINES).

One of these external variables, ESCDELAY, is also settable with a ruby method (Ncurses.ESCDELAY=).


(static C Preprocessor macros)

Constants are implemented as module constants in the Ncurses module, if possible. Ruby constants can not start with an underscore, so these constants have been renamed (they lost the leading underscore). There are,however, module functions with the same name as these constants, that also return the constant’s value, when invoked (e.g. “Ncurses._ENDLINE” returns the value of the constant “Ncurses::ENDLINE”, which has the same value as the C constant “_ENDLINE”).

Note: The ncurses macros starting with ACS_ are not constants, their value depends on the terminal in use. Nevertheless, they are implemented as constants of the Ncurses module, but since they depend on the terminal, they are not initialized before initscr() has been called. If you need more than one terminal in a single program, you can access the ACS_ values through member functions of class SCREEN.


Functions (also those only implemented by macros in C) can also be accessed through module functions of the Module Ncurses. They take exactly the same arguments as their C counterparts. Some of the C functions return additional arguments through pointer arguments. These are implemented as follows:

Functions expecting pointers to integer types

When the C-function expects a pointer to int, short, chtype, or attr_type, You should use a variable containing an empty array as the argument to the ruby function. This is because ruby passes these types (ints) “by value” instead of “by reference”; but arrays are passed by reference, so that you can see the changes to them. Attention: some macro-only functions like getsyx accept variables of type int, but, being macros, they write values to their arguments. Thus, they also need empty array arguments when called from ruby. Example: color_pair_number = 4 foreground_color = [] background_color = [] if (Ncurses.pair_content(color_pair_number, foreground_color, background_color) != Ncurses::ERR) “color pair number #color_pair_number contains color number ” + “#0 as the foreground color, and color ” + “number #0 as the background color”) end

There are 2 functions that read a value from the location pointed to by a pointer to int, and store another value at those locations. These functions are mouse_trafo and wmouse_trafo. When calling these functions, you have to provide 2 arrays, each filled with exacly one Integer. The values contained in these arrays will then be changed by the ruby module function.

Functions expecting (non-const) pointers to char

When the C-function expects a pointer to char, you should use a variable containing an empty string as the argument to the ruby function. Example: line2 = “” if (Ncurses.mvwinnstr(Ncurses.stdscr, y=2, x=0, line2, Ncurses.getmaxx(Ncurses.stdscr)) == Ncurses::ERR) raise “could not scan 3rd line” else Ncurses.beep if line2.index(“|”) end The string that the C function would store at the pointer-to-char location will be appended to the given string.

Functions expecting const pointers to char do not modify the string they receive, you can pass any string to them.

Functions expecting pointers to structs

When the C-function expects a pointer to WINDOW, SCREEN, MEVENT, PANEL, FORM, FIELD or FIELDTYPE then simply pass it the corresponding, already existing ruby object.

scanf style functions expecting various pointers

namely scanw, mvscanw, wscanw, mvwscanw. Use an array after the format string. The scanned values will be placed there. Remember, you need scanf for ruby installed for these functions to work.

Module / Class Hierarchie

module Ncurses class WINDOW; end class SCREEN; end class MEVENT; end module Panel class PANEL; end end module Form class FORM; end class FIELD; end class FIELDTYPE; end end end

Where to find the functions

As stated, all ncurses functions are implemented as module functions in the module Ncurses. If you know how an ncurses function is named in C (example: “mvaddch”), then call the corresponding module functions with the same number of arguments (example: “Ncurses.mvaddch(y,x,ch)”)

The class window implements method_missing and tries to map invoked methods to Ncurses module functions using a simple heuristic: If the method name starts with “mv”, it looks for a Ncurses module function that starts with “mvw”, and if it exists, adds itself to the argument list and calls this function. If no such module function exists, or the name of the invoked method does not start with “mv”, it looks if there is a module function with the name “w” + methodname, and if it exists, adds itself again to the argument list and calls this function. If this module function did not exist either, then, as a last step, it invokes a module function with the same name as the method, adding itself to the argument list.

Example: If you invoke win.mvaddch(y,x,ch) on an Ncurses::WINDOW object, it will delegate the method call to Ncurses.mvwaddch(win,y,x,ch).

Other examples:

win.delwin()        =>  Ncurses.delwin(win)          # win cannot be used
                                                     # after this call
win.printw("hello") =>  Ncurses.wprintw(win, "hello")
             x=[])  =>  Ncurses.getmaxyx(win,y,x)

Example programs

Directory “examples” contains a few example programs demonstrating how to use the library with ruby. Be sure to read the file “examples/LICENSES_for_examples”.

Applications using ncurses-ruby

aeditor - Pair programming editor, metaeditor.sourceforge.net/ raggle - RSS aggregator, www.raggle.org/about/

The panel library

The panel library has also been wrapped. All panel functions are implemented as module functions of the module Ncurses::Panel.

Most of these functions are also implemented as methods of class Ncurses::Panel::PANEL, once with their original name and once with the subword “panel” and an adjacent underscore removed.

The form library

The form library was wrapped inside the Ncurses:Form module. All form functions are implemented as module functions on the module Ncurses::Form. In addition, all function for which the first parameter is one of the objects are also implemented as an instance method of that object. For example, instead of calling post_form(form), you can use form.post_form().

Three objects are defined in the Ncurses:Form module: 1. FORM 2. FIELD 3. FIELDTYPE

They are wrapping actual ncurses pointers and should be use whenever a pointer to one of these types is expected in function calls.

All form constants are defined in the module as Ruby constants with the same name as the curses constants.

Constructors for FORM, FIELD and FIELDTYPE objects are also provided, and they expect the same parameters as new_form, new_field and new_fieldtype curses functions.

Field validation is implemented using Ruby Proc objects. You must provide a Ruby block whenever a function pointer is expected in curses function arguments. See the example form2.rb for more details.

The functions form_userptr and field_userptr are not supported. Use form.user_object and field.user_object to store Ruby objects instead.