ffi-ncurses 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
+