ffi-ncurses 0.3.3 → 0.4.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.
Files changed (61) hide show
  1. data/COPYING +22 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile.lock +13 -0
  4. data/History.txt +32 -3
  5. data/README.rdoc +118 -58
  6. data/Rakefile +30 -0
  7. data/examples/acs_chars.rb +53 -0
  8. data/examples/acs_chars.rbc +1502 -0
  9. data/examples/{example-attributes.rb → attributes.rb} +0 -0
  10. data/examples/color.rb +63 -0
  11. data/examples/cursor.rb +27 -0
  12. data/examples/example.rb +17 -17
  13. data/examples/getkey.rb +212 -0
  14. data/examples/{example-getsetsyx.rb → getsetsyx.rb} +2 -2
  15. data/examples/globals.rb +38 -0
  16. data/examples/hello.rb +34 -0
  17. data/examples/hello.rbc +638 -0
  18. data/examples/hellowide.rb +59 -0
  19. data/examples/keys.rb +27 -0
  20. data/examples/{example-mouse.rb → mouse.rb} +2 -2
  21. data/examples/multiterm.rb +120 -0
  22. data/examples/ncurses/LICENSES_for_examples +26 -0
  23. data/examples/{ncurses-example.rb → ncurses/example.rb} +13 -80
  24. data/examples/ncurses/hello_ncurses.rb +57 -0
  25. data/examples/ncurses/rain.rb +220 -0
  26. data/examples/ncurses/read_line.rb +67 -0
  27. data/examples/ncurses/subwin.rb +71 -0
  28. data/examples/ncurses/tclock.rb +227 -0
  29. data/examples/newterm.rb +65 -0
  30. data/examples/panel_simple.rb +82 -0
  31. data/examples/{example-printw-variadic.rb → printw-variadic.rb} +1 -1
  32. data/examples/ripoffline.rb +86 -0
  33. data/examples/run-all.sh +14 -0
  34. data/examples/{example-softkeys.rb → softkeys.rb} +0 -0
  35. data/examples/{example-stdscr.rb → stdscr.rb} +2 -1
  36. data/examples/temp_leave.rb +99 -0
  37. data/examples/viewer.rb +350 -0
  38. data/examples/wacs_chars.rb +64 -0
  39. data/examples/windows.rb +73 -0
  40. data/ffi-ncurses.gemspec +39 -52
  41. data/lib/ffi-ncurses.rb +214 -474
  42. data/lib/ffi-ncurses/acs.rb +150 -0
  43. data/lib/ffi-ncurses/bool_wrappers.rb +66 -0
  44. data/lib/ffi-ncurses/functions.rb +450 -0
  45. data/lib/ffi-ncurses/keydefs.rb +136 -99
  46. data/lib/ffi-ncurses/mouse.rb +106 -106
  47. data/lib/ffi-ncurses/ncurses.rb +176 -0
  48. data/lib/ffi-ncurses/{ord-shim.rb → ord_shim.rb} +0 -0
  49. data/lib/ffi-ncurses/panel.rb +21 -0
  50. data/lib/ffi-ncurses/typedefs.rb +35 -0
  51. data/lib/ffi-ncurses/version.rb +7 -0
  52. data/lib/ffi-ncurses/widechars.rb +137 -0
  53. data/lib/ffi-ncurses/winstruct.rb +55 -33
  54. data/spec/attached_functions_spec.rb +42 -0
  55. metadata +95 -85
  56. data/examples/example-colour.rb +0 -63
  57. data/examples/example-cursor.rb +0 -22
  58. data/examples/example-hello.rb +0 -24
  59. data/examples/example-jruby.rb +0 -14
  60. data/examples/example-keys.rb +0 -25
  61. data/examples/example-windows.rb +0 -24
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby; coding: utf-8 -*-
3
+ #
4
+ # Sean O'Halpin, 2009-02-15
5
+ #
6
+ require 'ffi-ncurses'
7
+ require 'ffi-ncurses/widechars'
8
+
9
+ def centre(text)
10
+ col = (COLS() - WideChars.display_width(text.strip))/2
11
+ y, x = getyx(stdscr)
12
+ mvaddstr y, col, text
13
+ end
14
+
15
+ if RUBY_VERSION >= '1.9.0'
16
+ def fullwidth(txt)
17
+ txt.encode("UTF-32BE").codepoints.map{ |x|
18
+ case x
19
+ when 0x30..0x7F
20
+ x + 0xFEE0
21
+ else
22
+ x
23
+ end
24
+ }.pack("U*")
25
+ end
26
+ else
27
+ def fullwidth(txt)
28
+ txt.unpack("U*").map { |x|
29
+ case x
30
+ when 0x30..0x7F
31
+ x + 0xFEE0
32
+ else
33
+ x
34
+ end
35
+ }.pack("U*")
36
+ end
37
+ end
38
+
39
+ include FFI::NCurses
40
+ begin
41
+ greeting = ARGV.shift || "World"
42
+ stdscr = initscr
43
+ raw
44
+ keypad stdscr, true
45
+ noecho
46
+ curs_set 0
47
+ clear
48
+ move (LINES() - 3)/3, 0
49
+ centre "Hello " + greeting + "\n"
50
+ centre "你好\n"
51
+ centre "HELLO WORLD\n"
52
+ centre fullwidth("[Testing 1234]\n\n")
53
+ centre "Press any key to continue"
54
+ refresh
55
+ ch = getch
56
+ ensure
57
+ flushinp
58
+ endwin
59
+ end
@@ -0,0 +1,27 @@
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
+ raw
10
+ keypad stdscr, true
11
+ noecho
12
+ curs_set 0
13
+ ch = 0
14
+ name = "none"
15
+ # while ch != 27 # Escape
16
+ while ch != KEY_CTRL_Q
17
+ clear
18
+ addstr "Press any key (Ctrl-Q to exit): "
19
+ #printw "name: %s dec: %d char: [%c]", :string, name, :int, ch, :int, ch
20
+ addstr sprintf("name: %s dec: %d char: [%s]", name, ch, (1..127).include?(ch) ? ch.chr : " ")
21
+ refresh
22
+ ch = getch
23
+ name = keyname(ch)
24
+ end
25
+ ensure
26
+ endwin
27
+ end
@@ -4,7 +4,7 @@
4
4
  #
5
5
  require 'ffi-ncurses'
6
6
  require 'ffi-ncurses/mouse'
7
- require 'ffi-ncurses/ord-shim' # for 1.8.6 compatibility
7
+ require 'ffi-ncurses/ord_shim' # for 1.8.6 compatibility
8
8
 
9
9
  include FFI::NCurses
10
10
 
@@ -13,7 +13,7 @@ begin
13
13
  clear
14
14
  noecho
15
15
  cbreak
16
- keypad stdscr, FFI::NCurses::TRUE
16
+ keypad stdscr, true
17
17
 
18
18
  # Get all the mouse events
19
19
  mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, nil)
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ffi-ncurses'
3
+
4
+ # newterm2 - how to use more than one terminal at a time
5
+ #
6
+ # Note: ncurses knows nothing about your window manager so cannot
7
+ # switch window focus for you.
8
+ #
9
+ # This is how programmers used to do multi-screen - with more than one
10
+ # physical terminal. Typically, one would be used for input, the other
11
+ # for output.
12
+ #
13
+ # It might be useful for outputting debug info during a program for
14
+ # instance.
15
+
16
+ def log(*a)
17
+ File.open("ncurses.log", "a") do |file|
18
+ file.puts(a.inspect)
19
+ end
20
+ end
21
+
22
+ module CLib
23
+ extend FFI::Library
24
+ ffi_lib FFI::Library::LIBC
25
+ # FILE* open and close
26
+ typedef :pointer, :FILEP
27
+ attach_function :fdopen, [:int, :string], :FILEP
28
+ attach_function :fopen, [:string, :string], :FILEP
29
+ attach_function :fclose, [:FILEP], :int
30
+ attach_function :feof, [:FILEP], :int
31
+
32
+ module FileExt
33
+ def closed?
34
+ CLib.feof(self) ? true : false
35
+ end
36
+
37
+ def close
38
+ if closed?
39
+ raise IOError, "closed stream"
40
+ else
41
+ CLib.fclose(self)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ def usage
49
+ abort "usage: #{$0} term1 term2\ne.g. #{$0} /dev/pts/0 /dev/pts/1"
50
+ end
51
+
52
+ if ARGV.size != 2
53
+ usage
54
+ end
55
+ term1 = ARGV[0]
56
+ term2 = ARGV[1]
57
+
58
+ if File.exist?(term1)
59
+ term1_file = File.open(term1, "rb+")
60
+ if !term1_file.tty?
61
+ term1_file.close
62
+ usage
63
+ end
64
+ end
65
+
66
+ if File.exist?(term1)
67
+ term2_file = File.open(term2, "rb+")
68
+ if !term2_file.tty?
69
+ term2_file.close
70
+ term1_file.close
71
+ usage
72
+ end
73
+ end
74
+
75
+ begin
76
+ tty1 = CLib.fdopen(term1_file.fileno, "rb+")
77
+ tty1.extend(CLib::FileExt)
78
+ tty2 = CLib.fdopen(term2_file.fileno, "rb+")
79
+ tty2.extend(CLib::FileExt)
80
+ screen1 = FFI::NCurses.newterm(nil, tty1, tty1)
81
+ screen2 = FFI::NCurses.newterm(nil, tty2, tty2)
82
+ FFI::NCurses.noecho
83
+ [[screen1, "Hello"], [screen2, "World"]].each do |screen, text|
84
+ old_screen = FFI::NCurses.set_term(screen)
85
+ FFI::NCurses.curs_set(0)
86
+ FFI::NCurses.border(*([0]*8))
87
+ FFI::NCurses.move(4, 4)
88
+ FFI::NCurses.addstr(text)
89
+ FFI::NCurses.refresh
90
+ FFI::NCurses.flushinp
91
+ end
92
+ FFI::NCurses.set_term(screen1)
93
+ FFI::NCurses.curs_set(1)
94
+ FFI::NCurses.getch
95
+ rescue => e
96
+ log :e1, e
97
+ ensure
98
+ begin
99
+ # Watch the ordering of these calls, i.e. do not call delscreen
100
+ # before endwin
101
+ FFI::NCurses.flushinp
102
+ FFI::NCurses.echo
103
+
104
+ # close each terminal
105
+ [screen2, screen1].each do |screen|
106
+ FFI::NCurses.set_term(screen)
107
+ FFI::NCurses.endwin
108
+ FFI::NCurses.delscreen(screen)
109
+ end
110
+ rescue => e
111
+ log :e2, e
112
+ ensure
113
+ # [tty2, tty1] do |fd|
114
+ # CLib.fclose(fd)
115
+ # end
116
+ [tty2, tty1, term2_file, term1_file].each do |fd|
117
+ fd.close if !fd.closed? # handle case where tty1 == tty2
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,26 @@
1
+ $Id: LICENSES_for_examples,v 1.6 2004/05/13 21:55:17 t-peters Exp $
2
+
3
+ Ideally, an example program on how to use a library should be in the public
4
+ domain.
5
+
6
+ Some of the example programs contained in this dircectory have not been put in
7
+ the public domain, however.
8
+
9
+ The reason is because I did not write all programs completely myself -- I've
10
+ adapted the following example programs from ncurses programs in other
11
+ programming languages, or I have included example programs contributed by
12
+ other authors, and I have to respect their original licenses:
13
+ - rain.rb is adapted from rain.c from the ncurses library distribution.
14
+ - example.rb is adapted from an example program for the python ncurses binding.
15
+ - tclock.rb is adapted from tclock.c from the ncurses library distribution.
16
+ - form.rb anf form2.rb have been written by Simon Kaczor, who has adapted them
17
+ from sample code from the NCurses Programming HOWTO.
18
+
19
+ See the comments in the source files for restrictions imposed on copying and
20
+ modifying these.
21
+
22
+ That said, I suppose you may still look at their source code and learn how
23
+ ncurses programs generally work, as long as you dont start your own programs
24
+ by loading the example program into your editor and modify it to your needs.
25
+
26
+ Tobias Peters <t-peters@users.berlios.de>
@@ -6,8 +6,8 @@
6
6
  # Copyright (C) 2002 Tobias Peters <t-peters@users.berlios.de>
7
7
  #
8
8
  # The following license applys only to this file. It is less restrictive
9
- # than the license for the rest of the ncurses-ruby distribution.
10
- # I've adapted this file from someone else, see below.
9
+ # than the license for the rest of the ncurses-ruby distribution.
10
+ # I've adapted this file from someone else, see below.
11
11
  #
12
12
  # Permission is hereby granted, free of charge, to any person
13
13
  # obtaining a copy of this file
@@ -16,10 +16,10 @@
16
16
  # publish, distribute, sublicense, and/or sell copies of the Software,
17
17
  # and to permit persons to whom the Software is furnished to do so,
18
18
  # subject to the following conditions:
19
- #
19
+ #
20
20
  # The above copyright notice and this permission notice shall be
21
21
  # included in all copies or substantial portions of the Software.
22
- #
22
+ #
23
23
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
24
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
25
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -36,7 +36,7 @@
36
36
  # statement:
37
37
 
38
38
  # Copyright (c) 2000 by Harry Henry Gebel
39
- #
39
+ #
40
40
  # Permission is hereby granted, free of charge, to any person
41
41
  # obtaining a copy of this software and associated documentation files
42
42
  # (the "Software"), to deal in the Software without restriction,
@@ -44,10 +44,10 @@
44
44
  # publish, distribute, sublicense, and/or sell copies of the Software,
45
45
  # and to permit persons to whom the Software is furnished to do so,
46
46
  # subject to the following conditions:
47
- #
47
+ #
48
48
  # The above copyright notice and this permission notice shall be
49
49
  # included in all copies or substantial portions of the Software.
50
- #
50
+ #
51
51
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
52
52
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53
53
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -57,73 +57,9 @@
57
57
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
58
58
  # SOFTWARE.
59
59
 
60
- require "ffi-ncurses"
61
- require 'ffi-ncurses/ord-shim' # for 1.8.6 compatibility
62
60
 
63
- module NcursesExtension
64
- def method_missing(method, *args, &block)
65
- FFI::NCurses.send(method, self.win, *args, &block)
66
- end
67
- end
68
61
 
69
- module Ncurses
70
- FALSE = 0
71
- TRUE = 1
72
- module NCX
73
- def COLS
74
- FFI::NCurses.getmaxx(FFI::NCurses.stdscr)
75
- end
76
- end
77
- include NCX
78
- extend NCX
79
- class WINDOW
80
- attr_accessor :win
81
- def initialize(*args, &block)
82
- if block_given?
83
- @win = args.first
84
- else
85
- @win = FFI::NCurses.newwin(*args)
86
- end
87
- end
88
- def method_missing(name, *args)
89
- name = name.to_s
90
- if (name[0,2] == "mv")
91
- test_name = name.dup
92
- test_name[2,0] = "w" # insert "w" after"mv"
93
- if (FFI::NCurses.respond_to?(test_name))
94
- return FFI::NCurses.send(test_name, @win, *args)
95
- end
96
- end
97
- test_name = "w" + name
98
- if (FFI::NCurses.respond_to?(test_name))
99
- return FFI::NCurses.send(test_name, @win, *args)
100
- end
101
- FFI::NCurses.send(name, @win, *args)
102
- end
103
- def respond_to?(name)
104
- name = name.to_s
105
- if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
106
- return true
107
- end
108
- FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
109
- end
110
- def del
111
- FFI::NCurses.delwin(@win)
112
- end
113
- alias delete del
114
- end
115
- def self.initscr
116
- @stdscr = Ncurses::WINDOW.new(FFI::NCurses.initscr) { }
117
- end
118
- def self.stdscr
119
- @stdscr
120
- end
121
- class << self
122
- def method_missing(method, *args, &block)
123
- FFI::NCurses.send(method, *args, &block)
124
- end
125
- end
126
- end
62
+ require "ncurses"
127
63
 
128
64
  def moving(scr)
129
65
  scr.clear() # clear screen
@@ -175,14 +111,11 @@ begin
175
111
  Ncurses.cbreak # provide unbuffered input
176
112
  Ncurses.noecho # turn off input echoing
177
113
  Ncurses.nonl # turn off newline translation
178
- # Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt
179
- # Ncurses.stdscr.keypad(true) # turn on keypad mode
180
- # Ncurses.stdscr.addstr("Press a key to continue") # output string
181
- # Ncurses.stdscr.getch # get a charachter
182
- Ncurses.stdscr.intrflush(Ncurses::FALSE) # turn off flush-on-interrupt
183
- Ncurses.stdscr.keypad(Ncurses::TRUE) # turn on keypad mode
184
- Ncurses.addstr("Press a key to continue") # output string
185
- Ncurses.getch() # get a charachter
114
+ Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt
115
+ Ncurses.stdscr.keypad(true) # turn on keypad mode
116
+
117
+ Ncurses.stdscr.addstr("Press a key to continue") # output string
118
+ Ncurses.stdscr.getch # get a charachter
186
119
 
187
120
  moving(Ncurses.stdscr) # demo of moving cursor
188
121
  border(Ncurses.stdscr) # demo of borders
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: hello_ncurses.rb,v 1.3 2002/02/28 13:50:03 t-peters Exp $
4
+
5
+ # this ncurses-ruby program follows an ancient tradition of example
6
+ # computer programs: When invoked, it prints a friendly greeting on the
7
+ # screen and exits.
8
+ #
9
+ # Copyright (C) 2002 Tobias Peters <t-peters@users.berlios.de>
10
+ #
11
+ # You may use, modify, and redistribute this file without restriction.
12
+
13
+
14
+
15
+ # First, we have to tell Ruby to use the Ncurses extension module:
16
+
17
+ require "ncurses"
18
+
19
+
20
+
21
+ # Second, every program using ncurses must initialize the ncurses library
22
+ # before the first call to any ncurses function:
23
+
24
+ Ncurses.initscr
25
+
26
+
27
+
28
+ # Now the program can use ncurses facilities for screen output. It will print
29
+ # a greeting to the 5th line on the screen, starting at column 20
30
+
31
+ Ncurses.mvaddstr(4, 19, "Hello, world!");
32
+
33
+ # Note that ncurses counts lines and columns starting from 0, and that it
34
+ # expects the line number first and the column number second every time it
35
+ # expects a coordinate pair.
36
+
37
+
38
+
39
+ # The previous function call did not alter the screen at all. Ncurses makes
40
+ # all changes first to an internal buffer. The contents of this buffer is
41
+ # copied to the screen with the following function call:
42
+
43
+ Ncurses.refresh
44
+
45
+
46
+ # Now pause for a short while, enough time for the program user to read the
47
+ # greeting and greet back.
48
+
49
+ sleep(2.5)
50
+
51
+
52
+ # The program has almost finished its task. It only needs to put the screen
53
+ # back to its normal state:
54
+
55
+ Ncurses.endwin
56
+
57
+