curses 1.2.7 → 1.4.1

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 (254) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +19 -0
  3. data/.github/workflows/ubuntu.yml +26 -0
  4. data/.github/workflows/windows.yml +25 -0
  5. data/.gitmodules +1 -1
  6. data/History.md +41 -0
  7. data/README.md +14 -46
  8. data/Rakefile +0 -83
  9. data/curses.gemspec +2 -3
  10. data/ext/curses/curses.c +1314 -176
  11. data/ext/curses/extconf.rb +140 -17
  12. data/lib/curses.rb +5 -12
  13. data/sample/form.rb +52 -0
  14. data/sample/menu.rb +1 -1
  15. data/vendor/PDCurses/.gitignore +47 -0
  16. data/vendor/PDCurses/.travis.yml +49 -0
  17. data/vendor/PDCurses/CMakeLists.txt +68 -0
  18. data/vendor/PDCurses/HISTORY.md +2036 -0
  19. data/vendor/PDCurses/IMPLEMNT.md +327 -0
  20. data/vendor/PDCurses/README.md +77 -0
  21. data/vendor/PDCurses/acs_defs.h +265 -0
  22. data/vendor/PDCurses/appveyor.yml +218 -0
  23. data/vendor/PDCurses/cmake/README.md +71 -0
  24. data/vendor/PDCurses/cmake/build_dependencies.cmake +178 -0
  25. data/vendor/PDCurses/cmake/build_options.cmake +25 -0
  26. data/vendor/PDCurses/cmake/dll_version.cmake +26 -0
  27. data/vendor/PDCurses/cmake/gen_config_header.cmake +43 -0
  28. data/vendor/PDCurses/cmake/get_version.cmake +17 -0
  29. data/vendor/PDCurses/cmake/make_uninstall.cmake +19 -0
  30. data/vendor/PDCurses/cmake/project_common.cmake +121 -0
  31. data/vendor/PDCurses/cmake/resource.in.cmake +52 -0
  32. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +83 -0
  33. data/vendor/PDCurses/cmake/target_arch.cmake +36 -0
  34. data/vendor/PDCurses/cmake/version.in.cmake +73 -0
  35. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +96 -0
  36. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +106 -0
  37. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +105 -0
  38. data/vendor/PDCurses/curses.h +1846 -0
  39. data/vendor/PDCurses/curspriv.h +134 -0
  40. data/vendor/PDCurses/demos/README.md +25 -0
  41. data/vendor/PDCurses/demos/firework.c +144 -0
  42. data/vendor/PDCurses/demos/newtest.c +581 -0
  43. data/vendor/PDCurses/demos/ozdemo.c +447 -0
  44. data/vendor/PDCurses/demos/ptest.c +283 -0
  45. data/vendor/PDCurses/demos/rain.c +157 -0
  46. data/vendor/PDCurses/demos/testcurs.c +1607 -0
  47. data/vendor/PDCurses/demos/tui.c +1048 -0
  48. data/vendor/PDCurses/demos/tui.h +65 -0
  49. data/vendor/PDCurses/demos/tuidemo.c +233 -0
  50. data/vendor/PDCurses/demos/version.c +61 -0
  51. data/vendor/PDCurses/demos/worm.c +432 -0
  52. data/vendor/PDCurses/demos/xmas.c +955 -0
  53. data/vendor/PDCurses/dos/CMakeLists.txt +47 -0
  54. data/vendor/PDCurses/dos/Makefile.bcc +83 -0
  55. data/vendor/PDCurses/dos/Makefile.dmc +257 -0
  56. data/vendor/PDCurses/dos/Makefile.msc +113 -0
  57. data/vendor/PDCurses/dos/Makefile.wcc +107 -0
  58. data/vendor/PDCurses/dos/README.md +51 -0
  59. data/vendor/PDCurses/dos/bccdos.lrf +9 -0
  60. data/vendor/PDCurses/dos/mscdos.lrf +50 -0
  61. data/vendor/PDCurses/dos/pdcclip.c +132 -0
  62. data/vendor/PDCurses/dos/pdcdisp.c +135 -0
  63. data/vendor/PDCurses/dos/pdcdos.h +194 -0
  64. data/vendor/PDCurses/dos/pdcgetsc.c +98 -0
  65. data/vendor/PDCurses/dos/pdckbd.c +513 -0
  66. data/vendor/PDCurses/dos/pdcscrn.c +785 -0
  67. data/vendor/PDCurses/dos/pdcsetsc.c +101 -0
  68. data/vendor/PDCurses/dos/pdcutil.c +212 -0
  69. data/vendor/PDCurses/libobjs.mif +26 -0
  70. data/vendor/PDCurses/makedist.mif +20 -0
  71. data/vendor/PDCurses/man/README.md +21 -0
  72. data/vendor/PDCurses/man/intro.md +361 -0
  73. data/vendor/PDCurses/man/manext.c +119 -0
  74. data/vendor/PDCurses/man/sdl.md +152 -0
  75. data/vendor/PDCurses/man/sdl2.md +58 -0
  76. data/vendor/PDCurses/man/x11.md +407 -0
  77. data/vendor/PDCurses/ncurses/CMakeLists.txt +66 -0
  78. data/vendor/PDCurses/ncurses/README.md +26 -0
  79. data/vendor/PDCurses/ncurses/makefile +29 -0
  80. data/vendor/PDCurses/os2/CMakeLists.txt +41 -0
  81. data/vendor/PDCurses/os2/Makefile.bcc +90 -0
  82. data/vendor/PDCurses/os2/Makefile.wcc +43 -0
  83. data/vendor/PDCurses/os2/README.md +43 -0
  84. data/vendor/PDCurses/os2/iccos2.lrf +50 -0
  85. data/vendor/PDCurses/os2/iccos2.mak +256 -0
  86. data/vendor/PDCurses/os2/pdcclip.c +188 -0
  87. data/vendor/PDCurses/os2/pdcdisp.c +93 -0
  88. data/vendor/PDCurses/os2/pdcgetsc.c +89 -0
  89. data/vendor/PDCurses/os2/pdckbd.c +521 -0
  90. data/vendor/PDCurses/os2/pdcos2.h +55 -0
  91. data/vendor/PDCurses/os2/pdcscrn.c +449 -0
  92. data/vendor/PDCurses/os2/pdcsetsc.c +112 -0
  93. data/vendor/PDCurses/os2/pdcutil.c +52 -0
  94. data/vendor/PDCurses/panel.h +56 -0
  95. data/vendor/PDCurses/pdcurses/README.md +25 -0
  96. data/vendor/PDCurses/pdcurses/addch.c +693 -0
  97. data/vendor/PDCurses/pdcurses/addchstr.c +245 -0
  98. data/vendor/PDCurses/pdcurses/addstr.c +240 -0
  99. data/vendor/PDCurses/pdcurses/attr.c +359 -0
  100. data/vendor/PDCurses/pdcurses/beep.c +68 -0
  101. data/vendor/PDCurses/pdcurses/bkgd.c +223 -0
  102. data/vendor/PDCurses/pdcurses/border.c +411 -0
  103. data/vendor/PDCurses/pdcurses/clear.c +159 -0
  104. data/vendor/PDCurses/pdcurses/color.c +298 -0
  105. data/vendor/PDCurses/pdcurses/debug.c +109 -0
  106. data/vendor/PDCurses/pdcurses/delch.c +96 -0
  107. data/vendor/PDCurses/pdcurses/deleteln.c +211 -0
  108. data/vendor/PDCurses/pdcurses/deprec.c +27 -0
  109. data/vendor/PDCurses/pdcurses/getch.c +417 -0
  110. data/vendor/PDCurses/pdcurses/getstr.c +474 -0
  111. data/vendor/PDCurses/pdcurses/getyx.c +139 -0
  112. data/vendor/PDCurses/pdcurses/inch.c +127 -0
  113. data/vendor/PDCurses/pdcurses/inchstr.c +214 -0
  114. data/vendor/PDCurses/pdcurses/initscr.c +367 -0
  115. data/vendor/PDCurses/pdcurses/inopts.c +324 -0
  116. data/vendor/PDCurses/pdcurses/insch.c +271 -0
  117. data/vendor/PDCurses/pdcurses/insstr.c +264 -0
  118. data/vendor/PDCurses/pdcurses/instr.c +246 -0
  119. data/vendor/PDCurses/pdcurses/kernel.c +259 -0
  120. data/vendor/PDCurses/pdcurses/keyname.c +157 -0
  121. data/vendor/PDCurses/pdcurses/mouse.c +438 -0
  122. data/vendor/PDCurses/pdcurses/move.c +57 -0
  123. data/vendor/PDCurses/pdcurses/outopts.c +159 -0
  124. data/vendor/PDCurses/pdcurses/overlay.c +214 -0
  125. data/vendor/PDCurses/pdcurses/pad.c +260 -0
  126. data/vendor/PDCurses/pdcurses/panel.c +633 -0
  127. data/vendor/PDCurses/pdcurses/printw.c +126 -0
  128. data/vendor/PDCurses/pdcurses/refresh.c +279 -0
  129. data/vendor/PDCurses/pdcurses/scanw.c +578 -0
  130. data/vendor/PDCurses/pdcurses/scr_dump.c +213 -0
  131. data/vendor/PDCurses/pdcurses/scroll.c +101 -0
  132. data/vendor/PDCurses/pdcurses/slk.c +591 -0
  133. data/vendor/PDCurses/pdcurses/termattr.c +182 -0
  134. data/vendor/PDCurses/pdcurses/terminfo.c +217 -0
  135. data/vendor/PDCurses/pdcurses/touch.c +163 -0
  136. data/vendor/PDCurses/pdcurses/util.c +312 -0
  137. data/vendor/PDCurses/pdcurses/window.c +569 -0
  138. data/vendor/PDCurses/sdl1/Makefile.mng +110 -0
  139. data/vendor/PDCurses/sdl1/README.md +31 -0
  140. data/vendor/PDCurses/sdl1/deffont.h +385 -0
  141. data/vendor/PDCurses/sdl1/deficon.h +23 -0
  142. data/vendor/PDCurses/sdl1/pdcclip.c +131 -0
  143. data/vendor/PDCurses/sdl1/pdcdisp.c +373 -0
  144. data/vendor/PDCurses/sdl1/pdcgetsc.c +30 -0
  145. data/vendor/PDCurses/sdl1/pdckbd.c +405 -0
  146. data/vendor/PDCurses/sdl1/pdcscrn.c +414 -0
  147. data/vendor/PDCurses/sdl1/pdcsdl.h +31 -0
  148. data/vendor/PDCurses/sdl1/pdcsetsc.c +64 -0
  149. data/vendor/PDCurses/sdl1/pdcutil.c +40 -0
  150. data/vendor/PDCurses/sdl1/sdltest.c +79 -0
  151. data/vendor/PDCurses/sdl2/CMakeLists.txt +76 -0
  152. data/vendor/PDCurses/sdl2/Makefile.vc +164 -0
  153. data/vendor/PDCurses/sdl2/README.md +34 -0
  154. data/vendor/PDCurses/sdl2/deffont.h +385 -0
  155. data/vendor/PDCurses/sdl2/deficon.h +23 -0
  156. data/vendor/PDCurses/sdl2/pdcclip.c +93 -0
  157. data/vendor/PDCurses/sdl2/pdcdisp.c +534 -0
  158. data/vendor/PDCurses/sdl2/pdcgetsc.c +30 -0
  159. data/vendor/PDCurses/sdl2/pdckbd.c +480 -0
  160. data/vendor/PDCurses/sdl2/pdcscrn.c +443 -0
  161. data/vendor/PDCurses/sdl2/pdcsdl.h +33 -0
  162. data/vendor/PDCurses/sdl2/pdcsetsc.c +67 -0
  163. data/vendor/PDCurses/sdl2/pdcutil.c +39 -0
  164. data/vendor/PDCurses/sdl2/sdltest.c +81 -0
  165. data/vendor/PDCurses/term.h +48 -0
  166. data/vendor/PDCurses/version.mif +7 -0
  167. data/vendor/PDCurses/vt/CMakeLists.txt +28 -0
  168. data/vendor/PDCurses/vt/Makefile.bcc +111 -0
  169. data/vendor/PDCurses/vt/Makefile.dmc +258 -0
  170. data/vendor/PDCurses/vt/Makefile.vc +144 -0
  171. data/vendor/PDCurses/vt/Makefile.wcc +107 -0
  172. data/vendor/PDCurses/vt/README.md +64 -0
  173. data/vendor/PDCurses/vt/pdcclip.c +20 -0
  174. data/vendor/PDCurses/vt/pdcdisp.c +284 -0
  175. data/vendor/PDCurses/vt/pdcgetsc.c +27 -0
  176. data/vendor/PDCurses/vt/pdckbd.c +394 -0
  177. data/vendor/PDCurses/vt/pdcscrn.c +434 -0
  178. data/vendor/PDCurses/vt/pdcsetsc.c +45 -0
  179. data/vendor/PDCurses/vt/pdcutil.c +43 -0
  180. data/vendor/PDCurses/vt/pdcvt.h +16 -0
  181. data/vendor/PDCurses/watcom.mif +68 -0
  182. data/vendor/PDCurses/wincon/CMakeLists.txt +27 -0
  183. data/vendor/PDCurses/wincon/Makefile.bcc +88 -0
  184. data/vendor/PDCurses/wincon/Makefile.dmc +256 -0
  185. data/vendor/PDCurses/wincon/Makefile.lcc +273 -0
  186. data/vendor/PDCurses/wincon/Makefile.mng +176 -0
  187. data/vendor/PDCurses/wincon/Makefile.vc +144 -0
  188. data/vendor/PDCurses/wincon/Makefile.wcc +51 -0
  189. data/vendor/PDCurses/wincon/README.md +85 -0
  190. data/vendor/PDCurses/wincon/pdcclip.c +174 -0
  191. data/vendor/PDCurses/wincon/pdcdisp.c +143 -0
  192. data/vendor/PDCurses/wincon/pdcgetsc.c +55 -0
  193. data/vendor/PDCurses/wincon/pdckbd.c +786 -0
  194. data/vendor/PDCurses/wincon/pdcscrn.c +717 -0
  195. data/vendor/PDCurses/wincon/pdcsetsc.c +91 -0
  196. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  197. data/vendor/PDCurses/wincon/pdcurses.rc +28 -0
  198. data/vendor/PDCurses/wincon/pdcutil.c +41 -0
  199. data/vendor/PDCurses/wincon/pdcwin.h +31 -0
  200. data/vendor/PDCurses/wingui/CMakeLists.txt +27 -0
  201. data/vendor/PDCurses/wingui/Makefile.bcc +85 -0
  202. data/vendor/PDCurses/wingui/Makefile.dmc +259 -0
  203. data/vendor/PDCurses/wingui/Makefile.lcc +273 -0
  204. data/vendor/PDCurses/wingui/Makefile.mng +171 -0
  205. data/vendor/PDCurses/wingui/Makefile.vc +144 -0
  206. data/vendor/PDCurses/wingui/Makefile.wcc +51 -0
  207. data/vendor/PDCurses/wingui/README.md +93 -0
  208. data/vendor/PDCurses/wingui/pdcclip.c +174 -0
  209. data/vendor/PDCurses/wingui/pdcdisp.c +718 -0
  210. data/vendor/PDCurses/wingui/pdcgetsc.c +30 -0
  211. data/vendor/PDCurses/wingui/pdckbd.c +143 -0
  212. data/vendor/PDCurses/wingui/pdcscrn.c +2797 -0
  213. data/vendor/PDCurses/wingui/pdcsetsc.c +89 -0
  214. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  215. data/vendor/PDCurses/wingui/pdcurses.rc +28 -0
  216. data/vendor/PDCurses/wingui/pdcutil.c +61 -0
  217. data/vendor/PDCurses/wingui/pdcwin.h +122 -0
  218. data/vendor/PDCurses/x11/Makefile.in +754 -0
  219. data/vendor/PDCurses/x11/PDCurses.spec +82 -0
  220. data/vendor/PDCurses/x11/README.md +62 -0
  221. data/vendor/PDCurses/x11/ScrollBox.c +319 -0
  222. data/vendor/PDCurses/x11/ScrollBox.h +51 -0
  223. data/vendor/PDCurses/x11/ScrollBoxP.h +70 -0
  224. data/vendor/PDCurses/x11/aclocal.m4 +994 -0
  225. data/vendor/PDCurses/x11/big_icon.xbm +46 -0
  226. data/vendor/PDCurses/x11/compose.h +201 -0
  227. data/vendor/PDCurses/x11/config.guess +1500 -0
  228. data/vendor/PDCurses/x11/config.h.in +100 -0
  229. data/vendor/PDCurses/x11/config.sub +1616 -0
  230. data/vendor/PDCurses/x11/configure +6700 -0
  231. data/vendor/PDCurses/x11/configure.ac +295 -0
  232. data/vendor/PDCurses/x11/debian/changelog +6 -0
  233. data/vendor/PDCurses/x11/debian/compat +1 -0
  234. data/vendor/PDCurses/x11/debian/control +11 -0
  235. data/vendor/PDCurses/x11/debian/copyright +27 -0
  236. data/vendor/PDCurses/x11/debian/rules +98 -0
  237. data/vendor/PDCurses/x11/install-sh +253 -0
  238. data/vendor/PDCurses/x11/little_icon.xbm +14 -0
  239. data/vendor/PDCurses/x11/ncurses_cfg.h +45 -0
  240. data/vendor/PDCurses/x11/pdcclip.c +173 -0
  241. data/vendor/PDCurses/x11/pdcdisp.c +85 -0
  242. data/vendor/PDCurses/x11/pdcgetsc.c +28 -0
  243. data/vendor/PDCurses/x11/pdckbd.c +104 -0
  244. data/vendor/PDCurses/x11/pdcscrn.c +258 -0
  245. data/vendor/PDCurses/x11/pdcsetsc.c +95 -0
  246. data/vendor/PDCurses/x11/pdcutil.c +52 -0
  247. data/vendor/PDCurses/x11/pdcx11.c +316 -0
  248. data/vendor/PDCurses/x11/pdcx11.h +191 -0
  249. data/vendor/PDCurses/x11/sb.c +155 -0
  250. data/vendor/PDCurses/x11/x11.c +3686 -0
  251. data/vendor/PDCurses/x11/xcurses-config.in +81 -0
  252. metadata +255 -24
  253. data/.travis.yml +0 -13
  254. data/appveyor.yml +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfa821d182e0a62293a794d22c2b09a0167be3c839a5ac67ea596e98fd5b1f55
4
- data.tar.gz: 1249a4e26714cfdb8ac20394e5c1333b3136b9d5275fac18b3618165cdd1d286
3
+ metadata.gz: 857d0a003f909b9e148855feb1d7b5eca2487aab1d22c544e0fdf560a92293b5
4
+ data.tar.gz: 49329a8c35c0e157c5cba591eb317bf9acf2672af16c8e826aa22ab0ada59cda
5
5
  SHA512:
6
- metadata.gz: e11281a03551d1104a38e2c9b48c0fa1dc8313c8777f2c8e25c97b7833a75c4ea4d44c6d5b0e6b7e2008f7ee012ae9e0e2719df74adbfb85ca731858b3bc2cae
7
- data.tar.gz: 98b90ee805453cb60ec62f698a7477279631e712b6f83ba1ce4edb5488a06d38694e4d0ac5de4eb00e098d47ce9b77c12b4c988afc42d9b1f123705d3cb2ab18
6
+ metadata.gz: 7330fdebb60f3871c10d74685ea5c7ed0194ba7630d0def5cd65de72a3e32e48df343b290ed7e718a116eae1eeab52b5f32d58a4e16e64db6210da9fea19d99e
7
+ data.tar.gz: 77d3c8bcc7183642917311d0cbde1d14f55771b133adb2b7953a052a02672053a5bdc3dd0fc0ab78963383d1e114c9b4534df643be05cb17c2adfdcfca8d7c1a
@@ -0,0 +1,19 @@
1
+ name: macos
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: macos-latest
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - name: Install dependencies
11
+ run: |
12
+ gem install bundler --no-document
13
+ bundle install
14
+ - name: Build package
15
+ run: bundle exec rake build
16
+ - name: Install package
17
+ run: |
18
+ gem install pkg/curses-*.gem
19
+ ruby -r curses -e 'puts Curses::VERSION'
@@ -0,0 +1,26 @@
1
+ name: ubuntu
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ matrix:
9
+ ruby: [ head, 2.7, 2.6, 2.5 ]
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: ${{ matrix.ruby }}
16
+ - name: Install dependencies
17
+ run: |
18
+ sudo apt install libncursesw5-dev
19
+ gem install bundler --no-document
20
+ bundle install
21
+ - name: Build package
22
+ run: bundle exec rake build
23
+ - name: Install package
24
+ run: |
25
+ gem install pkg/curses-*.gem
26
+ ruby -r curses -e 'puts Curses::VERSION'
@@ -0,0 +1,25 @@
1
+ name: windows
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: windows-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: [ 'mingw', 'mswin', '2.7', '2.6', '2.5' ]
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ with:
14
+ submodules: true
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ bundler-cache: true
20
+ - name: Build package
21
+ run: bundle exec rake build
22
+ - name: Install package
23
+ run: |
24
+ gem install pkg/curses-*.gem
25
+ ruby -r curses -e 'puts Curses::VERSION'
data/.gitmodules CHANGED
@@ -1,3 +1,3 @@
1
1
  [submodule "vendor/PDCurses"]
2
2
  path = vendor/PDCurses
3
- url = https://github.com/Bill-Gray/PDCurses.git
3
+ url = https://github.com/shugo/PDCurses.git
data/History.md CHANGED
@@ -1,3 +1,44 @@
1
+ ### 1.4.1 / 2021-05-22
2
+
3
+ Bug fixes:
4
+
5
+ * Use chtype instead of char to support attributes
6
+ * Fixes for Ruby 3.1.
7
+
8
+ ### 1.4.0 / 2020-12-10
9
+
10
+ New features:
11
+
12
+ * Remove fat binary support for newer versions of Ruby
13
+
14
+ ### 1.3.2 / 2019-12-20
15
+
16
+ Bug fixes:
17
+
18
+ * Drop rb_safe_level check for Ruby 2.7 by Eric Wong.
19
+ * Try libtinfow first. Issue #52 by Marco Sirabella.
20
+
21
+ ### 1.3.1 / 2019-04-21
22
+
23
+ Bug fixes:
24
+
25
+ * Check whether sizeof(WINDOW) is available to avoid build failures on macOS.
26
+ Issue #48 reported by chdiza.
27
+
28
+ ### 1.3.0 / 2019-04-16
29
+
30
+ New features:
31
+
32
+ * Add Curses::Form and Curses::Field.
33
+
34
+ Bug fixes:
35
+
36
+ * Fix TravisCI issues by amatsuda and znz.
37
+ * Fix typo in sample/menu.rb by binford2k.
38
+ * Ctrl-/ should return ^_ on Windows.
39
+ * Workaround for new Windows console.
40
+ https://github.com/Bill-Gray/PDCurses/pull/108
41
+
1
42
  ### 1.2.7 / 2019-01-10
2
43
 
3
44
  Bug fixes:
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # curses
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/curses.svg)](https://badge.fury.io/rb/curses)
4
- [![Build Status](https://travis-ci.org/ruby/curses.svg?branch=master)](https://travis-ci.org/ruby/curses)
5
- [![Build status](https://ci.appveyor.com/api/projects/status/kdvksgjo4fyd3c4m/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/curses/branch/master)
4
+ [![ubuntu](https://github.com/ruby/curses/workflows/ubuntu/badge.svg)](https://github.com/ruby/curses/actions?query=workflow%3Aubuntu)
5
+ [![windows](https://github.com/ruby/curses/workflows/windows/badge.svg)](https://github.com/ruby/curses/actions?query=workflow%3Awindows)
6
+ [![macos](https://github.com/ruby/curses/workflows/macos/badge.svg)](https://github.com/ruby/curses/actions?query=workflow%3Amacos)
6
7
 
7
8
  * https://github.com/ruby/curses
8
9
  * https://github.com/ruby/curses/issues
@@ -18,7 +19,7 @@ with the release of Ruby 2.1.0. (see [ruby/ruby@9c5b2fd][2])
18
19
  ## Install
19
20
 
20
21
  $ gem install curses
21
-
22
+
22
23
  Requires ncurses or ncursesw (with wide character support).
23
24
  On Debian based distributions, you can install it with apt:
24
25
 
@@ -28,6 +29,14 @@ Or
28
29
 
29
30
  $ apt install libncursesw5-dev
30
31
 
32
+ On Windows, `gem install curses` will build bundled PDCurses, so you
33
+ don't need to install extra libraries.
34
+ However, if you prefer ncurses to PDCurses, specify the following option:
35
+
36
+ > gem install curses -- --use-system-libraries
37
+
38
+ On mingw, you need DevKit to compile the extension library.
39
+
31
40
  ## Documentation
32
41
 
33
42
  See [https://www.rubydoc.info/gems/curses](https://www.rubydoc.info/gems/curses).
@@ -39,57 +48,16 @@ After checking out the repo, run `bundle install` to install dependencies.
39
48
  To compile the extension library, run `bundle exec rake compile`.
40
49
 
41
50
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `curses.gemspec`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
-
43
- ### Cross compilation for Windows on Debian GNU/Linux based platforms
44
-
45
- 1. Install development environment fo 32- and 64-bit Windows.
46
-
47
- ```
48
- $ sudo apt-get install mingw-w64
49
- ```
50
-
51
- 2. Install rake-compiler.
52
-
53
- ```
54
- $ gem install rake-compiler
55
- ```
56
-
57
- 3. Compile multiple versions of Ruby.
58
-
59
- ```
60
- $ rake-compiler cross-ruby HOST=i686-w64-mingw32 VERSION=2.2.6
61
- $ rake-compiler cross-ruby HOST=i686-w64-mingw32 VERSION=2.3.3
62
- $ rake-compiler cross-ruby HOST=i686-w64-mingw32 VERSION=2.4.0
63
- $ rake-compiler cross-ruby HOST=x86_64-w64-mingw32 VERSION=2.2.6
64
- $ rake-compiler cross-ruby HOST=x86_64-w64-mingw32 VERSION=2.3.3
65
- $ rake-compiler cross-ruby HOST=x86_64-w64-mingw32 VERSION=2.4.0
66
- ```
67
-
68
- 3. Compile PDCurses.
69
-
70
- ```
71
- $ rake build:pdcurses
72
- ```
73
-
74
- 5. Compile curses.gem.
75
-
76
- ```
77
- $ rake RUBY_CC_VERSION=2.3.3:2.4.0 cross clean compile native gem
78
- ```
79
-
80
- Binary gems are generated in pkg/.
81
-
82
51
  ## License
83
52
 
84
53
  curses is released under the Ruby and 2-clause BSD licenses. See COPYING for
85
54
  details.
86
55
 
87
- Binary gems for mingw32 include a forked version of PDCurses, which is in
88
- the public domain:
56
+ It includes a forked version of PDCurses, which is in the public domain:
89
57
 
90
58
  https://github.com/Bill-Gray/PDCurses
91
59
 
92
- The version for Win32 console mode in the win32 subdirectory is used.
60
+ The version for Win32 console mode in the wincon subdirectory is used.
93
61
 
94
62
  [1]: https://bugs.ruby-lang.org/issues/8584
95
63
  [2]: https://github.com/ruby/ruby/commit/9c5b2fd8aa0fd343ad094d47a638cfd3f6ae0a81
data/Rakefile CHANGED
@@ -1,86 +1,3 @@
1
1
  require "bundler"
2
2
 
3
3
  Bundler::GemHelper.install_tasks
4
-
5
- begin
6
- require 'rake/extensiontask'
7
- rescue LoadError => e
8
- warn "\nmissing #{e.path} (for rake-compiler)" if e.respond_to? :path
9
- warn "run: bundle install\n\n"
10
- end
11
-
12
- $mswin = /mswin/ =~ RUBY_PLATFORM
13
-
14
- CLOBBER.include("vendor/#{RUBY_PLATFORM}") if $mswin
15
- CLOBBER.include("vendor/x86-mingw32")
16
- CLOBBER.include("vendor/x64-mingw32")
17
- CLOBBER.include("lib/2.*")
18
- CLOBBER.include("pkg")
19
-
20
- namespace :build do
21
- desc "Build PDCurses"
22
- task :pdcurses do
23
- mkdir_p "vendor/#{RUBY_PLATFORM}/PDCurses" if $mswin
24
- mkdir_p "vendor/x86-mingw32/PDCurses"
25
- mkdir_p "vendor/x64-mingw32/PDCurses"
26
- chdir "vendor/PDCurses/win32" do
27
- if $mswin
28
- sh "nmake -f vcwin32.mak clean all WIDE=Y DLL=Y"
29
- cp %w[pdcurses.dll pdcurses.lib], "../../#{RUBY_PLATFORM}/PDCurses"
30
- else
31
- sh "make -f mingwin32.mak clean all WIDE=Y DLL=N"
32
- cp "pdcurses.a", "../../x86-mingw32/PDCurses/libpdcurses.a"
33
-
34
- sh "make -f mingwin32.mak clean all _w64=1 WIDE=Y DLL=N"
35
- cp "pdcurses.a", "../../x64-mingw32/PDCurses/libpdcurses.a"
36
- end
37
- end
38
- end
39
- end
40
-
41
- namespace :clean do
42
- desc "Clean PDCurses"
43
- task :pdcurses do
44
- chdir "vendor/PDCurses/win32" do
45
- sh "nmake -f vcwin32.mak clean" if $mswin
46
- sh "make -f mingwin32.mak clean _linux_w64=1"
47
- end
48
- end
49
- end
50
-
51
- spec = eval(File.read(File.expand_path("curses.gemspec", __dir__)))
52
- Rake::ExtensionTask.new(spec.name, spec) do |ext|
53
- if $mswin
54
- ext.config_options << '--with-curses-include=' +
55
- File.expand_path("vendor/PDCurses", __dir__) +
56
- ' --with-curses-version=function --enable-pdcurses-wide' +
57
- ' --enable-pdcurses-dll' +
58
- ' --with-curses-lib=' +
59
- File.expand_path("vendor/#{RUBY_PLATFORM}/PDCurses", __dir__)
60
- spec.files += ["vendor/#{RUBY_PLATFORM}/PDCurses/pdcurses.dll"]
61
- end
62
-
63
- ext.cross_compile = true
64
- ext.cross_platform = ["x86-mingw32", "x64-mingw32"]
65
- ext.cross_config_options << '--with-curses-include=' +
66
- File.expand_path("vendor/PDCurses", __dir__) +
67
- ' --with-curses-version=function --enable-pdcurses-wide'
68
- ext.cross_config_options << {
69
- 'x86-mingw32' => '--with-curses-lib=' +
70
- File.expand_path("vendor/x86-mingw32/PDCurses", __dir__),
71
- 'x64-mingw32' => '--with-curses-lib=' +
72
- File.expand_path("vendor/x64-mingw32/PDCurses", __dir__)
73
- }
74
- if $mswin
75
- ext.cross_compiling do |_spec|
76
- bin_file = "vendor/#{_spec.platform}/PDCurses/pdcurses.dll"
77
- _spec.files += [bin_file]
78
- stage_file = "#{ext.tmp_dir}/#{_spec.platform}/stage/#{bin_file}"
79
- stage_dir = File.dirname(stage_file)
80
- directory stage_dir
81
- file stage_file => [stage_dir, bin_file] do
82
- cp bin_file, stage_file
83
- end
84
- end
85
- end
86
- end
data/curses.gemspec CHANGED
@@ -1,17 +1,16 @@
1
1
  Gem::Specification.new { |s|
2
2
  s.name = "curses"
3
- s.version = "1.2.7"
3
+ s.version = "1.4.1"
4
4
  s.author = ["Shugo Maeda", 'Eric Hodel']
5
5
6
6
  s.homepage = "https://github.com/ruby/curses"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.summary = "A Ruby binding for curses, ncurses, and PDCurses. curses is an extension library for text UI applications. Formerly part of the Ruby standard library, [curses was removed and placed in this gem][1] with the release of Ruby 2.1.0. (see [ruby/ruby@9c5b2fd][2])"
9
- s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(vendor)/}) }
9
+ s.files = `git ls-files --recurse-submodules -z`.split("\x0")
10
10
  s.extensions = ["ext/curses/extconf.rb"]
11
11
  s.require_path = "lib"
12
12
  s.required_ruby_version = Gem::Requirement.new('>= 2.1.0')
13
13
  s.licenses = ['Ruby', 'BSD-2-Clause']
14
14
  s.add_development_dependency 'bundler'
15
15
  s.add_development_dependency 'rake'
16
- s.add_development_dependency 'rake-compiler'
17
16
  }
data/ext/curses/curses.c CHANGED
@@ -20,7 +20,9 @@
20
20
  #include "ruby/io.h"
21
21
  #include "ruby/thread.h"
22
22
 
23
- #if defined(HAVE_NCURSESW_CURSES_H)
23
+ #if defined(HAVE_PDCURSES_H)
24
+ # include <pdcurses.h>
25
+ #elif defined(HAVE_NCURSESW_CURSES_H)
24
26
  # include <ncursesw/curses.h>
25
27
  #elif defined(HAVE_NCURSES_CURSES_H)
26
28
  # include <ncurses/curses.h>
@@ -61,6 +63,16 @@
61
63
  # include <menu.h>
62
64
  #endif
63
65
 
66
+ #if defined(HAVE_NCURSESW_FORM_H)
67
+ # include <ncursesw/form.h>
68
+ #elif defined(HAVE_NCURSES_FORM_H)
69
+ # include <ncurses/form.h>
70
+ #elif defined(HAVE_CURSES_FORM_H)
71
+ # include <curses/form.h>
72
+ #elif defined(HAVE_FORM_H)
73
+ # include <form.h>
74
+ #endif
75
+
64
76
  #ifdef HAVE_INIT_COLOR
65
77
  # define USE_COLOR 1
66
78
  #endif
@@ -70,8 +82,19 @@
70
82
  # define USE_MOUSE 1
71
83
  #endif
72
84
 
73
- #define NUM2CH NUM2CHR
74
- #define CH2FIX CHR2FIX
85
+ #define OBJ2CHTYPE rb_obj2chtype_inline
86
+
87
+ static inline chtype
88
+ rb_obj2chtype_inline(VALUE x)
89
+ {
90
+ if (RB_TYPE_P(x, RUBY_T_STRING)) {
91
+ ID id_ord;
92
+
93
+ CONST_ID(id_ord, "ord");
94
+ x = rb_funcall(x, id_ord, 0);
95
+ }
96
+ return NUM2CHTYPE(x);
97
+ }
75
98
 
76
99
  static VALUE mCurses;
77
100
  static VALUE mKey;
@@ -84,6 +107,10 @@ static VALUE cMouseEvent;
84
107
  static VALUE cItem;
85
108
  static VALUE cMenu;
86
109
  #endif
110
+ #ifdef HAVE_FORM
111
+ static VALUE cField;
112
+ static VALUE cForm;
113
+ #endif
87
114
  static VALUE eError;
88
115
  static VALUE eSystemError;
89
116
  static VALUE eBadArgumentError;
@@ -199,6 +226,7 @@ static VALUE window_attroff(VALUE obj, VALUE attrs);
199
226
  static VALUE window_attron(VALUE obj, VALUE attrs);
200
227
  static VALUE window_attrset(VALUE obj, VALUE attrs);
201
228
 
229
+ NORETURN(static void no_window(void));
202
230
  static void
203
231
  no_window(void)
204
232
  {
@@ -206,8 +234,6 @@ no_window(void)
206
234
  }
207
235
 
208
236
  #define GetWINDOW(obj, winp) do {\
209
- if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
210
- rb_raise(rb_eSecurityError, "Insecure: operation on untainted window");\
211
237
  TypedData_Get_Struct((obj), struct windata, &windata_type, (winp));\
212
238
  if ((winp)->window == 0) no_window();\
213
239
  } while (0)
@@ -227,7 +253,7 @@ window_memsize(const void *p)
227
253
  const struct windata *winp = p;
228
254
  size_t size = sizeof(*winp);
229
255
  if (!winp) return 0;
230
- if (winp->window && winp->window != stdscr) size += sizeof(winp->window);
256
+ if (winp->window && winp->window != stdscr) size += CURSES_SIZEOF_WINDOW;
231
257
  return size;
232
258
  }
233
259
 
@@ -276,7 +302,7 @@ static void curses_finalize(VALUE);
276
302
  * see also Curses.stdscr
277
303
  */
278
304
  static VALUE
279
- curses_init_screen(void)
305
+ curses_init_screen(VALUE self)
280
306
  {
281
307
  if (rb_stdscr) return rb_stdscr;
282
308
  initscr();
@@ -299,7 +325,7 @@ curses_init_screen(void)
299
325
  *
300
326
  * Many curses functions use this window.
301
327
  */
302
- #define curses_stdscr curses_init_screen
328
+ #define curses_stdscr() curses_init_screen(Qnil)
303
329
 
304
330
  /*
305
331
  * Document-method: Curses.close_screen
@@ -315,7 +341,7 @@ curses_init_screen(void)
315
341
  *
316
342
  */
317
343
  static VALUE
318
- curses_close_screen(void)
344
+ curses_close_screen(VALUE self)
319
345
  {
320
346
  curses_stdscr();
321
347
  #ifdef HAVE_ISENDWIN
@@ -355,7 +381,7 @@ curses_finalize(VALUE dummy)
355
381
  * returns +false+ otherwise.
356
382
  */
357
383
  static VALUE
358
- curses_closed(void)
384
+ curses_closed(VALUE self)
359
385
  {
360
386
  curses_stdscr();
361
387
  if (isendwin()) {
@@ -405,7 +431,7 @@ curses_erase(VALUE obj)
405
431
  * Clears to the end of line, that the cursor is currently on.
406
432
  */
407
433
  static VALUE
408
- curses_clrtoeol(void)
434
+ curses_clrtoeol(VALUE self)
409
435
  {
410
436
  curses_stdscr();
411
437
  clrtoeol();
@@ -732,7 +758,7 @@ static VALUE
732
758
  curses_inch(VALUE obj)
733
759
  {
734
760
  curses_stdscr();
735
- return CH2FIX(inch());
761
+ return CHTYPE2NUM(inch());
736
762
  }
737
763
 
738
764
  /*
@@ -747,7 +773,7 @@ static VALUE
747
773
  curses_addch(VALUE obj, VALUE ch)
748
774
  {
749
775
  curses_stdscr();
750
- addch(NUM2CH(ch));
776
+ addch(OBJ2CHTYPE(ch));
751
777
  return Qnil;
752
778
  }
753
779
 
@@ -762,7 +788,7 @@ static VALUE
762
788
  curses_insch(VALUE obj, VALUE ch)
763
789
  {
764
790
  curses_stdscr();
765
- insch(NUM2CH(ch));
791
+ insch(OBJ2CHTYPE(ch));
766
792
  return Qnil;
767
793
  }
768
794
 
@@ -843,7 +869,7 @@ getstr_func(void *arg)
843
869
  /*
844
870
  * Document-method: Curses.getstr
845
871
  *
846
- * This is equivalent to a series f Curses::Window.getch calls
872
+ * This is equivalent to a series of Curses::Window.getch calls
847
873
  *
848
874
  */
849
875
  static VALUE
@@ -934,7 +960,7 @@ curses_keyname(VALUE obj, VALUE c)
934
960
  * Returns the number of lines on the screen
935
961
  */
936
962
  static VALUE
937
- curses_lines(void)
963
+ curses_lines(VALUE self)
938
964
  {
939
965
  return INT2FIX(LINES);
940
966
  }
@@ -945,7 +971,7 @@ curses_lines(void)
945
971
  * Returns the number of columns on the screen
946
972
  */
947
973
  static VALUE
948
- curses_cols(void)
974
+ curses_cols(VALUE self)
949
975
  {
950
976
  return INT2FIX(COLS);
951
977
  }
@@ -1091,7 +1117,7 @@ curses_bkgdset(VALUE obj, VALUE ch)
1091
1117
  {
1092
1118
  #ifdef HAVE_BKGDSET
1093
1119
  curses_stdscr();
1094
- bkgdset(NUM2CHTYPE(ch));
1120
+ bkgdset(OBJ2CHTYPE(ch));
1095
1121
  #endif
1096
1122
  return Qnil;
1097
1123
  }
@@ -1112,7 +1138,7 @@ curses_bkgd(VALUE obj, VALUE ch)
1112
1138
  {
1113
1139
  #ifdef HAVE_BKGD
1114
1140
  curses_stdscr();
1115
- return (bkgd(NUM2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
1141
+ return (bkgd(OBJ2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
1116
1142
  #else
1117
1143
  return Qfalse;
1118
1144
  #endif
@@ -1425,6 +1451,7 @@ struct mousedata {
1425
1451
  MEVENT *mevent;
1426
1452
  };
1427
1453
 
1454
+ NORETURN(static void no_mevent(void));
1428
1455
  static void
1429
1456
  no_mevent(void)
1430
1457
  {
@@ -1432,8 +1459,6 @@ no_mevent(void)
1432
1459
  }
1433
1460
 
1434
1461
  #define GetMOUSE(obj, data) do {\
1435
- if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
1436
- rb_raise(rb_eSecurityError, "Insecure: operation on untainted mouse");\
1437
1462
  TypedData_Get_Struct((obj), struct mousedata, &mousedata_type, (data));\
1438
1463
  if ((data)->mevent == 0) no_mevent();\
1439
1464
  } while (0)
@@ -1452,7 +1477,7 @@ curses_mousedata_memsize(const void *p)
1452
1477
  const struct mousedata *mdata = p;
1453
1478
  size_t size = sizeof(*mdata);
1454
1479
  if (!mdata) return 0;
1455
- if (mdata->mevent) size += sizeof(mdata->mevent);
1480
+ if (mdata->mevent) size += CURSES_SIZEOF_MEVENT;
1456
1481
  return size;
1457
1482
  }
1458
1483
 
@@ -1534,7 +1559,7 @@ static VALUE
1534
1559
  curses_mousemask(VALUE obj, VALUE mask)
1535
1560
  {
1536
1561
  curses_stdscr();
1537
- return INT2NUM(mousemask(NUM2UINT(mask),NULL));
1562
+ return ULONG2NUM(mousemask(NUM2UINT(mask),NULL));
1538
1563
  }
1539
1564
 
1540
1565
  #define DEFINE_MOUSE_GET_MEMBER(func_name,mem) \
@@ -1575,7 +1600,12 @@ DEFINE_MOUSE_GET_MEMBER(curs_mouse_z, z)
1575
1600
  * Returns the current mouse's button state. Use this with the button state
1576
1601
  * constants to determine which buttons were pressed.
1577
1602
  */
1578
- DEFINE_MOUSE_GET_MEMBER(curs_mouse_bstate, bstate)
1603
+ static VALUE curs_mouse_bstate(VALUE mouse)
1604
+ {
1605
+ struct mousedata *mdata;
1606
+ GetMOUSE(mouse, mdata);
1607
+ return ULONG2NUM(mdata->mevent->bstate);
1608
+ }
1579
1609
  #undef define_curs_mouse_member
1580
1610
  #endif /* USE_MOUSE */
1581
1611
 
@@ -1667,7 +1697,7 @@ window_initialize(VALUE obj, VALUE h, VALUE w, VALUE top, VALUE left)
1667
1697
  struct windata *winp;
1668
1698
  WINDOW *window;
1669
1699
 
1670
- curses_init_screen();
1700
+ curses_init_screen(Qnil);
1671
1701
  TypedData_Get_Struct(obj, struct windata, &windata_type, winp);
1672
1702
  if (winp->window) delwin(winp->window);
1673
1703
  window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left));
@@ -2164,7 +2194,7 @@ window_begx(VALUE obj)
2164
2194
 
2165
2195
  /*
2166
2196
  * Document-method: Curses::Window.box
2167
- * call-seq: box(vert, hor)
2197
+ * call-seq: box(vert = nil, hor = nil, corn = nil)
2168
2198
  *
2169
2199
  * set the characters to frame the window in.
2170
2200
  * The vertical +vert+ and horizontal +hor+ character.
@@ -2179,16 +2209,18 @@ window_box(int argc, VALUE *argv, VALUE self)
2179
2209
  struct windata *winp;
2180
2210
  VALUE vert, hor, corn;
2181
2211
 
2182
- rb_scan_args(argc, argv, "21", &vert, &hor, &corn);
2212
+ rb_scan_args(argc, argv, "03", &vert, &hor, &corn);
2183
2213
 
2184
2214
  GetWINDOW(self, winp);
2185
- box(winp->window, NUM2CH(vert), NUM2CH(hor));
2215
+ box(winp->window,
2216
+ NIL_P(vert) ? 0 : OBJ2CHTYPE(vert),
2217
+ NIL_P(hor) ? 0 : OBJ2CHTYPE(hor));
2186
2218
 
2187
2219
  if (!NIL_P(corn)) {
2188
2220
  int cur_x, cur_y, x, y;
2189
2221
  chtype c;
2190
2222
 
2191
- c = NUM2CH(corn);
2223
+ c = OBJ2CHTYPE(corn);
2192
2224
  getyx(winp->window, cur_y, cur_x);
2193
2225
  x = NUM2INT(window_maxx(self)) - 1;
2194
2226
  y = NUM2INT(window_maxy(self)) - 1;
@@ -2255,7 +2287,7 @@ window_inch(VALUE obj)
2255
2287
  struct windata *winp;
2256
2288
 
2257
2289
  GetWINDOW(obj, winp);
2258
- return CH2FIX(winch(winp->window));
2290
+ return CHTYPE2NUM(winch(winp->window));
2259
2291
  }
2260
2292
 
2261
2293
  /*
@@ -2272,7 +2304,7 @@ window_addch(VALUE obj, VALUE ch)
2272
2304
  struct windata *winp;
2273
2305
 
2274
2306
  GetWINDOW(obj, winp);
2275
- waddch(winp->window, NUM2CH(ch));
2307
+ waddch(winp->window, OBJ2CHTYPE(ch));
2276
2308
 
2277
2309
  return Qnil;
2278
2310
  }
@@ -2290,7 +2322,7 @@ window_insch(VALUE obj, VALUE ch)
2290
2322
  struct windata *winp;
2291
2323
 
2292
2324
  GetWINDOW(obj, winp);
2293
- winsch(winp->window, NUM2CH(ch));
2325
+ winsch(winp->window, OBJ2CHTYPE(ch));
2294
2326
 
2295
2327
  return Qnil;
2296
2328
  }
@@ -2400,7 +2432,7 @@ wgetstr_func(void *_arg)
2400
2432
  /*
2401
2433
  * Document-method: Curses::Window.getstr
2402
2434
  *
2403
- * This is equivalent to a series f Curses::Window.getch calls
2435
+ * This is equivalent to a series of Curses::Window.getch calls
2404
2436
  *
2405
2437
  */
2406
2438
  static VALUE
@@ -2718,7 +2750,7 @@ window_bkgdset(VALUE obj, VALUE ch)
2718
2750
  struct windata *winp;
2719
2751
 
2720
2752
  GetWINDOW(obj,winp);
2721
- wbkgdset(winp->window, NUM2CHTYPE(ch));
2753
+ wbkgdset(winp->window, OBJ2CHTYPE(ch));
2722
2754
  #endif
2723
2755
  return Qnil;
2724
2756
  }
@@ -2739,7 +2771,7 @@ window_bkgd(VALUE obj, VALUE ch)
2739
2771
  struct windata *winp;
2740
2772
 
2741
2773
  GetWINDOW(obj,winp);
2742
- return (wbkgd(winp->window, NUM2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
2774
+ return (wbkgd(winp->window, OBJ2CHTYPE(ch)) == OK) ? Qtrue : Qfalse;
2743
2775
  #else
2744
2776
  return Qfalse;
2745
2777
  #endif
@@ -2907,7 +2939,7 @@ pad_initialize(VALUE obj, VALUE h, VALUE w)
2907
2939
  struct windata *padp;
2908
2940
  WINDOW *window;
2909
2941
 
2910
- curses_init_screen();
2942
+ curses_init_screen(Qnil);
2911
2943
  TypedData_Get_Struct(obj, struct windata, &windata_type, padp);
2912
2944
  if (padp->window) delwin(padp->window);
2913
2945
  window = newpad(NUM2INT(h), NUM2INT(w));
@@ -3028,8 +3060,6 @@ no_item(void)
3028
3060
  }
3029
3061
 
3030
3062
  #define GetITEM(obj, itemp) do {\
3031
- if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
3032
- rb_raise(rb_eSecurityError, "Insecure: operation on untainted item");\
3033
3063
  TypedData_Get_Struct((obj), struct itemdata, &itemdata_type, (itemp));\
3034
3064
  if ((itemp)->item == 0) no_item();\
3035
3065
  } while (0)
@@ -3049,7 +3079,7 @@ item_memsize(const void *p)
3049
3079
  const struct itemdata *itemp = p;
3050
3080
  size_t size = sizeof(*itemp);
3051
3081
  if (!itemp) return 0;
3052
- if (itemp->item) size += sizeof(itemp->item);
3082
+ if (itemp->item) size += CURSES_SIZEOF_ITEM;
3053
3083
  return size;
3054
3084
  }
3055
3085
 
@@ -3080,7 +3110,7 @@ item_initialize(VALUE obj, VALUE name, VALUE description)
3080
3110
  {
3081
3111
  struct itemdata *itemp;
3082
3112
 
3083
- curses_init_screen();
3113
+ curses_init_screen(Qnil);
3084
3114
  TypedData_Get_Struct(obj, struct itemdata, &itemdata_type, itemp);
3085
3115
  if (itemp->item) {
3086
3116
  rb_raise(rb_eRuntimeError, "already initialized item");
@@ -3139,6 +3169,83 @@ item_description_m(VALUE obj)
3139
3169
  return rb_external_str_new_with_enc(desc, strlen(desc), terminal_encoding);
3140
3170
  }
3141
3171
 
3172
+ /*
3173
+ * Document-method: Curses::Item#set_opts
3174
+ *
3175
+ * call-seq:
3176
+ * set_opts(opts)
3177
+ *
3178
+ * Set the option bits of the item.
3179
+ */
3180
+ static VALUE
3181
+ item_set_opts(VALUE obj, VALUE opts)
3182
+ {
3183
+ struct itemdata *itemp;
3184
+ int error;
3185
+
3186
+ GetITEM(obj, itemp);
3187
+ error = set_item_opts(itemp->item, NUM2INT(opts));
3188
+ check_curses_error(error);
3189
+ return obj;
3190
+ }
3191
+
3192
+ /*
3193
+ * Document-method: Curses::Item#opts_on
3194
+ *
3195
+ * call-seq:
3196
+ * opts_on(opts)
3197
+ *
3198
+ * Turn on the option bits of the item.
3199
+ */
3200
+ static VALUE
3201
+ item_opts_on_m(VALUE obj, VALUE opts)
3202
+ {
3203
+ struct itemdata *itemp;
3204
+ int error;
3205
+
3206
+ GetITEM(obj, itemp);
3207
+ error = item_opts_on(itemp->item, NUM2INT(opts));
3208
+ check_curses_error(error);
3209
+ return obj;
3210
+ }
3211
+
3212
+ /*
3213
+ * Document-method: Curses::Item#opts_off
3214
+ *
3215
+ * call-seq:
3216
+ * opts_off(opts)
3217
+ *
3218
+ * Turn off the option bits of the item.
3219
+ */
3220
+ static VALUE
3221
+ item_opts_off_m(VALUE obj, VALUE opts)
3222
+ {
3223
+ struct itemdata *itemp;
3224
+ int error;
3225
+
3226
+ GetITEM(obj, itemp);
3227
+ error = item_opts_off(itemp->item, NUM2INT(opts));
3228
+ check_curses_error(error);
3229
+ return obj;
3230
+ }
3231
+
3232
+ /*
3233
+ * Document-method: Curses::Item#opts
3234
+ *
3235
+ * call-seq:
3236
+ * opts
3237
+ *
3238
+ * Get the current option bits of the item.
3239
+ */
3240
+ static VALUE
3241
+ item_opts_m(VALUE obj, VALUE opts)
3242
+ {
3243
+ struct itemdata *itemp;
3244
+
3245
+ GetITEM(obj, itemp);
3246
+ return INT2NUM(item_opts(itemp->item));
3247
+ }
3248
+
3142
3249
  struct menudata {
3143
3250
  MENU *menu;
3144
3251
  VALUE items;
@@ -3151,8 +3258,6 @@ no_menu(void)
3151
3258
  }
3152
3259
 
3153
3260
  #define GetMENU(obj, menup) do {\
3154
- if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\
3155
- rb_raise(rb_eSecurityError, "Insecure: operation on untainted menu");\
3156
3261
  TypedData_Get_Struct((obj), struct menudata, &menudata_type, (menup));\
3157
3262
  if ((menup)->menu == 0) no_menu();\
3158
3263
  } while (0)
@@ -3183,7 +3288,7 @@ menu_memsize(const void *p)
3183
3288
  const struct menudata *menup = p;
3184
3289
  size_t size = sizeof(*menup);
3185
3290
  if (!menup) return 0;
3186
- if (menup->menu) size += sizeof(menup->menu);
3291
+ if (menup->menu) size += CURSES_SIZEOF_MENU;
3187
3292
  return size;
3188
3293
  }
3189
3294
 
@@ -3205,7 +3310,7 @@ menu_s_allocate(VALUE class)
3205
3310
  * Document-method: Curses::Menu.new
3206
3311
  *
3207
3312
  * call-seq:
3208
- * new(name, description)
3313
+ * new(items)
3209
3314
  *
3210
3315
  * Construct a new Curses::Menu.
3211
3316
  */
@@ -3215,26 +3320,33 @@ menu_initialize(VALUE obj, VALUE items)
3215
3320
  struct menudata *menup;
3216
3321
  ITEM **menu_items;
3217
3322
  int i;
3323
+ ID id_new;
3218
3324
 
3219
3325
  Check_Type(items, T_ARRAY);
3220
- curses_init_screen();
3326
+ curses_init_screen(Qnil);
3221
3327
  TypedData_Get_Struct(obj, struct menudata, &menudata_type, menup);
3222
3328
  if (menup->menu) {
3223
3329
  rb_raise(rb_eRuntimeError, "already initialized menu");
3224
3330
  }
3331
+ menup->items = rb_ary_new();
3225
3332
  menu_items = ALLOC_N(ITEM *, RARRAY_LEN(items) + 1);
3333
+ CONST_ID(id_new, "new");
3226
3334
  for (i = 0; i < RARRAY_LEN(items); i++) {
3335
+ VALUE item = RARRAY_AREF(items, i);
3227
3336
  struct itemdata *itemp;
3228
3337
 
3229
- GetITEM(RARRAY_AREF(items, i), itemp);
3338
+ if (RB_TYPE_P(item, T_ARRAY)) {
3339
+ item = rb_apply(cItem, id_new, item);
3340
+ }
3341
+ GetITEM(item, itemp);
3230
3342
  menu_items[i] = itemp->item;
3343
+ rb_ary_push(menup->items, item);
3231
3344
  }
3232
3345
  menu_items[RARRAY_LEN(items)] = NULL;
3233
3346
  menup->menu = new_menu(menu_items);
3234
3347
  if (menup->menu == NULL) {
3235
3348
  check_curses_error(errno);
3236
3349
  }
3237
- menup->items = rb_ary_dup(items);
3238
3350
 
3239
3351
  return obj;
3240
3352
  }
@@ -3426,190 +3538,1065 @@ menu_set_current_item(VALUE obj, VALUE item)
3426
3538
  return item;
3427
3539
  }
3428
3540
 
3429
- #endif /* HAVE_MENU */
3430
-
3431
3541
  /*
3432
- * Document-method: Curses.keyboard_encoding
3433
- * call-seq: Curses.keyboard_encoding
3542
+ * Document-method: Curses::Menu#set_win
3434
3543
  *
3435
- * Returns the encoding for keyboard input.
3544
+ * call-seq:
3545
+ * set_win=(win)
3546
+ *
3547
+ * Set the window of the menu.
3436
3548
  */
3437
3549
  static VALUE
3438
- curses_get_keyboard_encoding(VALUE obj)
3550
+ menu_set_win(VALUE obj, VALUE win)
3439
3551
  {
3440
- return rb_enc_from_encoding(keyboard_encoding);
3552
+ struct menudata *menup;
3553
+ struct windata *winp;
3554
+
3555
+ GetMENU(obj, menup);
3556
+ GetWINDOW(win, winp);
3557
+ set_menu_win(menup->menu, winp->window);
3558
+ return win;
3441
3559
  }
3442
3560
 
3443
3561
  /*
3444
- * Document-method: Curses.keyboard_encoding=
3445
- * call-seq: Curses.keyboard_encoding = encoding
3562
+ * Document-method: Curses::Menu#set_sub
3446
3563
  *
3447
- * Sets the encoding for keyboard input.
3564
+ * call-seq:
3565
+ * set_sub=(win)
3566
+ *
3567
+ * Set the subwindow of the menu.
3448
3568
  */
3449
3569
  static VALUE
3450
- curses_set_keyboard_encoding(VALUE obj, VALUE enc)
3570
+ menu_set_sub(VALUE obj, VALUE win)
3451
3571
  {
3452
- keyboard_encoding = rb_to_encoding(enc);
3453
- return enc;
3572
+ struct menudata *menup;
3573
+ struct windata *winp;
3574
+
3575
+ GetMENU(obj, menup);
3576
+ GetWINDOW(win, winp);
3577
+ set_menu_sub(menup->menu, winp->window);
3578
+ return win;
3454
3579
  }
3455
3580
 
3456
3581
  /*
3457
- * Document-method: Curses.terminal_encoding
3458
- * call-seq: Curses.terminal_encoding
3582
+ * Document-method: Curses::Menu#scale
3459
3583
  *
3460
- * Returns the encoding for terminal output.
3584
+ * call-seq:
3585
+ * scale
3586
+ *
3587
+ * Return the minimum rows and columns required for the subwindow of the menu.
3461
3588
  */
3462
3589
  static VALUE
3463
- curses_get_terminal_encoding(VALUE obj)
3590
+ menu_scale(VALUE obj)
3464
3591
  {
3465
- return rb_enc_from_encoding(terminal_encoding);
3592
+ struct menudata *menup;
3593
+ int error, rows, columns;
3594
+
3595
+ GetMENU(obj, menup);
3596
+ error = scale_menu(menup->menu, &rows, &columns);
3597
+ check_curses_error(error);
3598
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(columns));
3466
3599
  }
3467
3600
 
3468
3601
  /*
3469
- * Document-method: Curses.terminal_encoding=
3470
- * call-seq: Curses.terminal_encoding = encoding
3602
+ * Document-method: Curses::Menu#set_format
3471
3603
  *
3472
- * Sets the encoding for terminal output.
3604
+ * call-seq:
3605
+ * set_format(rows, cols)
3606
+ *
3607
+ * Set the maximum size of the menu.
3473
3608
  */
3474
3609
  static VALUE
3475
- curses_set_terminal_encoding(VALUE obj, VALUE enc)
3610
+ menu_set_format(VALUE obj, VALUE rows, VALUE cols)
3476
3611
  {
3477
- terminal_encoding = rb_to_encoding(enc);
3478
- return enc;
3612
+ struct menudata *menup;
3613
+ int error;
3614
+
3615
+ GetMENU(obj, menup);
3616
+ error = set_menu_format(menup->menu, NUM2INT(rows), NUM2INT(cols));
3617
+ check_curses_error(error);
3618
+ return obj;
3479
3619
  }
3480
3620
 
3481
3621
  /*
3482
- * Document-method: Curses.unget_char
3483
- * call-seq: unget_char(ch)
3622
+ * Document-method: Curses::Menu#format
3484
3623
  *
3485
- * Places +ch+ back onto the input queue to be returned by
3486
- * the next call to Curses.get_char etc.
3624
+ * call-seq:
3625
+ * format
3487
3626
  *
3488
- * There is just one input queue for all windows.
3627
+ * Get the maximum size of the menu.
3489
3628
  */
3490
3629
  static VALUE
3491
- curses_unget_char(VALUE obj, VALUE ch)
3630
+ menu_format_m(VALUE obj)
3492
3631
  {
3493
- ID id_ord;
3494
- unsigned int c;
3632
+ struct menudata *menup;
3633
+ int rows, cols;
3495
3634
 
3496
- curses_stdscr();
3497
- if (FIXNUM_P(ch)) {
3498
- ungetch(NUM2UINT(ch));
3499
- }
3500
- else {
3501
- StringValue(ch);
3502
- CONST_ID(id_ord, "ord");
3503
- c = NUM2UINT(rb_funcall(ch, id_ord, 0));
3504
- #ifdef HAVE_UNGET_WCH
3505
- unget_wch(c);
3506
- #else
3507
- if (c > 0xff) {
3508
- rb_raise(rb_eRangeError, "Out of range: %u", c);
3509
- }
3510
- ungetch(c);
3511
- #endif
3512
- }
3513
- return Qnil;
3635
+ GetMENU(obj, menup);
3636
+ menu_format(menup->menu, &rows, &cols);
3637
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(cols));
3514
3638
  }
3515
3639
 
3640
+ /*
3641
+ * Document-method: Curses::Menu#set_opts
3642
+ *
3643
+ * call-seq:
3644
+ * set_opts(opts)
3645
+ *
3646
+ * Set the option bits of the menu.
3647
+ */
3516
3648
  static VALUE
3517
- keyboard_uint_chr(unsigned int ch)
3649
+ menu_set_opts(VALUE obj, VALUE opts)
3518
3650
  {
3519
- return rb_enc_uint_chr(ch, keyboard_encoding);
3520
- }
3521
-
3522
- #ifdef HAVE_GET_WCH
3523
- struct get_wch_arg {
3524
- int retval;
3525
- wint_t ch;
3526
- };
3651
+ struct menudata *menup;
3652
+ int error;
3527
3653
 
3528
- static void *
3529
- get_wch_func(void *_arg)
3530
- {
3531
- struct get_wch_arg *arg = (struct get_wch_arg *) _arg;
3532
- arg->retval = get_wch(&arg->ch);
3533
- return 0;
3654
+ GetMENU(obj, menup);
3655
+ error = set_menu_opts(menup->menu, NUM2INT(opts));
3656
+ check_curses_error(error);
3657
+ return obj;
3534
3658
  }
3535
- #endif
3536
3659
 
3537
3660
  /*
3538
- * Document-method: Curses.get_char
3539
- *
3540
- * Read and returns a character or function key from the window.
3541
- * A single or multibyte character is represented by a String, and
3542
- * a function key is represented by an Integer.
3543
- * Returns nil if no input is ready.
3661
+ * Document-method: Curses::Menu#opts_on
3544
3662
  *
3545
- * See Curses::Key to all the function KEY_* available
3663
+ * call-seq:
3664
+ * opts_on(opts)
3546
3665
  *
3666
+ * Turn on the option bits of the menu.
3547
3667
  */
3548
3668
  static VALUE
3549
- curses_get_char(VALUE obj)
3669
+ menu_opts_on_m(VALUE obj, VALUE opts)
3550
3670
  {
3551
- #ifdef HAVE_GET_WCH
3552
- struct get_wch_arg arg;
3553
-
3554
- curses_stdscr();
3555
- rb_thread_call_without_gvl(get_wch_func, &arg, RUBY_UBF_IO, 0);
3556
- switch (arg.retval) {
3557
- case OK:
3558
- return keyboard_uint_chr(arg.ch);
3559
- case KEY_CODE_YES:
3560
- return UINT2NUM(arg.ch);
3561
- }
3562
- return Qnil;
3563
- #else
3564
- int c;
3671
+ struct menudata *menup;
3672
+ int error;
3565
3673
 
3566
- curses_stdscr();
3567
- rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
3568
- if (c > 0xff) {
3569
- return INT2NUM(c);
3570
- }
3571
- else if (c >= 0) {
3572
- return keyboard_uint_chr(c);
3573
- }
3574
- else {
3575
- return Qnil;
3576
- }
3577
- #endif
3674
+ GetMENU(obj, menup);
3675
+ error = menu_opts_on(menup->menu, NUM2INT(opts));
3676
+ check_curses_error(error);
3677
+ return obj;
3578
3678
  }
3579
3679
 
3580
-
3581
- #ifdef HAVE_WGET_WCH
3582
- struct wget_wch_arg {
3583
- WINDOW *win;
3584
- int retval;
3585
- wint_t ch;
3586
- };
3587
-
3588
- static void *
3589
- wget_wch_func(void *_arg)
3680
+ /*
3681
+ * Document-method: Curses::Menu#opts_off
3682
+ *
3683
+ * call-seq:
3684
+ * opts_off(opts)
3685
+ *
3686
+ * Turn off the option bits of the menu.
3687
+ */
3688
+ static VALUE
3689
+ menu_opts_off_m(VALUE obj, VALUE opts)
3590
3690
  {
3591
- struct wget_wch_arg *arg = (struct wget_wch_arg *) _arg;
3592
- arg->retval = wget_wch(arg->win, &arg->ch);
3593
- return 0;
3691
+ struct menudata *menup;
3692
+ int error;
3693
+
3694
+ GetMENU(obj, menup);
3695
+ error = menu_opts_off(menup->menu, NUM2INT(opts));
3696
+ check_curses_error(error);
3697
+ return obj;
3594
3698
  }
3595
- #endif
3596
3699
 
3597
3700
  /*
3598
- * Document-method: Curses::Window.get_char
3599
- *
3600
- * Read and returns a character or function key from the window.
3601
- * A single or multibyte character is represented by a String, and
3602
- * a function key is represented by an Integer.
3603
- * Returns nil if no input is ready.
3701
+ * Document-method: Curses::Menu#opts
3604
3702
  *
3605
- * See Curses::Key to all the function KEY_* available
3703
+ * call-seq:
3704
+ * opts
3606
3705
  *
3706
+ * Get the current option bits of the menu.
3607
3707
  */
3608
3708
  static VALUE
3609
- window_get_char(VALUE obj)
3709
+ menu_opts_m(VALUE obj, VALUE opts)
3610
3710
  {
3611
- #ifdef HAVE_WGET_WCH
3612
- struct windata *winp;
3711
+ struct menudata *menup;
3712
+
3713
+ GetMENU(obj, menup);
3714
+ return INT2NUM(menu_opts(menup->menu));
3715
+ }
3716
+ #endif /* HAVE_MENU */
3717
+
3718
+ #ifdef HAVE_FORM
3719
+ struct fielddata {
3720
+ FIELD *field;
3721
+ };
3722
+
3723
+ NORETURN(static void no_field(void));
3724
+ static void
3725
+ no_field(void)
3726
+ {
3727
+ rb_raise(rb_eRuntimeError, "already deleted field");
3728
+ }
3729
+
3730
+ #define GetFIELD(obj, fieldp) do {\
3731
+ TypedData_Get_Struct((obj), struct fielddata, &fielddata_type, (fieldp));\
3732
+ if ((fieldp)->field == 0) no_field();\
3733
+ } while (0)
3734
+
3735
+ static void
3736
+ field_free(void *p)
3737
+ {
3738
+ struct fielddata *fieldp = p;
3739
+ if (fieldp->field) free_field(fieldp->field);
3740
+ fieldp->field = 0;
3741
+ xfree(fieldp);
3742
+ }
3743
+
3744
+ static size_t
3745
+ field_memsize(const void *p)
3746
+ {
3747
+ const struct fielddata *fieldp = p;
3748
+ size_t size = sizeof(*fieldp);
3749
+ if (!fieldp) return 0;
3750
+ if (fieldp->field) size += CURSES_SIZEOF_FIELD;
3751
+ return size;
3752
+ }
3753
+
3754
+ static const rb_data_type_t fielddata_type = {
3755
+ "fielddata",
3756
+ {0, field_free, field_memsize,}
3757
+ };
3758
+
3759
+ /* returns a Curses::Menu object */
3760
+ static VALUE
3761
+ field_s_allocate(VALUE class)
3762
+ {
3763
+ struct fielddata *fieldp;
3764
+
3765
+ return TypedData_Make_Struct(class, struct fielddata, &fielddata_type, fieldp);
3766
+ }
3767
+
3768
+ /*
3769
+ * Document-method: Curses::Field.new
3770
+ *
3771
+ * call-seq:
3772
+ * new(height, width, toprow, leftcol, offscreen, nbuffers)
3773
+ *
3774
+ * Construct a new Curses::Field.
3775
+ */
3776
+ static VALUE
3777
+ field_initialize(VALUE obj, VALUE height, VALUE width,
3778
+ VALUE toprow, VALUE leftcol, VALUE offscreen, VALUE nbuffers)
3779
+ {
3780
+ struct fielddata *fieldp;
3781
+
3782
+ curses_init_screen(Qnil);
3783
+ TypedData_Get_Struct(obj, struct fielddata, &fielddata_type, fieldp);
3784
+ if (fieldp->field) {
3785
+ rb_raise(rb_eRuntimeError, "already initialized field");
3786
+ }
3787
+ fieldp->field = new_field(NUM2INT(height), NUM2INT(width),
3788
+ NUM2INT(toprow), NUM2INT(leftcol),
3789
+ NUM2INT(offscreen), NUM2INT(nbuffers));
3790
+ if (fieldp->field == NULL) {
3791
+ check_curses_error(errno);
3792
+ }
3793
+
3794
+ return obj;
3795
+ }
3796
+
3797
+ /*
3798
+ * Document-method: Curses::Field#set_buffer
3799
+ *
3800
+ * call-seq:
3801
+ * set_buffer(buf, value)
3802
+ *
3803
+ * Set the numbered buffer of the field.
3804
+ */
3805
+ static VALUE
3806
+ field_set_buffer(VALUE obj, VALUE buf, VALUE value)
3807
+ {
3808
+ struct fielddata *fieldp;
3809
+
3810
+ GetFIELD(obj, fieldp);
3811
+ value = rb_str_export_to_enc(value, terminal_encoding);
3812
+ set_field_buffer(fieldp->field, NUM2INT(buf), StringValueCStr(value));
3813
+
3814
+ return obj;
3815
+ }
3816
+
3817
+ /*
3818
+ * Document-method: Curses::Field#buffer
3819
+ *
3820
+ * call-seq:
3821
+ * buffer(buf)
3822
+ *
3823
+ * Get the numbered buffer of the field.
3824
+ */
3825
+ static VALUE
3826
+ field_buffer_m(VALUE obj, VALUE buf)
3827
+ {
3828
+ struct fielddata *fieldp;
3829
+ char *s;
3830
+
3831
+ GetFIELD(obj, fieldp);
3832
+ s = field_buffer(fieldp->field, NUM2INT(buf));
3833
+ return rb_external_str_new_with_enc(s, strlen(s), terminal_encoding);
3834
+ }
3835
+
3836
+ /*
3837
+ * Document-method: Curses::Field#set_fore
3838
+ *
3839
+ * call-seq:
3840
+ * set_fore(attr)
3841
+ *
3842
+ * Set the foreground attribute of the field.
3843
+ */
3844
+ static VALUE
3845
+ field_set_fore(VALUE obj, VALUE attr)
3846
+ {
3847
+ struct fielddata *fieldp;
3848
+
3849
+ GetFIELD(obj, fieldp);
3850
+ set_field_fore(fieldp->field, NUM2CHTYPE(attr));
3851
+
3852
+ return attr;
3853
+ }
3854
+
3855
+ /*
3856
+ * Document-method: Curses::Field#fore
3857
+ *
3858
+ * call-seq:
3859
+ * fore
3860
+ *
3861
+ * Get the foreground attribute of the field.
3862
+ */
3863
+ static VALUE
3864
+ field_get_fore(VALUE obj)
3865
+ {
3866
+ struct fielddata *fieldp;
3867
+
3868
+ GetFIELD(obj, fieldp);
3869
+ return CHTYPE2NUM(field_fore(fieldp->field));
3870
+ }
3871
+
3872
+ /*
3873
+ * Document-method: Curses::Field#set_back
3874
+ *
3875
+ * call-seq:
3876
+ * set_back(attr)
3877
+ *
3878
+ * Set the background attribute of the field.
3879
+ */
3880
+ static VALUE
3881
+ field_set_back(VALUE obj, VALUE attr)
3882
+ {
3883
+ struct fielddata *fieldp;
3884
+
3885
+ GetFIELD(obj, fieldp);
3886
+ set_field_back(fieldp->field, NUM2CHTYPE(attr));
3887
+
3888
+ return attr;
3889
+ }
3890
+
3891
+ /*
3892
+ * Document-method: Curses::Field#back
3893
+ *
3894
+ * call-seq:
3895
+ * back
3896
+ *
3897
+ * Get the background attribute of the field.
3898
+ */
3899
+ static VALUE
3900
+ field_get_back(VALUE obj)
3901
+ {
3902
+ struct fielddata *fieldp;
3903
+
3904
+ GetFIELD(obj, fieldp);
3905
+ return CHTYPE2NUM(field_back(fieldp->field));
3906
+ }
3907
+
3908
+ /*
3909
+ * Document-method: Curses::Field#opts_on
3910
+ *
3911
+ * call-seq:
3912
+ * opts_on(opts)
3913
+ *
3914
+ * Turn on the given option bits.
3915
+ */
3916
+ static VALUE
3917
+ field_opts_on_m(VALUE obj, VALUE opts)
3918
+ {
3919
+ struct fielddata *fieldp;
3920
+
3921
+ GetFIELD(obj, fieldp);
3922
+ field_opts_on(fieldp->field, NUM2INT(opts));
3923
+
3924
+ return opts;
3925
+ }
3926
+
3927
+ /*
3928
+ * Document-method: Curses::Field#opts_off
3929
+ *
3930
+ * call-seq:
3931
+ * opts_off(opts)
3932
+ *
3933
+ * Turn off the given option bits.
3934
+ */
3935
+ static VALUE
3936
+ field_opts_off_m(VALUE obj, VALUE opts)
3937
+ {
3938
+ struct fielddata *fieldp;
3939
+
3940
+ GetFIELD(obj, fieldp);
3941
+ field_opts_off(fieldp->field, NUM2INT(opts));
3942
+
3943
+ return opts;
3944
+ }
3945
+
3946
+ /*
3947
+ * Document-method: Curses::Field#opts
3948
+ *
3949
+ * call-seq:
3950
+ * opts
3951
+ *
3952
+ * Get the current option bits.
3953
+ */
3954
+ static VALUE
3955
+ field_opts_m(VALUE obj)
3956
+ {
3957
+ struct fielddata *fieldp;
3958
+
3959
+ GetFIELD(obj, fieldp);
3960
+ return INT2NUM(field_opts(fieldp->field));
3961
+ }
3962
+
3963
+ static VALUE
3964
+ field_height(VALUE obj)
3965
+ {
3966
+ struct fielddata *fieldp;
3967
+ int error, val;
3968
+
3969
+ GetFIELD(obj, fieldp);
3970
+ error = field_info(fieldp->field, &val, NULL, NULL, NULL, NULL, NULL);
3971
+ check_curses_error(error);
3972
+ return INT2NUM(val);
3973
+ }
3974
+
3975
+ static VALUE
3976
+ field_width(VALUE obj)
3977
+ {
3978
+ struct fielddata *fieldp;
3979
+ int error, val;
3980
+
3981
+ GetFIELD(obj, fieldp);
3982
+ error = field_info(fieldp->field, NULL, &val, NULL, NULL, NULL, NULL);
3983
+ check_curses_error(error);
3984
+ return INT2NUM(val);
3985
+ }
3986
+
3987
+ static VALUE
3988
+ field_toprow(VALUE obj)
3989
+ {
3990
+ struct fielddata *fieldp;
3991
+ int error, val;
3992
+
3993
+ GetFIELD(obj, fieldp);
3994
+ error = field_info(fieldp->field, NULL, NULL, &val, NULL, NULL, NULL);
3995
+ check_curses_error(error);
3996
+ return INT2NUM(val);
3997
+ }
3998
+
3999
+ static VALUE
4000
+ field_leftcol(VALUE obj)
4001
+ {
4002
+ struct fielddata *fieldp;
4003
+ int error, val;
4004
+
4005
+ GetFIELD(obj, fieldp);
4006
+ error = field_info(fieldp->field, NULL, NULL, NULL, &val, NULL, NULL);
4007
+ check_curses_error(error);
4008
+ return INT2NUM(val);
4009
+ }
4010
+
4011
+ static VALUE
4012
+ field_offscreen(VALUE obj)
4013
+ {
4014
+ struct fielddata *fieldp;
4015
+ int error, val;
4016
+
4017
+ GetFIELD(obj, fieldp);
4018
+ error = field_info(fieldp->field, NULL, NULL, NULL, NULL, &val, NULL);
4019
+ check_curses_error(error);
4020
+ return INT2NUM(val);
4021
+ }
4022
+
4023
+ static VALUE
4024
+ field_nbuffers(VALUE obj)
4025
+ {
4026
+ struct fielddata *fieldp;
4027
+ int error, val;
4028
+
4029
+ GetFIELD(obj, fieldp);
4030
+ error = field_info(fieldp->field, NULL, NULL, NULL, NULL, NULL, &val);
4031
+ check_curses_error(error);
4032
+ return INT2NUM(val);
4033
+ }
4034
+
4035
+ static VALUE
4036
+ field_dynamic_height(VALUE obj)
4037
+ {
4038
+ struct fielddata *fieldp;
4039
+ int error, val;
4040
+
4041
+ GetFIELD(obj, fieldp);
4042
+ error = dynamic_field_info(fieldp->field, &val, NULL, NULL);
4043
+ check_curses_error(error);
4044
+ return INT2NUM(val);
4045
+ }
4046
+
4047
+ static VALUE
4048
+ field_dynamic_width(VALUE obj)
4049
+ {
4050
+ struct fielddata *fieldp;
4051
+ int error, val;
4052
+
4053
+ GetFIELD(obj, fieldp);
4054
+ error = dynamic_field_info(fieldp->field, NULL, &val, NULL);
4055
+ check_curses_error(error);
4056
+ return INT2NUM(val);
4057
+ }
4058
+
4059
+ static VALUE
4060
+ field_max(VALUE obj)
4061
+ {
4062
+ struct fielddata *fieldp;
4063
+ int error, val;
4064
+
4065
+ GetFIELD(obj, fieldp);
4066
+ error = dynamic_field_info(fieldp->field, NULL, NULL, &val);
4067
+ check_curses_error(error);
4068
+ return INT2NUM(val);
4069
+ }
4070
+
4071
+ static VALUE
4072
+ field_set_max(VALUE obj, VALUE max)
4073
+ {
4074
+ struct fielddata *fieldp;
4075
+ int error;
4076
+
4077
+ GetFIELD(obj, fieldp);
4078
+ error = set_max_field(fieldp->field, NUM2INT(max));
4079
+ check_curses_error(error);
4080
+ return max;
4081
+ }
4082
+
4083
+ #define TYPE_CODE_ALPHA 1
4084
+ #define TYPE_CODE_ALNUM 2
4085
+ #define TYPE_CODE_ENUM 3
4086
+ #define TYPE_CODE_INTEGER 4
4087
+ #define TYPE_CODE_NUMERIC 5
4088
+ #define TYPE_CODE_REGEXP 6
4089
+
4090
+ static VALUE
4091
+ field_set_type(int argc, VALUE *argv, VALUE obj)
4092
+ {
4093
+ struct fielddata *fieldp;
4094
+ VALUE type;
4095
+ int type_code;
4096
+ int error;
4097
+
4098
+ if (argc < 1) {
4099
+ rb_raise(rb_eArgError,
4100
+ "wrong number of arguments (given %d, expected 1)", argc);
4101
+ }
4102
+ type_code = NUM2INT(argv[0]);
4103
+ GetFIELD(obj, fieldp);
4104
+ switch (type_code) {
4105
+ case TYPE_CODE_ALPHA:
4106
+ {
4107
+ VALUE width;
4108
+ rb_scan_args(argc, argv, "11", &type, &width);
4109
+ error = set_field_type(fieldp->field, TYPE_ALPHA,
4110
+ NIL_P(width) ? 0 : NUM2INT(width));
4111
+ }
4112
+ break;
4113
+ case TYPE_CODE_ALNUM:
4114
+ {
4115
+ VALUE width;
4116
+ rb_scan_args(argc, argv, "11", &type, &width);
4117
+ error = set_field_type(fieldp->field, TYPE_ALNUM,
4118
+ NIL_P(width) ? 0 : NUM2INT(width));
4119
+ }
4120
+ break;
4121
+ #if 0
4122
+ case TYPE_CODE_ENUM:
4123
+ {
4124
+ /* TODO: consider how valuelist should be allocated? */
4125
+ }
4126
+ break;
4127
+ #endif
4128
+ case TYPE_CODE_INTEGER:
4129
+ {
4130
+ VALUE padding, vmin, vmax;
4131
+ rb_scan_args(argc, argv, "13", &type, &padding, &vmin, &vmax);
4132
+ error = set_field_type(fieldp->field, TYPE_INTEGER,
4133
+ NIL_P(padding) ? 0 : NUM2INT(padding),
4134
+ NIL_P(vmin) ? INT_MIN : NUM2INT(vmin),
4135
+ NIL_P(vmax) ? INT_MAX : NUM2INT(vmax));
4136
+ }
4137
+ break;
4138
+ case TYPE_CODE_NUMERIC:
4139
+ {
4140
+ VALUE padding, vmin, vmax;
4141
+ rb_scan_args(argc, argv, "13", &type, &padding, &vmin, &vmax);
4142
+ error = set_field_type(fieldp->field, TYPE_INTEGER,
4143
+ NIL_P(padding) ? 0 : NUM2INT(padding),
4144
+ NIL_P(vmin) ? INT_MIN : NUM2INT(vmin),
4145
+ NIL_P(vmax) ? INT_MAX : NUM2INT(vmax));
4146
+ }
4147
+ break;
4148
+ #if 0
4149
+ case TYPE_CODE_REGEXP:
4150
+ {
4151
+ /* TODO: consider how regexp should be allocated? */
4152
+ }
4153
+ break;
4154
+ #endif
4155
+ default:
4156
+ rb_raise(rb_eArgError, "unknwon type: %d", type_code);
4157
+ break;
4158
+ }
4159
+ check_curses_error(error);
4160
+ return obj;
4161
+ }
4162
+
4163
+ struct formdata {
4164
+ FORM *form;
4165
+ VALUE fields;
4166
+ };
4167
+
4168
+ NORETURN(static void no_form(void));
4169
+ static void
4170
+ no_form(void)
4171
+ {
4172
+ rb_raise(rb_eRuntimeError, "already deleted form");
4173
+ }
4174
+
4175
+ #define GetFORM(obj, formp) do {\
4176
+ TypedData_Get_Struct((obj), struct formdata, &formdata_type, (formp));\
4177
+ if ((formp)->form == 0) no_form();\
4178
+ } while (0)
4179
+
4180
+ static void
4181
+ form_gc_mark(void *p)
4182
+ {
4183
+ struct formdata *formp = p;
4184
+
4185
+ rb_gc_mark(formp->fields);
4186
+ }
4187
+
4188
+ static void
4189
+ form_free(void *p)
4190
+ {
4191
+ struct formdata *formp = p;
4192
+ FIELD **fields = form_fields(formp->form);
4193
+ if (formp->form) free_form(formp->form);
4194
+ xfree(fields);
4195
+ formp->form = 0;
4196
+ formp->fields = Qnil;
4197
+ xfree(formp);
4198
+ }
4199
+
4200
+ static size_t
4201
+ form_memsize(const void *p)
4202
+ {
4203
+ const struct formdata *formp = p;
4204
+ size_t size = sizeof(*formp);
4205
+ if (!formp) return 0;
4206
+ if (formp->form) size += CURSES_SIZEOF_FORM;
4207
+ return size;
4208
+ }
4209
+
4210
+ static const rb_data_type_t formdata_type = {
4211
+ "formdata",
4212
+ {form_gc_mark, form_free, form_memsize,}
4213
+ };
4214
+
4215
+ /* returns a Curses::Form object */
4216
+ static VALUE
4217
+ form_s_allocate(VALUE class)
4218
+ {
4219
+ struct formdata *formp;
4220
+
4221
+ return TypedData_Make_Struct(class, struct formdata, &formdata_type, formp);
4222
+ }
4223
+
4224
+ /*
4225
+ * Document-method: Curses::Form.new
4226
+ *
4227
+ * call-seq:
4228
+ * new(fields)
4229
+ *
4230
+ * Construct a new Curses::Form.
4231
+ */
4232
+ static VALUE
4233
+ form_initialize(VALUE obj, VALUE fields)
4234
+ {
4235
+ struct formdata *formp;
4236
+ FIELD **form_fields;
4237
+ int i;
4238
+
4239
+ Check_Type(fields, T_ARRAY);
4240
+ curses_init_screen(Qnil);
4241
+ TypedData_Get_Struct(obj, struct formdata, &formdata_type, formp);
4242
+ if (formp->form) {
4243
+ rb_raise(rb_eRuntimeError, "already initialized form");
4244
+ }
4245
+ formp->fields = rb_ary_new();
4246
+ form_fields = ALLOC_N(FIELD *, RARRAY_LEN(fields) + 1);
4247
+ for (i = 0; i < RARRAY_LEN(fields); i++) {
4248
+ VALUE field = RARRAY_AREF(fields, i);
4249
+ struct fielddata *fieldp;
4250
+
4251
+ GetFIELD(field, fieldp);
4252
+ form_fields[i] = fieldp->field;
4253
+ rb_ary_push(formp->fields, field);
4254
+ }
4255
+ form_fields[RARRAY_LEN(fields)] = NULL;
4256
+ formp->form = new_form(form_fields);
4257
+ if (formp->form == NULL) {
4258
+ check_curses_error(errno);
4259
+ }
4260
+
4261
+ return obj;
4262
+ }
4263
+
4264
+ /*
4265
+ * Document-method: Curses::Form#post
4266
+ *
4267
+ * call-seq:
4268
+ * post
4269
+ *
4270
+ * Post the form.
4271
+ */
4272
+ static VALUE
4273
+ form_post(VALUE obj)
4274
+ {
4275
+ struct formdata *formp;
4276
+ int error;
4277
+
4278
+ GetFORM(obj, formp);
4279
+ error = post_form(formp->form);
4280
+ check_curses_error(error);
4281
+
4282
+ return obj;
4283
+ }
4284
+
4285
+ /*
4286
+ * Document-method: Curses::Form#unpost
4287
+ *
4288
+ * call-seq:
4289
+ * unpost
4290
+ *
4291
+ * Unpost the form.
4292
+ */
4293
+ static VALUE
4294
+ form_unpost(VALUE obj)
4295
+ {
4296
+ struct formdata *formp;
4297
+ int error;
4298
+
4299
+ GetFORM(obj, formp);
4300
+ error = unpost_form(formp->form);
4301
+ check_curses_error(error);
4302
+
4303
+ return obj;
4304
+ }
4305
+
4306
+ /*
4307
+ * Document-method: Curses::Form#driver
4308
+ *
4309
+ * call-seq:
4310
+ * driver(command)
4311
+ *
4312
+ * Perform the command on the form.
4313
+ */
4314
+ static VALUE
4315
+ form_driver_m(VALUE obj, VALUE command)
4316
+ {
4317
+ struct formdata *formp;
4318
+ int error, c;
4319
+
4320
+ GetFORM(obj, formp);
4321
+ if (FIXNUM_P(command)) {
4322
+ c = NUM2INT(command);
4323
+ }
4324
+ else {
4325
+ ID id_ord;
4326
+
4327
+ StringValue(command);
4328
+ CONST_ID(id_ord, "ord");
4329
+ c = NUM2INT(rb_funcall(command, id_ord, 0));
4330
+ }
4331
+ #ifdef HAVE_FORM_DRIVER_W
4332
+ error = form_driver_w(formp->form,
4333
+ FIXNUM_P(command) ? KEY_CODE_YES : OK,
4334
+ c);
4335
+ #else
4336
+ error = form_driver(formp->form, c);
4337
+ #endif
4338
+ check_curses_error(error);
4339
+
4340
+ return obj;
4341
+ }
4342
+
4343
+ /*
4344
+ * Document-method: Curses::Form#set_win
4345
+ *
4346
+ * call-seq:
4347
+ * set_win=(win)
4348
+ *
4349
+ * Set the window of the form.
4350
+ */
4351
+ static VALUE
4352
+ form_set_win(VALUE obj, VALUE win)
4353
+ {
4354
+ struct formdata *formp;
4355
+ struct windata *winp;
4356
+
4357
+ GetFORM(obj, formp);
4358
+ GetWINDOW(win, winp);
4359
+ set_form_win(formp->form, winp->window);
4360
+ return win;
4361
+ }
4362
+
4363
+ /*
4364
+ * Document-method: Curses::Form#set_sub
4365
+ *
4366
+ * call-seq:
4367
+ * set_sub=(win)
4368
+ *
4369
+ * Set the subwindow of the form.
4370
+ */
4371
+ static VALUE
4372
+ form_set_sub(VALUE obj, VALUE win)
4373
+ {
4374
+ struct formdata *formp;
4375
+ struct windata *winp;
4376
+
4377
+ GetFORM(obj, formp);
4378
+ GetWINDOW(win, winp);
4379
+ set_form_sub(formp->form, winp->window);
4380
+ return win;
4381
+ }
4382
+
4383
+ /*
4384
+ * Document-method: Curses::Form#scale
4385
+ *
4386
+ * call-seq:
4387
+ * scale
4388
+ *
4389
+ * Return the minimum rows and columns required for the subwindow of the form.
4390
+ */
4391
+ static VALUE
4392
+ form_scale(VALUE obj)
4393
+ {
4394
+ struct formdata *formp;
4395
+ int error, rows, columns;
4396
+
4397
+ GetFORM(obj, formp);
4398
+ error = scale_form(formp->form, &rows, &columns);
4399
+ check_curses_error(error);
4400
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(columns));
4401
+ }
4402
+
4403
+ #endif /* HAVE_FORM */
4404
+
4405
+ /*
4406
+ * Document-method: Curses.keyboard_encoding
4407
+ * call-seq: Curses.keyboard_encoding
4408
+ *
4409
+ * Returns the encoding for keyboard input.
4410
+ */
4411
+ static VALUE
4412
+ curses_get_keyboard_encoding(VALUE obj)
4413
+ {
4414
+ return rb_enc_from_encoding(keyboard_encoding);
4415
+ }
4416
+
4417
+ /*
4418
+ * Document-method: Curses.keyboard_encoding=
4419
+ * call-seq: Curses.keyboard_encoding = encoding
4420
+ *
4421
+ * Sets the encoding for keyboard input.
4422
+ */
4423
+ static VALUE
4424
+ curses_set_keyboard_encoding(VALUE obj, VALUE enc)
4425
+ {
4426
+ keyboard_encoding = rb_to_encoding(enc);
4427
+ return enc;
4428
+ }
4429
+
4430
+ /*
4431
+ * Document-method: Curses.terminal_encoding
4432
+ * call-seq: Curses.terminal_encoding
4433
+ *
4434
+ * Returns the encoding for terminal output.
4435
+ */
4436
+ static VALUE
4437
+ curses_get_terminal_encoding(VALUE obj)
4438
+ {
4439
+ return rb_enc_from_encoding(terminal_encoding);
4440
+ }
4441
+
4442
+ /*
4443
+ * Document-method: Curses.terminal_encoding=
4444
+ * call-seq: Curses.terminal_encoding = encoding
4445
+ *
4446
+ * Sets the encoding for terminal output.
4447
+ */
4448
+ static VALUE
4449
+ curses_set_terminal_encoding(VALUE obj, VALUE enc)
4450
+ {
4451
+ terminal_encoding = rb_to_encoding(enc);
4452
+ return enc;
4453
+ }
4454
+
4455
+ /*
4456
+ * Document-method: Curses.unget_char
4457
+ * call-seq: unget_char(ch)
4458
+ *
4459
+ * Places +ch+ back onto the input queue to be returned by
4460
+ * the next call to Curses.get_char etc.
4461
+ *
4462
+ * There is just one input queue for all windows.
4463
+ */
4464
+ static VALUE
4465
+ curses_unget_char(VALUE obj, VALUE ch)
4466
+ {
4467
+ ID id_ord;
4468
+ unsigned int c;
4469
+
4470
+ curses_stdscr();
4471
+ if (FIXNUM_P(ch)) {
4472
+ ungetch(NUM2UINT(ch));
4473
+ }
4474
+ else {
4475
+ StringValue(ch);
4476
+ CONST_ID(id_ord, "ord");
4477
+ c = NUM2UINT(rb_funcall(ch, id_ord, 0));
4478
+ #ifdef HAVE_UNGET_WCH
4479
+ unget_wch(c);
4480
+ #else
4481
+ if (c > 0xff) {
4482
+ rb_raise(rb_eRangeError, "Out of range: %u", c);
4483
+ }
4484
+ ungetch(c);
4485
+ #endif
4486
+ }
4487
+ return Qnil;
4488
+ }
4489
+
4490
+ static VALUE
4491
+ keyboard_uint_chr(unsigned int ch)
4492
+ {
4493
+ return rb_enc_uint_chr(ch, keyboard_encoding);
4494
+ }
4495
+
4496
+ #if defined(HAVE_GET_WCH) || defined(HAVE_WGET_WCH)
4497
+ static VALUE
4498
+ key_code_value(unsigned int ch)
4499
+ {
4500
+ #ifdef CTL_FSLASH
4501
+ if (ch == CTL_FSLASH) {
4502
+ return keyboard_uint_chr(0x1F);
4503
+ }
4504
+ #endif
4505
+ return UINT2NUM(ch);
4506
+ }
4507
+ #endif
4508
+
4509
+ #ifdef HAVE_GET_WCH
4510
+ struct get_wch_arg {
4511
+ int retval;
4512
+ wint_t ch;
4513
+ };
4514
+
4515
+ static void *
4516
+ get_wch_func(void *_arg)
4517
+ {
4518
+ struct get_wch_arg *arg = (struct get_wch_arg *) _arg;
4519
+ arg->retval = get_wch(&arg->ch);
4520
+ return 0;
4521
+ }
4522
+ #endif
4523
+
4524
+ /*
4525
+ * Document-method: Curses.get_char
4526
+ *
4527
+ * Read and returns a character or function key from the window.
4528
+ * A single or multibyte character is represented by a String, and
4529
+ * a function key is represented by an Integer.
4530
+ * Returns nil if no input is ready.
4531
+ *
4532
+ * See Curses::Key to all the function KEY_* available
4533
+ *
4534
+ */
4535
+ static VALUE
4536
+ curses_get_char(VALUE obj)
4537
+ {
4538
+ #ifdef HAVE_GET_WCH
4539
+ struct get_wch_arg arg;
4540
+
4541
+ curses_stdscr();
4542
+ rb_thread_call_without_gvl(get_wch_func, &arg, RUBY_UBF_IO, 0);
4543
+ switch (arg.retval) {
4544
+ case OK:
4545
+ return keyboard_uint_chr(arg.ch);
4546
+ case KEY_CODE_YES:
4547
+ return key_code_value(arg.ch);
4548
+ }
4549
+ return Qnil;
4550
+ #else
4551
+ int c;
4552
+
4553
+ curses_stdscr();
4554
+ rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
4555
+ if (c > 0xff) {
4556
+ return INT2NUM(c);
4557
+ }
4558
+ else if (c >= 0) {
4559
+ return keyboard_uint_chr(c);
4560
+ }
4561
+ else {
4562
+ return Qnil;
4563
+ }
4564
+ #endif
4565
+ }
4566
+
4567
+
4568
+ #ifdef HAVE_WGET_WCH
4569
+ struct wget_wch_arg {
4570
+ WINDOW *win;
4571
+ int retval;
4572
+ wint_t ch;
4573
+ };
4574
+
4575
+ static void *
4576
+ wget_wch_func(void *_arg)
4577
+ {
4578
+ struct wget_wch_arg *arg = (struct wget_wch_arg *) _arg;
4579
+ arg->retval = wget_wch(arg->win, &arg->ch);
4580
+ return 0;
4581
+ }
4582
+ #endif
4583
+
4584
+ /*
4585
+ * Document-method: Curses::Window.get_char
4586
+ *
4587
+ * Read and returns a character or function key from the window.
4588
+ * A single or multibyte character is represented by a String, and
4589
+ * a function key is represented by an Integer.
4590
+ * Returns nil if no input is ready.
4591
+ *
4592
+ * See Curses::Key to all the function KEY_* available
4593
+ *
4594
+ */
4595
+ static VALUE
4596
+ window_get_char(VALUE obj)
4597
+ {
4598
+ #ifdef HAVE_WGET_WCH
4599
+ struct windata *winp;
3613
4600
  struct wget_wch_arg arg;
3614
4601
 
3615
4602
  GetWINDOW(obj, winp);
@@ -3619,7 +4606,7 @@ window_get_char(VALUE obj)
3619
4606
  case OK:
3620
4607
  return keyboard_uint_chr(arg.ch);
3621
4608
  case KEY_CODE_YES:
3622
- return UINT2NUM(arg.ch);
4609
+ return key_code_value(arg.ch);
3623
4610
  }
3624
4611
  return Qnil;
3625
4612
  #else
@@ -3750,7 +4737,7 @@ Init_curses(void)
3750
4737
  rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
3751
4738
  rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
3752
4739
  rb_define_module_function(mCurses, "closed?", curses_closed, 0);
3753
- rb_define_module_function(mCurses, "stdscr", curses_stdscr, 0);
4740
+ rb_define_module_function(mCurses, "stdscr", curses_init_screen, 0);
3754
4741
  rb_define_module_function(mCurses, "refresh", curses_refresh, 0);
3755
4742
  rb_define_module_function(mCurses, "doupdate", curses_doupdate, 0);
3756
4743
  rb_define_module_function(mCurses, "clear", curses_clear, 0);
@@ -3890,7 +4877,7 @@ Init_curses(void)
3890
4877
  * win.close
3891
4878
  *
3892
4879
  */
3893
- cWindow = rb_define_class_under(mCurses, "Window", rb_cData);
4880
+ cWindow = rb_define_class_under(mCurses, "Window", rb_cObject);
3894
4881
  rb_define_alloc_func(cWindow, window_s_allocate);
3895
4882
  rb_define_method(cWindow, "initialize", window_initialize, 4);
3896
4883
  rb_define_method(cWindow, "subwin", window_subwin, 4);
@@ -3974,14 +4961,18 @@ Init_curses(void)
3974
4961
  #endif
3975
4962
 
3976
4963
  #ifdef HAVE_MENU
3977
- cItem = rb_define_class_under(mCurses, "Item", rb_cData);
4964
+ cItem = rb_define_class_under(mCurses, "Item", rb_cObject);
3978
4965
  rb_define_alloc_func(cItem, item_s_allocate);
3979
4966
  rb_define_method(cItem, "initialize", item_initialize, 2);
3980
4967
  rb_define_method(cItem, "==", item_eq, 1);
3981
4968
  rb_define_method(cItem, "name", item_name_m, 0);
3982
4969
  rb_define_method(cItem, "description", item_description_m, 0);
4970
+ rb_define_method(cItem, "set_opts", item_set_opts, 1);
4971
+ rb_define_method(cItem, "opts_on", item_opts_on_m, 1);
4972
+ rb_define_method(cItem, "opts_off", item_opts_off_m, 1);
4973
+ rb_define_method(cItem, "opts", item_opts_m, 0);
3983
4974
 
3984
- cMenu = rb_define_class_under(mCurses, "Menu", rb_cData);
4975
+ cMenu = rb_define_class_under(mCurses, "Menu", rb_cObject);
3985
4976
  rb_define_alloc_func(cMenu, menu_s_allocate);
3986
4977
  rb_define_method(cMenu, "initialize", menu_initialize, 1);
3987
4978
  rb_define_method(cMenu, "post", menu_post, 0);
@@ -3992,6 +4983,54 @@ Init_curses(void)
3992
4983
  rb_define_method(cMenu, "items=", menu_set_items, 1);
3993
4984
  rb_define_method(cMenu, "current_item", menu_get_current_item, 0);
3994
4985
  rb_define_method(cMenu, "current_item=", menu_set_current_item, 1);
4986
+ rb_define_method(cMenu, "set_win", menu_set_win, 1);
4987
+ rb_define_method(cMenu, "set_sub", menu_set_sub, 1);
4988
+ rb_define_method(cMenu, "scale", menu_scale, 0);
4989
+ rb_define_method(cMenu, "set_format", menu_set_format, 2);
4990
+ rb_define_method(cMenu, "format", menu_format_m, 0);
4991
+ rb_define_method(cMenu, "set_opts", menu_set_opts, 1);
4992
+ rb_define_method(cMenu, "opts_on", menu_opts_on_m, 1);
4993
+ rb_define_method(cMenu, "opts_off", menu_opts_off_m, 1);
4994
+ rb_define_method(cMenu, "opts", menu_opts_m, 0);
4995
+ #endif
4996
+
4997
+ #ifdef HAVE_FORM
4998
+ cField = rb_define_class_under(mCurses, "Field", rb_cObject);
4999
+ rb_define_alloc_func(cField, field_s_allocate);
5000
+ rb_define_method(cField, "initialize", field_initialize, 6);
5001
+ rb_define_method(cField, "set_buffer", field_set_buffer, 2);
5002
+ rb_define_method(cField, "buffer", field_buffer_m, 1);
5003
+ rb_define_method(cField, "set_fore", field_set_fore, 1);
5004
+ rb_define_method(cField, "fore=", field_set_fore, 1);
5005
+ rb_define_method(cField, "fore", field_get_fore, 0);
5006
+ rb_define_method(cField, "set_back", field_set_back, 1);
5007
+ rb_define_method(cField, "back=", field_set_back, 1);
5008
+ rb_define_method(cField, "back", field_get_back, 0);
5009
+ rb_define_method(cField, "opts_on", field_opts_on_m, 1);
5010
+ rb_define_method(cField, "opts_off", field_opts_off_m, 1);
5011
+ rb_define_method(cField, "opts", field_opts_m, 0);
5012
+ rb_define_method(cField, "height", field_height, 0);
5013
+ rb_define_method(cField, "width", field_width, 0);
5014
+ rb_define_method(cField, "toprow", field_toprow, 0);
5015
+ rb_define_method(cField, "leftcol", field_leftcol, 0);
5016
+ rb_define_method(cField, "offscreen", field_offscreen, 0);
5017
+ rb_define_method(cField, "nbuffers", field_nbuffers, 0);
5018
+ rb_define_method(cField, "dynamic_height", field_dynamic_height, 0);
5019
+ rb_define_method(cField, "dynamic_width", field_dynamic_width, 0);
5020
+ rb_define_method(cField, "max", field_max, 0);
5021
+ rb_define_method(cField, "set_max", field_set_max, 1);
5022
+ rb_define_method(cField, "max=", field_set_max, 1);
5023
+ rb_define_method(cField, "set_type", field_set_type, -1);
5024
+
5025
+ cForm = rb_define_class_under(mCurses, "Form", rb_cObject);
5026
+ rb_define_alloc_func(cForm, form_s_allocate);
5027
+ rb_define_method(cForm, "initialize", form_initialize, 1);
5028
+ rb_define_method(cForm, "post", form_post, 0);
5029
+ rb_define_method(cForm, "unpost", form_unpost, 0);
5030
+ rb_define_method(cForm, "driver", form_driver_m, 1);
5031
+ rb_define_method(cForm, "set_win", form_set_win, 1);
5032
+ rb_define_method(cForm, "set_sub", form_set_sub, 1);
5033
+ rb_define_method(cForm, "scale", form_scale, 0);
3995
5034
  #endif
3996
5035
 
3997
5036
  #define rb_curses_define_error(c) do { \
@@ -5482,6 +6521,17 @@ Init_curses(void)
5482
6521
  #endif
5483
6522
 
5484
6523
  #ifdef HAVE_MENU
6524
+ rb_curses_define_const(O_ONEVALUE);
6525
+ rb_curses_define_const(O_SHOWDESC);
6526
+ rb_curses_define_const(O_ROWMAJOR);
6527
+ rb_curses_define_const(O_IGNORECASE);
6528
+ rb_curses_define_const(O_SHOWMATCH);
6529
+ rb_curses_define_const(O_NONCYCLIC);
6530
+ #ifdef O_MOUSE_MENU
6531
+ rb_curses_define_const(O_MOUSE_MENU);
6532
+ #endif
6533
+ rb_curses_define_const(O_SELECTABLE);
6534
+
5485
6535
  rb_curses_define_const(REQ_LEFT_ITEM);
5486
6536
  rb_curses_define_const(REQ_RIGHT_ITEM);
5487
6537
  rb_curses_define_const(REQ_UP_ITEM);
@@ -5500,5 +6550,93 @@ Init_curses(void)
5500
6550
  rb_curses_define_const(REQ_NEXT_MATCH);
5501
6551
  rb_curses_define_const(REQ_PREV_MATCH);
5502
6552
  #endif
6553
+
6554
+ #ifdef HAVE_FORM
6555
+ rb_curses_define_const(O_VISIBLE);
6556
+ rb_curses_define_const(O_ACTIVE);
6557
+ rb_curses_define_const(O_PUBLIC);
6558
+ rb_curses_define_const(O_EDIT);
6559
+ rb_curses_define_const(O_WRAP);
6560
+ rb_curses_define_const(O_BLANK);
6561
+ rb_curses_define_const(O_AUTOSKIP);
6562
+ rb_curses_define_const(O_NULLOK);
6563
+ rb_curses_define_const(O_PASSOK);
6564
+ rb_curses_define_const(O_STATIC);
6565
+ #ifdef O_DYNAMIC_JUSTIFY
6566
+ rb_curses_define_const(O_DYNAMIC_JUSTIFY);
6567
+ #endif
6568
+ #ifdef O_NO_LEFT_STRIP
6569
+ rb_curses_define_const(O_NO_LEFT_STRIP);
6570
+ #endif
6571
+
6572
+ rb_define_const(mCurses, "TYPE_ALPHA", INT2NUM(TYPE_CODE_ALPHA));
6573
+ rb_define_const(mCurses, "TYPE_ALNUM", INT2NUM(TYPE_CODE_ALNUM));
6574
+ rb_define_const(mCurses, "TYPE_ENUM", INT2NUM(TYPE_CODE_ENUM));
6575
+ rb_define_const(mCurses, "TYPE_INTEGER", INT2NUM(TYPE_CODE_INTEGER));
6576
+ rb_define_const(mCurses, "TYPE_NUMERIC", INT2NUM(TYPE_CODE_NUMERIC));
6577
+ rb_define_const(mCurses, "TYPE_REGEXP", INT2NUM(TYPE_CODE_REGEXP));
6578
+
6579
+ rb_curses_define_const(REQ_NEXT_PAGE);
6580
+ rb_curses_define_const(REQ_PREV_PAGE);
6581
+ rb_curses_define_const(REQ_FIRST_PAGE);
6582
+ rb_curses_define_const(REQ_LAST_PAGE);
6583
+
6584
+ rb_curses_define_const(REQ_NEXT_FIELD);
6585
+ rb_curses_define_const(REQ_PREV_FIELD);
6586
+ rb_curses_define_const(REQ_FIRST_FIELD);
6587
+ rb_curses_define_const(REQ_LAST_FIELD);
6588
+ rb_curses_define_const(REQ_SNEXT_FIELD);
6589
+ rb_curses_define_const(REQ_SPREV_FIELD);
6590
+ rb_curses_define_const(REQ_SFIRST_FIELD);
6591
+ rb_curses_define_const(REQ_SLAST_FIELD);
6592
+ rb_curses_define_const(REQ_LEFT_FIELD);
6593
+ rb_curses_define_const(REQ_RIGHT_FIELD);
6594
+ rb_curses_define_const(REQ_UP_FIELD);
6595
+ rb_curses_define_const(REQ_DOWN_FIELD);
6596
+
6597
+ rb_curses_define_const(REQ_NEXT_CHAR);
6598
+ rb_curses_define_const(REQ_PREV_CHAR);
6599
+ rb_curses_define_const(REQ_NEXT_LINE);
6600
+ rb_curses_define_const(REQ_PREV_LINE);
6601
+ rb_curses_define_const(REQ_NEXT_WORD);
6602
+ rb_curses_define_const(REQ_PREV_WORD);
6603
+ rb_curses_define_const(REQ_BEG_FIELD);
6604
+ rb_curses_define_const(REQ_END_FIELD);
6605
+ rb_curses_define_const(REQ_BEG_LINE);
6606
+ rb_curses_define_const(REQ_END_LINE);
6607
+ rb_curses_define_const(REQ_LEFT_CHAR);
6608
+ rb_curses_define_const(REQ_RIGHT_CHAR);
6609
+ rb_curses_define_const(REQ_UP_CHAR);
6610
+ rb_curses_define_const(REQ_DOWN_CHAR);
6611
+
6612
+ rb_curses_define_const(REQ_NEW_LINE);
6613
+ rb_curses_define_const(REQ_INS_CHAR);
6614
+ rb_curses_define_const(REQ_INS_LINE);
6615
+ rb_curses_define_const(REQ_DEL_CHAR);
6616
+ rb_curses_define_const(REQ_DEL_PREV);
6617
+ rb_curses_define_const(REQ_DEL_LINE);
6618
+ rb_curses_define_const(REQ_DEL_WORD);
6619
+ rb_curses_define_const(REQ_CLR_EOL);
6620
+ rb_curses_define_const(REQ_CLR_EOF);
6621
+ rb_curses_define_const(REQ_CLR_FIELD);
6622
+ rb_curses_define_const(REQ_OVL_MODE);
6623
+ rb_curses_define_const(REQ_INS_MODE);
6624
+ rb_curses_define_const(REQ_SCR_FLINE);
6625
+ rb_curses_define_const(REQ_SCR_BLINE);
6626
+ rb_curses_define_const(REQ_SCR_FPAGE);
6627
+ rb_curses_define_const(REQ_SCR_BPAGE);
6628
+ rb_curses_define_const(REQ_SCR_FHPAGE);
6629
+ rb_curses_define_const(REQ_SCR_BHPAGE);
6630
+ rb_curses_define_const(REQ_SCR_FCHAR);
6631
+ rb_curses_define_const(REQ_SCR_BCHAR);
6632
+ rb_curses_define_const(REQ_SCR_HFLINE);
6633
+ rb_curses_define_const(REQ_SCR_HBLINE);
6634
+ rb_curses_define_const(REQ_SCR_HFHALF);
6635
+ rb_curses_define_const(REQ_SCR_HBHALF);
6636
+
6637
+ rb_curses_define_const(REQ_VALIDATION);
6638
+ rb_curses_define_const(REQ_NEXT_CHOICE);
6639
+ rb_curses_define_const(REQ_PREV_CHOICE);
6640
+ #endif
5503
6641
  #undef rb_curses_define_const
5504
6642
  }
OSZAR »