1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
|
$Id: README,v 1.16 2009-05-03 14:13:27 t-peters Exp $y
This directory contains a ruby module for accessing the FSF's ncurses
library.
* (C) 2002, 2003, 2004 Tobias Peters <t-peters@users.berlios.de>
* (C) 2004 Simon Kaczor <skaczor@cox.net>
* (C) 2005 2006 Tobias Herzke <t-peters@users.berlios.de>
* (C) 2013 2014 Gaute Hope <eg@gaute.vetsj.com>
* (C) 2013 2014 Sup developers
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
# Overview
This README file explains how to use the `ncurses` ruby interface. It is
assumed that the reader has a rough understanding of what the `ncurses`
library is and how to use it from the C language. It then goes into
detail, explaining what is covered by the ruby interface, and the
rules that were followed in translating the C interface into a ruby
interface.
This `ncurses` interface 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 README is organized into the following parts:
- [Overview](#overview)
- [Installation and Usage](#installation-and-usage)
- [External Variables](#external-variables)
- [Constants](#constants)
- [Functions (and their Interfaces)](#functions-and-their-interfaces)
- [Module / Class Hierarchy](#module--class-hierarchy)
- [The Window class](#the-window-class)
- [The Panel Library](#the-panel-library)
- [The Form Library](#the-form-library)
- [The Menu Library](#the-menu-library)
- [Locale handling](#locale-handling)
- [Ncurses and Ruby Threads](#ncurses-and-ruby-threads)
- [Example programs](#example-programs)
## General Ncurses Literature
If you don't know how to use `ncurses` from C, then please read an
introduction to `ncurses` before continuing with this README. Eric
Raymond has written an introduction that should be part of the `ncurses`
development package installed on your computer.
If you'd like 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`, a useful
reference while coding.
## Installation and Usage
gem install ncursesw
Or add to your Gemfile
gem 'ncursesw'
If your programs use the `scanw` functions (most unlikely) you will have to
install the `scanf` library for ruby (http://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`, can also be set with a ruby method
(`Ncurses.ESCDELAY=`).
Another external variable, `Ncurses.RESIZEDELAY` is introduced by this wrapper.
It contains the maximum milliseconds delay with which terminal resizings are
recognized.
## Constants
(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 (and their Interfaces)
Functions (also those only implemented by macros in C) can be accessed
as 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 (`int`) "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 " +
"#{foreground_color[0]} as the foreground color, and color " +
"number #{background_color[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 Hierarchy
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
module Menu
class MENU; end
class ITEM; end
end
end
## The Window class
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.printw("hello") => Ncurses.wprintw(win, "hello")
win.getmaxyx(y=[],
x=[]) => Ncurses.getmaxyx(win,y,x)
win.delwin() => Ncurses.delwin(win) # win cannot be used
# after this call
## 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 the respective class. 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.
## The Menu Library
The menu library was wrapped inside the `Ncurses:Menu` module. All
menu functions are implemented as module functions in the module
`Ncurses::Menu`. In addition, all functions for which the first
parameter is one of the objects, are also implemented as an instance
method of the respective class.
For example, instead of calling `post_menu(menu)`, you can use
`menu.post_menu()`.
Two objects are defined in the `Ncurses:Menu` module:
1. `MENU`
2. `ITEM`
They are wrapping actual `ncurses` pointers and should be use whenever a
pointer to one of these types is expected in function calls.
All menu constants are defined in the module as Ruby constants with
the same name as the `curses` constants.
Constructors for `MENU` and `ITEM` objects are also provided, and they
expect the same parameters as `new_menu` and `new_item` curses functions.
You must provide a Ruby block whenever a function pointer is expected
in `curses` function arguments.
The functions `menu_userptr` and `item_userptr` are not supported. Use
`menu.user_object` and `item.user_object` to store Ruby objects instead.
## Locale handling
The C library function `setlocale` is not technically an `ncurses` function.
However, it is used by many `ncurses` programs, and for this purpose,
a wrapper for this function is also included in `ncurses-ruby`.
The function is implemented as a module function `Ncurses.ruby`, and
expects two arguments, an `Integer` and a `String`. It returns a string.
The constants that can be used as the Integer argument are also wrapped
as constants in the `ncurses` module. See the manual page for `setlocale`
for documentation of this function.
## Ncurses and Ruby Threads
The `ncurses` library is not thread-safe. Your application must properly
serialize calls into `ncurses`.
Prior to release 0.9.2, the `getch` and `wgetch` calls used to block the
complete ruby interpreter, all threads. This is no longer so. Other
threads should now continue to run during blocking calls to `getch` and
`wgetch`.
## Example programs
Directory `examples` contains a few example programs demonstrating how
to use the ncurses library with ruby. Be sure to read the file
`examples/LICENSES_for_examples`.
|