ffi-ncurses 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +22 -0
- data/README.rdoc +220 -0
- data/Rakefile +50 -0
- data/examples/doc-eg1.rb +14 -0
- data/examples/doc-eg2.rb +23 -0
- data/examples/example-attributes.rb +40 -0
- data/examples/example-colour.rb +62 -0
- data/examples/example-cursor.rb +22 -0
- data/examples/example-getsetsyx.rb +55 -0
- data/examples/example-hello.rb +24 -0
- data/examples/example-jruby.rb +14 -0
- data/examples/example-keys.rb +25 -0
- data/examples/example-mouse.rb +50 -0
- data/examples/example-printw-variadic.rb +15 -0
- data/examples/example-softkeys.rb +22 -0
- data/examples/example-stdscr.rb +18 -0
- data/examples/example-windows.rb +24 -0
- data/examples/example.rb +108 -0
- data/ffi-ncurses.gemspec +37 -0
- data/lib/ffi-ncurses.rb +584 -0
- data/lib/ffi-ncurses/darwin.rb +215 -0
- data/lib/ffi-ncurses/keydefs.rb +106 -0
- data/lib/ffi-ncurses/mouse.rb +146 -0
- data/lib/ffi-ncurses/winstruct.rb +177 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +300 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +109 -0
data/History.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
== 0.3.0 / 2009-02-15
|
2
|
+
|
3
|
+
* Features
|
4
|
+
* Use FFI::NCurses rather than NCurses
|
5
|
+
* Removed dependency on rubygems
|
6
|
+
* Reorganised library layout
|
7
|
+
|
8
|
+
== 0.2.0 / 2009-02-03
|
9
|
+
|
10
|
+
* Features
|
11
|
+
* Initial gem release
|
12
|
+
* Most features of ncurses wrapped for Linux, Mac, ruby 1.8.6
|
13
|
+
and JRuby 1.1.6
|
14
|
+
|
15
|
+
* Bugs
|
16
|
+
* +newscr+ and +curscr+ cannot be implemented in JRuby until
|
17
|
+
find_sym implemented in ffi (expected in JRuby 1.1.7)
|
18
|
+
|
19
|
+
== 0.1.0 / 2009-01-19
|
20
|
+
|
21
|
+
* Features
|
22
|
+
* Initial release
|
data/README.rdoc
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
= ffi-ncurses
|
2
|
+
|
3
|
+
Author: Sean O'Halpin
|
4
|
+
|
5
|
+
A wrapper for ncurses 5.x. Tested on Mac OS X 10.4 (Tiger) and Ubuntu
|
6
|
+
8.04 with ruby 1.8.6 using ruby-ffi (>= 0.2.0) and JRuby 1.1.6.
|
7
|
+
|
8
|
+
The API is very much a transliteration of the C API rather than an
|
9
|
+
attempt to provide an idiomatic Ruby object-oriented API. The intent
|
10
|
+
is to provide a 'close to the metal' wrapper around the ncurses
|
11
|
+
library upon which you can build your own abstractions.
|
12
|
+
|
13
|
+
This is still very much a work-in-progress, so expect some rough
|
14
|
+
edges. Having said that, you can do quite a lot with it as it is. The
|
15
|
+
main things left to be done are tests, access to global variables and
|
16
|
+
various macros.
|
17
|
+
|
18
|
+
Below are some very preliminary notes on usage. See the examples
|
19
|
+
directory for real working examples.
|
20
|
+
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
Load the library with:
|
24
|
+
|
25
|
+
require 'ffi-ncurses'
|
26
|
+
|
27
|
+
FFI::NCurses methods can be called as module methods:
|
28
|
+
|
29
|
+
begin
|
30
|
+
stdscr = FFI::NCurses.initscr
|
31
|
+
FFI::NCurses.clear
|
32
|
+
FFI::NCurses.addstr("Hello world!")
|
33
|
+
FFI::NCurses.refresh
|
34
|
+
FFI::NCurses.getch
|
35
|
+
ensure
|
36
|
+
FFI::NCurses.endwin
|
37
|
+
end
|
38
|
+
|
39
|
+
or as included methods:
|
40
|
+
|
41
|
+
require 'ffi-ncurses'
|
42
|
+
include FFI::NCurses
|
43
|
+
begin
|
44
|
+
stdscr = initscr
|
45
|
+
start_color
|
46
|
+
curs_set 0
|
47
|
+
raw
|
48
|
+
cbreak
|
49
|
+
noecho
|
50
|
+
clear
|
51
|
+
move 10, 10
|
52
|
+
standout
|
53
|
+
addstr("Hi!")
|
54
|
+
standend
|
55
|
+
refresh
|
56
|
+
getch
|
57
|
+
ensure
|
58
|
+
endwin
|
59
|
+
end
|
60
|
+
|
61
|
+
== Set up screen
|
62
|
+
|
63
|
+
require 'ffi-ncurses'
|
64
|
+
|
65
|
+
FFI::NCurses.initscr
|
66
|
+
begin
|
67
|
+
...
|
68
|
+
ensure
|
69
|
+
FFI::NCurses.endwin
|
70
|
+
end
|
71
|
+
|
72
|
+
== Typical initialization
|
73
|
+
|
74
|
+
stdscr = FFI::NCurses.initscr
|
75
|
+
FFI::NCurses.start_color
|
76
|
+
FFI::NCurses.curs_set 0
|
77
|
+
FFI::NCurses.raw
|
78
|
+
FFI::NCurses.cbreak
|
79
|
+
FFI::NCurses.noecho
|
80
|
+
FFI::NCurses.keypad(stdscr, true)
|
81
|
+
|
82
|
+
== Colours
|
83
|
+
|
84
|
+
start_color
|
85
|
+
init_pair(1, FFI::NCurses::COLOR_BLACK, FFI::NCurses::COLOR_RED)
|
86
|
+
attr_set FFI::NCurses::A_NORMAL, 1, nil
|
87
|
+
addch(?A)
|
88
|
+
addch(?Z | COLOR_PAIR(1))
|
89
|
+
|
90
|
+
== Cursor
|
91
|
+
|
92
|
+
=== Turn cursor off
|
93
|
+
|
94
|
+
FFI::NCurses.curs_set 0
|
95
|
+
|
96
|
+
=== Turn cursor on
|
97
|
+
|
98
|
+
FFI::NCurses.curs_set 1
|
99
|
+
|
100
|
+
== Windows
|
101
|
+
|
102
|
+
require 'ffi-ncurses'
|
103
|
+
begin
|
104
|
+
win = newwin(6, 12, 15, 15)
|
105
|
+
box(win, 0, 0)
|
106
|
+
inner_win = newwin(4, 10, 16, 16)
|
107
|
+
waddstr(inner_win, (["Hello window!"] * 5).join(' '))
|
108
|
+
wrefresh(win)
|
109
|
+
wrefresh(inner_win)
|
110
|
+
ch = wgetch(inner_win)
|
111
|
+
|
112
|
+
rescue Object => e
|
113
|
+
FFI::NCurses.endwin
|
114
|
+
puts e
|
115
|
+
ensure
|
116
|
+
FFI::NCurses.endwin
|
117
|
+
end
|
118
|
+
|
119
|
+
== Mouse handling
|
120
|
+
|
121
|
+
The ncurses mouse API is defined in a separate file. To include it use:
|
122
|
+
|
123
|
+
require 'ffi-ncurses/mouse'
|
124
|
+
|
125
|
+
You need to specify that you want keypad translation with:
|
126
|
+
|
127
|
+
keypad stdscr, FFI::NCurses::TRUE
|
128
|
+
|
129
|
+
otherwise your program will receive the raw mouse escape codes,
|
130
|
+
instead of KEY_MOUSE mouse event codes.
|
131
|
+
|
132
|
+
Specify which events you want to handle with:
|
133
|
+
|
134
|
+
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, nil)
|
135
|
+
|
136
|
+
and set up a mouse event structure to receive the returned values:
|
137
|
+
|
138
|
+
mouse_event = FFI::NCurses::MEVENT.new
|
139
|
+
|
140
|
+
Receiving mouse events is a two-stage process: first, you are notified
|
141
|
+
that a mouse event has taken place through a special key code, then
|
142
|
+
you retrieve the event using +getmouse+. For example:
|
143
|
+
|
144
|
+
ch = getch
|
145
|
+
case ch
|
146
|
+
when FFI::NCurses::KEY_MOUSE
|
147
|
+
if getmouse(mouse_event) == FFI::NCurses::OK
|
148
|
+
|
149
|
+
The mouse event contains the button state (+bstate+) and x, y
|
150
|
+
coordinates. You can test for the button state using:
|
151
|
+
|
152
|
+
if mouse_event[:bstate] & FFI::NCurses::BUTTON1_PRESSED
|
153
|
+
|
154
|
+
or
|
155
|
+
|
156
|
+
if FFI::NCurses.BUTTON_PRESS(mouse_event[:bstate], 1)
|
157
|
+
|
158
|
+
The possible button states are: PRESS, RELEASE, CLICK, DOUBLE_CLICK
|
159
|
+
and TRIPLE_CLICK.
|
160
|
+
|
161
|
+
= Experimental stuff
|
162
|
+
|
163
|
+
== Specifying which curses library to use
|
164
|
+
|
165
|
+
You can specify which variant of curses you want to use by setting the
|
166
|
+
environment variable +RUBY_FFI_NCURSES_LIB+ to the one you want. For
|
167
|
+
example, to use PDCurses X11 curses lib, use:
|
168
|
+
|
169
|
+
RUBY_FFI_NCURSES_LIB=XCurses ruby examples/hello.rb
|
170
|
+
|
171
|
+
You can use this to specify +ncursesw+ for example. Please note that
|
172
|
+
only the bog standard ncurses lib has been in any way tested as of
|
173
|
+
yet.
|
174
|
+
|
175
|
+
= TO DO
|
176
|
+
|
177
|
+
== Complete translation of core functions to Darwin (Mac OS X)
|
178
|
+
|
179
|
+
There are some macros in darwin ncurses.h which I haven't
|
180
|
+
implemented yet. I'm working on it but if there are any you
|
181
|
+
desperately need let me know.
|
182
|
+
|
183
|
+
== +curscr+ and +newscr+ for JRuby
|
184
|
+
|
185
|
+
These global variables are not often used but are required for certain
|
186
|
+
situations (e.g. doing a wrefresh after shelling out and for the
|
187
|
+
get/setsyx macros).
|
188
|
+
|
189
|
+
This requires the implementation of +find_sym+ in JRuby (expected in
|
190
|
+
JRuby 1.1.7).
|
191
|
+
|
192
|
+
== Tests
|
193
|
+
|
194
|
+
This is tricky - I'm not sure exactly how to properly test a wrapper
|
195
|
+
for a library like ncurses. I certainly don't want to test ncurses!
|
196
|
+
Instead, I want to ensure my wrapper faithfully reproduces the
|
197
|
+
functionality of the platform's ncurses lib. To that end, I'm
|
198
|
+
experimenting with a simple DSL to generate both C and Ruby versions
|
199
|
+
of a test. With that I can generate equivalent programs and compare
|
200
|
+
the output. However, this is not really ready for prime time yet.
|
201
|
+
|
202
|
+
== Tidy up internals and examples
|
203
|
+
|
204
|
+
Things got a bit messy as I switched between the Linux and Mac
|
205
|
+
versions. The examples should be more focussed.
|
206
|
+
|
207
|
+
== Scope implementation of Menu and Form interface wrappers
|
208
|
+
|
209
|
+
I'm not particularly interested in the ncurses extension libraries for
|
210
|
+
forms and menus. I would rather spend time implementing similar
|
211
|
+
functionality on top of a portable text console library (or porting
|
212
|
+
rbcurses). However, in the interests of completeness, I suppose I
|
213
|
+
ought to at least scope it out.
|
214
|
+
|
215
|
+
= Trivia
|
216
|
+
|
217
|
+
While researching ncurses on Google, I innocently entered "curses
|
218
|
+
getsx" as a search term. NSFW and definitely not one for "I'm Feeling
|
219
|
+
Lucky".
|
220
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bones'
|
7
|
+
Bones.setup
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
load 'tasks/setup.rb'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ensure_in_path 'lib'
|
17
|
+
require 'ffi-ncurses'
|
18
|
+
|
19
|
+
task :default => 'spec:run'
|
20
|
+
|
21
|
+
# see tasks/setup.rb for full list of options
|
22
|
+
|
23
|
+
PROJ.name = 'ffi-ncurses'
|
24
|
+
PROJ.authors = ["Sean O'Halpin"]
|
25
|
+
PROJ.email = 'sean.ohalpin@gmail.com'
|
26
|
+
PROJ.url = 'http://github.com/seanohalpin/ffi-ncurses'
|
27
|
+
PROJ.summary = "FFI wrapper for ncurses"
|
28
|
+
PROJ.version = "0.3.0"
|
29
|
+
PROJ.rubyforge.name = 'ffi-ncurses'
|
30
|
+
|
31
|
+
# gem
|
32
|
+
PROJ.gem.dependencies << ["ffi", ">= 0.2.0"]
|
33
|
+
|
34
|
+
# rdoc
|
35
|
+
PROJ.rdoc.exclude << "^notes"
|
36
|
+
PROJ.readme_file = 'README.rdoc'
|
37
|
+
|
38
|
+
# spec
|
39
|
+
PROJ.spec.opts << '--color'
|
40
|
+
|
41
|
+
# files
|
42
|
+
PROJ.exclude = %w(tmp$ bak$ ~$ CVS \.svn ^pkg ^doc \.git local notes)
|
43
|
+
PROJ.exclude << '^tags$' << "^bug" << "^tools"
|
44
|
+
PROJ.exclude << File.read('.gitignore').split(/\n/)
|
45
|
+
|
46
|
+
# notes
|
47
|
+
#PROJ.notes.exclude = %w(^README\.txt$ ^data/)
|
48
|
+
PROJ.notes.extensions << '.org'
|
49
|
+
|
50
|
+
# EOF
|
data/examples/doc-eg1.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Sean O'Halpin, 2009-02-15
|
4
|
+
#
|
5
|
+
require 'ffi-ncurses'
|
6
|
+
begin
|
7
|
+
stdscr = FFI::NCurses.initscr
|
8
|
+
FFI::NCurses.clear
|
9
|
+
FFI::NCurses.addstr("Hello world!")
|
10
|
+
FFI::NCurses.refresh
|
11
|
+
FFI::NCurses.getch
|
12
|
+
ensure
|
13
|
+
FFI::NCurses.endwin
|
14
|
+
end
|
data/examples/doc-eg2.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Sean O'Halpin, 2009-02-15
|
4
|
+
#
|
5
|
+
require 'ffi-ncurses'
|
6
|
+
include FFI::NCurses
|
7
|
+
begin
|
8
|
+
stdscr = initscr
|
9
|
+
start_color
|
10
|
+
curs_set 0
|
11
|
+
raw
|
12
|
+
cbreak
|
13
|
+
noecho
|
14
|
+
clear
|
15
|
+
move 10, 10
|
16
|
+
standout
|
17
|
+
addstr("Hi!")
|
18
|
+
standend
|
19
|
+
refresh
|
20
|
+
getch
|
21
|
+
ensure
|
22
|
+
endwin
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Sean O'Halpin, 2009-02-15
|
4
|
+
#
|
5
|
+
require 'ffi-ncurses'
|
6
|
+
include FFI::NCurses
|
7
|
+
initscr
|
8
|
+
begin
|
9
|
+
attributes = %w[
|
10
|
+
A_BLINK
|
11
|
+
A_BOLD
|
12
|
+
A_DIM
|
13
|
+
A_NORMAL
|
14
|
+
A_REVERSE
|
15
|
+
A_STANDOUT
|
16
|
+
A_UNDERLINE
|
17
|
+
]
|
18
|
+
alt_attributes = %w[
|
19
|
+
A_ALTCHARSET
|
20
|
+
A_HORIZONTAL
|
21
|
+
A_INVIS
|
22
|
+
A_LEFT
|
23
|
+
A_LOW
|
24
|
+
A_PROTECT
|
25
|
+
A_RIGHT
|
26
|
+
A_TOP
|
27
|
+
A_VERTICAL
|
28
|
+
]
|
29
|
+
|
30
|
+
attributes.each do |attr|
|
31
|
+
attr_const = FFI::NCurses.const_get(attr)
|
32
|
+
attr_set attr_const, 0, nil
|
33
|
+
addstr "THIS IS #{attr}\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
refresh
|
37
|
+
ch = getch
|
38
|
+
ensure
|
39
|
+
endwin
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Sean O'Halpin, 2009-02-15
|
4
|
+
#
|
5
|
+
require 'ffi-ncurses'
|
6
|
+
include FFI::NCurses
|
7
|
+
|
8
|
+
initscr
|
9
|
+
begin
|
10
|
+
# turn cursor off
|
11
|
+
curs_set 0
|
12
|
+
|
13
|
+
# initialize colour
|
14
|
+
start_color
|
15
|
+
|
16
|
+
# set up colour pairs
|
17
|
+
# Background Foreground
|
18
|
+
init_pair(0, Colour::BLACK, Colour::BLACK)
|
19
|
+
init_pair(1, Colour::RED, Colour::BLACK)
|
20
|
+
init_pair(2, Colour::GREEN, Colour::BLACK)
|
21
|
+
init_pair(3, Colour::YELLOW, Colour::BLACK)
|
22
|
+
init_pair(4, Colour::BLUE, Colour::BLACK)
|
23
|
+
init_pair(5, Colour::MAGENTA, Colour::BLACK)
|
24
|
+
init_pair(6, Colour::CYAN, Colour::BLACK)
|
25
|
+
init_pair(7, Colour::WHITE, Colour::BLACK)
|
26
|
+
|
27
|
+
init_pair(8, Colour::BLACK, Colour::BLACK)
|
28
|
+
init_pair(9, Colour::BLACK, Colour::RED)
|
29
|
+
init_pair(10, Colour::BLACK, Colour::GREEN)
|
30
|
+
init_pair(11, Colour::BLACK, Colour::YELLOW)
|
31
|
+
init_pair(12, Colour::BLACK, Colour::BLUE)
|
32
|
+
init_pair(13, Colour::BLACK, Colour::MAGENTA)
|
33
|
+
init_pair(14, Colour::BLACK, Colour::CYAN)
|
34
|
+
init_pair(15, Colour::BLACK, Colour::WHITE)
|
35
|
+
|
36
|
+
0.upto(15) do |i|
|
37
|
+
attr_set A_NORMAL, i, nil
|
38
|
+
addch(?A + i)
|
39
|
+
end
|
40
|
+
|
41
|
+
# add character and attribute together
|
42
|
+
addch(?Z | COLOR_PAIR(1)) # red
|
43
|
+
|
44
|
+
# reset attribute and colour to default
|
45
|
+
attr_set A_NORMAL, 0, nil
|
46
|
+
|
47
|
+
# start new line
|
48
|
+
addstr "\n"
|
49
|
+
|
50
|
+
# how to add a single space
|
51
|
+
addch(' '[0])
|
52
|
+
# or
|
53
|
+
addstr(" ")
|
54
|
+
|
55
|
+
addstr "Press any key"
|
56
|
+
|
57
|
+
# display and pause for key press
|
58
|
+
refresh
|
59
|
+
ch = getch
|
60
|
+
ensure
|
61
|
+
endwin
|
62
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Sean O'Halpin, 2009-02-15
|
4
|
+
#
|
5
|
+
require 'ffi-ncurses'
|
6
|
+
include FFI::NCurses
|
7
|
+
begin
|
8
|
+
initscr
|
9
|
+
addstr "Default"
|
10
|
+
getch
|
11
|
+
addstr "curs_set 0"
|
12
|
+
curs_set 0
|
13
|
+
getch
|
14
|
+
addstr "curs_set 1"
|
15
|
+
curs_set 1
|
16
|
+
getch
|
17
|
+
addstr "curs_set 2"
|
18
|
+
curs_set 2
|
19
|
+
getch
|
20
|
+
ensure
|
21
|
+
FFI::NCurses.endwin
|
22
|
+
end
|