-
Notifications
You must be signed in to change notification settings - Fork 20
/
README
355 lines (274 loc) · 12.9 KB
/
README
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
353
354
$Id: README,v 1.16 2009/05/03 14:13:27 t-peters Exp $
------------------------------------------------------------------------
This directory contains a ruby module for accessing the FSF's ncurses
library.
(C) 2002, 2003, 2004 Tobias Peters <[email protected]>
(C) 2004 Simon Kaczor <[email protected]>
(C) 2005 2006 Tobias Herzke <[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
------------------------------------------------------------------------
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
- Installation and Usage
- External Variables
- Constants
- Functions (and their Interfaces)
- Module / Class Hierarchie
- The WINDOW class
- The panel Library
- The form Library
- The menu Library
- Locale handling
- Ncurses and Ruby Threads
- 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
======================
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 (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, is also settable 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 resizesings 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 (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 " +
"#{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 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
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".