curses 1.2.6 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) 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 +28 -0
  5. data/.gitmodules +1 -1
  6. data/.travis.yml +6 -3
  7. data/History.md +40 -0
  8. data/README.md +4 -1
  9. data/Rakefile +0 -83
  10. data/curses.gemspec +2 -3
  11. data/ext/curses/curses.c +1271 -151
  12. data/ext/curses/extconf.rb +140 -17
  13. data/lib/curses.rb +5 -12
  14. data/sample/form.rb +52 -0
  15. data/sample/menu.rb +1 -1
  16. data/vendor/PDCurses/.gitignore +47 -0
  17. data/vendor/PDCurses/.travis.yml +49 -0
  18. data/vendor/PDCurses/CMakeLists.txt +68 -0
  19. data/vendor/PDCurses/HISTORY.md +2036 -0
  20. data/vendor/PDCurses/IMPLEMNT.md +327 -0
  21. data/vendor/PDCurses/README.md +77 -0
  22. data/vendor/PDCurses/acs_defs.h +265 -0
  23. data/vendor/PDCurses/appveyor.yml +218 -0
  24. data/vendor/PDCurses/cmake/README.md +71 -0
  25. data/vendor/PDCurses/cmake/build_dependencies.cmake +178 -0
  26. data/vendor/PDCurses/cmake/build_options.cmake +25 -0
  27. data/vendor/PDCurses/cmake/dll_version.cmake +26 -0
  28. data/vendor/PDCurses/cmake/gen_config_header.cmake +43 -0
  29. data/vendor/PDCurses/cmake/get_version.cmake +17 -0
  30. data/vendor/PDCurses/cmake/make_uninstall.cmake +19 -0
  31. data/vendor/PDCurses/cmake/project_common.cmake +121 -0
  32. data/vendor/PDCurses/cmake/resource.in.cmake +52 -0
  33. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +83 -0
  34. data/vendor/PDCurses/cmake/target_arch.cmake +36 -0
  35. data/vendor/PDCurses/cmake/version.in.cmake +73 -0
  36. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +96 -0
  37. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +106 -0
  38. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +105 -0
  39. data/vendor/PDCurses/curses.h +1846 -0
  40. data/vendor/PDCurses/curspriv.h +134 -0
  41. data/vendor/PDCurses/demos/README.md +25 -0
  42. data/vendor/PDCurses/demos/firework.c +144 -0
  43. data/vendor/PDCurses/demos/newtest.c +581 -0
  44. data/vendor/PDCurses/demos/ozdemo.c +447 -0
  45. data/vendor/PDCurses/demos/ptest.c +283 -0
  46. data/vendor/PDCurses/demos/rain.c +157 -0
  47. data/vendor/PDCurses/demos/testcurs.c +1607 -0
  48. data/vendor/PDCurses/demos/tui.c +1048 -0
  49. data/vendor/PDCurses/demos/tui.h +65 -0
  50. data/vendor/PDCurses/demos/tuidemo.c +233 -0
  51. data/vendor/PDCurses/demos/version.c +61 -0
  52. data/vendor/PDCurses/demos/worm.c +432 -0
  53. data/vendor/PDCurses/demos/xmas.c +955 -0
  54. data/vendor/PDCurses/dos/CMakeLists.txt +47 -0
  55. data/vendor/PDCurses/dos/Makefile.bcc +83 -0
  56. data/vendor/PDCurses/dos/Makefile.dmc +257 -0
  57. data/vendor/PDCurses/dos/Makefile.msc +113 -0
  58. data/vendor/PDCurses/dos/Makefile.wcc +107 -0
  59. data/vendor/PDCurses/dos/README.md +51 -0
  60. data/vendor/PDCurses/dos/bccdos.lrf +9 -0
  61. data/vendor/PDCurses/dos/mscdos.lrf +50 -0
  62. data/vendor/PDCurses/dos/pdcclip.c +132 -0
  63. data/vendor/PDCurses/dos/pdcdisp.c +135 -0
  64. data/vendor/PDCurses/dos/pdcdos.h +194 -0
  65. data/vendor/PDCurses/dos/pdcgetsc.c +98 -0
  66. data/vendor/PDCurses/dos/pdckbd.c +513 -0
  67. data/vendor/PDCurses/dos/pdcscrn.c +785 -0
  68. data/vendor/PDCurses/dos/pdcsetsc.c +101 -0
  69. data/vendor/PDCurses/dos/pdcutil.c +212 -0
  70. data/vendor/PDCurses/libobjs.mif +26 -0
  71. data/vendor/PDCurses/makedist.mif +20 -0
  72. data/vendor/PDCurses/man/README.md +21 -0
  73. data/vendor/PDCurses/man/intro.md +361 -0
  74. data/vendor/PDCurses/man/manext.c +119 -0
  75. data/vendor/PDCurses/man/sdl.md +152 -0
  76. data/vendor/PDCurses/man/sdl2.md +58 -0
  77. data/vendor/PDCurses/man/x11.md +407 -0
  78. data/vendor/PDCurses/ncurses/CMakeLists.txt +66 -0
  79. data/vendor/PDCurses/ncurses/README.md +26 -0
  80. data/vendor/PDCurses/ncurses/makefile +29 -0
  81. data/vendor/PDCurses/os2/CMakeLists.txt +41 -0
  82. data/vendor/PDCurses/os2/Makefile.bcc +90 -0
  83. data/vendor/PDCurses/os2/Makefile.wcc +43 -0
  84. data/vendor/PDCurses/os2/README.md +43 -0
  85. data/vendor/PDCurses/os2/iccos2.lrf +50 -0
  86. data/vendor/PDCurses/os2/iccos2.mak +256 -0
  87. data/vendor/PDCurses/os2/pdcclip.c +188 -0
  88. data/vendor/PDCurses/os2/pdcdisp.c +93 -0
  89. data/vendor/PDCurses/os2/pdcgetsc.c +89 -0
  90. data/vendor/PDCurses/os2/pdckbd.c +521 -0
  91. data/vendor/PDCurses/os2/pdcos2.h +55 -0
  92. data/vendor/PDCurses/os2/pdcscrn.c +449 -0
  93. data/vendor/PDCurses/os2/pdcsetsc.c +112 -0
  94. data/vendor/PDCurses/os2/pdcutil.c +52 -0
  95. data/vendor/PDCurses/panel.h +56 -0
  96. data/vendor/PDCurses/pdcurses/README.md +25 -0
  97. data/vendor/PDCurses/pdcurses/addch.c +693 -0
  98. data/vendor/PDCurses/pdcurses/addchstr.c +245 -0
  99. data/vendor/PDCurses/pdcurses/addstr.c +240 -0
  100. data/vendor/PDCurses/pdcurses/attr.c +359 -0
  101. data/vendor/PDCurses/pdcurses/beep.c +68 -0
  102. data/vendor/PDCurses/pdcurses/bkgd.c +223 -0
  103. data/vendor/PDCurses/pdcurses/border.c +411 -0
  104. data/vendor/PDCurses/pdcurses/clear.c +159 -0
  105. data/vendor/PDCurses/pdcurses/color.c +298 -0
  106. data/vendor/PDCurses/pdcurses/debug.c +109 -0
  107. data/vendor/PDCurses/pdcurses/delch.c +96 -0
  108. data/vendor/PDCurses/pdcurses/deleteln.c +211 -0
  109. data/vendor/PDCurses/pdcurses/deprec.c +27 -0
  110. data/vendor/PDCurses/pdcurses/getch.c +417 -0
  111. data/vendor/PDCurses/pdcurses/getstr.c +474 -0
  112. data/vendor/PDCurses/pdcurses/getyx.c +139 -0
  113. data/vendor/PDCurses/pdcurses/inch.c +127 -0
  114. data/vendor/PDCurses/pdcurses/inchstr.c +214 -0
  115. data/vendor/PDCurses/pdcurses/initscr.c +367 -0
  116. data/vendor/PDCurses/pdcurses/inopts.c +324 -0
  117. data/vendor/PDCurses/pdcurses/insch.c +271 -0
  118. data/vendor/PDCurses/pdcurses/insstr.c +264 -0
  119. data/vendor/PDCurses/pdcurses/instr.c +246 -0
  120. data/vendor/PDCurses/pdcurses/kernel.c +259 -0
  121. data/vendor/PDCurses/pdcurses/keyname.c +157 -0
  122. data/vendor/PDCurses/pdcurses/mouse.c +438 -0
  123. data/vendor/PDCurses/pdcurses/move.c +57 -0
  124. data/vendor/PDCurses/pdcurses/outopts.c +159 -0
  125. data/vendor/PDCurses/pdcurses/overlay.c +214 -0
  126. data/vendor/PDCurses/pdcurses/pad.c +260 -0
  127. data/vendor/PDCurses/pdcurses/panel.c +633 -0
  128. data/vendor/PDCurses/pdcurses/printw.c +126 -0
  129. data/vendor/PDCurses/pdcurses/refresh.c +279 -0
  130. data/vendor/PDCurses/pdcurses/scanw.c +578 -0
  131. data/vendor/PDCurses/pdcurses/scr_dump.c +213 -0
  132. data/vendor/PDCurses/pdcurses/scroll.c +101 -0
  133. data/vendor/PDCurses/pdcurses/slk.c +591 -0
  134. data/vendor/PDCurses/pdcurses/termattr.c +182 -0
  135. data/vendor/PDCurses/pdcurses/terminfo.c +217 -0
  136. data/vendor/PDCurses/pdcurses/touch.c +163 -0
  137. data/vendor/PDCurses/pdcurses/util.c +312 -0
  138. data/vendor/PDCurses/pdcurses/window.c +569 -0
  139. data/vendor/PDCurses/sdl1/Makefile.mng +110 -0
  140. data/vendor/PDCurses/sdl1/README.md +31 -0
  141. data/vendor/PDCurses/sdl1/deffont.h +385 -0
  142. data/vendor/PDCurses/sdl1/deficon.h +23 -0
  143. data/vendor/PDCurses/sdl1/pdcclip.c +131 -0
  144. data/vendor/PDCurses/sdl1/pdcdisp.c +373 -0
  145. data/vendor/PDCurses/sdl1/pdcgetsc.c +30 -0
  146. data/vendor/PDCurses/sdl1/pdckbd.c +405 -0
  147. data/vendor/PDCurses/sdl1/pdcscrn.c +414 -0
  148. data/vendor/PDCurses/sdl1/pdcsdl.h +31 -0
  149. data/vendor/PDCurses/sdl1/pdcsetsc.c +64 -0
  150. data/vendor/PDCurses/sdl1/pdcutil.c +40 -0
  151. data/vendor/PDCurses/sdl1/sdltest.c +79 -0
  152. data/vendor/PDCurses/sdl2/CMakeLists.txt +76 -0
  153. data/vendor/PDCurses/sdl2/Makefile.vc +164 -0
  154. data/vendor/PDCurses/sdl2/README.md +34 -0
  155. data/vendor/PDCurses/sdl2/deffont.h +385 -0
  156. data/vendor/PDCurses/sdl2/deficon.h +23 -0
  157. data/vendor/PDCurses/sdl2/pdcclip.c +93 -0
  158. data/vendor/PDCurses/sdl2/pdcdisp.c +534 -0
  159. data/vendor/PDCurses/sdl2/pdcgetsc.c +30 -0
  160. data/vendor/PDCurses/sdl2/pdckbd.c +480 -0
  161. data/vendor/PDCurses/sdl2/pdcscrn.c +443 -0
  162. data/vendor/PDCurses/sdl2/pdcsdl.h +33 -0
  163. data/vendor/PDCurses/sdl2/pdcsetsc.c +67 -0
  164. data/vendor/PDCurses/sdl2/pdcutil.c +39 -0
  165. data/vendor/PDCurses/sdl2/sdltest.c +81 -0
  166. data/vendor/PDCurses/term.h +48 -0
  167. data/vendor/PDCurses/version.mif +7 -0
  168. data/vendor/PDCurses/vt/CMakeLists.txt +28 -0
  169. data/vendor/PDCurses/vt/Makefile.bcc +111 -0
  170. data/vendor/PDCurses/vt/Makefile.dmc +258 -0
  171. data/vendor/PDCurses/vt/Makefile.vc +144 -0
  172. data/vendor/PDCurses/vt/Makefile.wcc +107 -0
  173. data/vendor/PDCurses/vt/README.md +64 -0
  174. data/vendor/PDCurses/vt/pdcclip.c +20 -0
  175. data/vendor/PDCurses/vt/pdcdisp.c +284 -0
  176. data/vendor/PDCurses/vt/pdcgetsc.c +27 -0
  177. data/vendor/PDCurses/vt/pdckbd.c +394 -0
  178. data/vendor/PDCurses/vt/pdcscrn.c +434 -0
  179. data/vendor/PDCurses/vt/pdcsetsc.c +45 -0
  180. data/vendor/PDCurses/vt/pdcutil.c +43 -0
  181. data/vendor/PDCurses/vt/pdcvt.h +16 -0
  182. data/vendor/PDCurses/watcom.mif +68 -0
  183. data/vendor/PDCurses/wincon/CMakeLists.txt +27 -0
  184. data/vendor/PDCurses/wincon/Makefile.bcc +88 -0
  185. data/vendor/PDCurses/wincon/Makefile.dmc +256 -0
  186. data/vendor/PDCurses/wincon/Makefile.lcc +273 -0
  187. data/vendor/PDCurses/wincon/Makefile.mng +176 -0
  188. data/vendor/PDCurses/wincon/Makefile.vc +144 -0
  189. data/vendor/PDCurses/wincon/Makefile.wcc +51 -0
  190. data/vendor/PDCurses/wincon/README.md +85 -0
  191. data/vendor/PDCurses/wincon/pdcclip.c +174 -0
  192. data/vendor/PDCurses/wincon/pdcdisp.c +143 -0
  193. data/vendor/PDCurses/wincon/pdcgetsc.c +55 -0
  194. data/vendor/PDCurses/wincon/pdckbd.c +786 -0
  195. data/vendor/PDCurses/wincon/pdcscrn.c +717 -0
  196. data/vendor/PDCurses/wincon/pdcsetsc.c +91 -0
  197. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  198. data/vendor/PDCurses/wincon/pdcurses.rc +28 -0
  199. data/vendor/PDCurses/wincon/pdcutil.c +41 -0
  200. data/vendor/PDCurses/wincon/pdcwin.h +31 -0
  201. data/vendor/PDCurses/wingui/CMakeLists.txt +27 -0
  202. data/vendor/PDCurses/wingui/Makefile.bcc +85 -0
  203. data/vendor/PDCurses/wingui/Makefile.dmc +259 -0
  204. data/vendor/PDCurses/wingui/Makefile.lcc +273 -0
  205. data/vendor/PDCurses/wingui/Makefile.mng +171 -0
  206. data/vendor/PDCurses/wingui/Makefile.vc +144 -0
  207. data/vendor/PDCurses/wingui/Makefile.wcc +51 -0
  208. data/vendor/PDCurses/wingui/README.md +93 -0
  209. data/vendor/PDCurses/wingui/pdcclip.c +174 -0
  210. data/vendor/PDCurses/wingui/pdcdisp.c +718 -0
  211. data/vendor/PDCurses/wingui/pdcgetsc.c +30 -0
  212. data/vendor/PDCurses/wingui/pdckbd.c +143 -0
  213. data/vendor/PDCurses/wingui/pdcscrn.c +2797 -0
  214. data/vendor/PDCurses/wingui/pdcsetsc.c +89 -0
  215. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  216. data/vendor/PDCurses/wingui/pdcurses.rc +28 -0
  217. data/vendor/PDCurses/wingui/pdcutil.c +61 -0
  218. data/vendor/PDCurses/wingui/pdcwin.h +122 -0
  219. data/vendor/PDCurses/x11/Makefile.in +754 -0
  220. data/vendor/PDCurses/x11/PDCurses.spec +82 -0
  221. data/vendor/PDCurses/x11/README.md +62 -0
  222. data/vendor/PDCurses/x11/ScrollBox.c +319 -0
  223. data/vendor/PDCurses/x11/ScrollBox.h +51 -0
  224. data/vendor/PDCurses/x11/ScrollBoxP.h +70 -0
  225. data/vendor/PDCurses/x11/aclocal.m4 +994 -0
  226. data/vendor/PDCurses/x11/big_icon.xbm +46 -0
  227. data/vendor/PDCurses/x11/compose.h +201 -0
  228. data/vendor/PDCurses/x11/config.guess +1500 -0
  229. data/vendor/PDCurses/x11/config.h.in +100 -0
  230. data/vendor/PDCurses/x11/config.sub +1616 -0
  231. data/vendor/PDCurses/x11/configure +6700 -0
  232. data/vendor/PDCurses/x11/configure.ac +295 -0
  233. data/vendor/PDCurses/x11/debian/changelog +6 -0
  234. data/vendor/PDCurses/x11/debian/compat +1 -0
  235. data/vendor/PDCurses/x11/debian/control +11 -0
  236. data/vendor/PDCurses/x11/debian/copyright +27 -0
  237. data/vendor/PDCurses/x11/debian/rules +98 -0
  238. data/vendor/PDCurses/x11/install-sh +253 -0
  239. data/vendor/PDCurses/x11/little_icon.xbm +14 -0
  240. data/vendor/PDCurses/x11/ncurses_cfg.h +45 -0
  241. data/vendor/PDCurses/x11/pdcclip.c +173 -0
  242. data/vendor/PDCurses/x11/pdcdisp.c +85 -0
  243. data/vendor/PDCurses/x11/pdcgetsc.c +28 -0
  244. data/vendor/PDCurses/x11/pdckbd.c +104 -0
  245. data/vendor/PDCurses/x11/pdcscrn.c +258 -0
  246. data/vendor/PDCurses/x11/pdcsetsc.c +95 -0
  247. data/vendor/PDCurses/x11/pdcutil.c +52 -0
  248. data/vendor/PDCurses/x11/pdcx11.c +316 -0
  249. data/vendor/PDCurses/x11/pdcx11.h +191 -0
  250. data/vendor/PDCurses/x11/sb.c +155 -0
  251. data/vendor/PDCurses/x11/x11.c +3686 -0
  252. data/vendor/PDCurses/x11/xcurses-config.in +81 -0
  253. metadata +255 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c8cd5188348efc3da97bd7fd52aaf748636da0278c9d08d9b3a8aef9bd124f9
4
- data.tar.gz: 98afd30e1daa2bee1a50f2f3f037ffbf503acd2befa84d89ee3fe3f6f0e62e83
3
+ metadata.gz: ab24f57e39b3e38b5b9833d34f9bf5d6c2d55337f59693c628e30aa1f4f7324e
4
+ data.tar.gz: a91a892d3c975670cccda3d99a5d7b7a9b0ff8e708aedaf87a2d57cc505d6338
5
5
  SHA512:
6
- metadata.gz: 5093a94321e82de364022d2e997263659a4ecbd0ce7528fcad780e09bbb08db7c172ee13805b6775d4dd9754e7581eafba50dd363f94aac7e458c9da9ee5af8b
7
- data.tar.gz: 8e4e86a0884300c5dcd0c9da5974597eba4adcc0d4bb1ab31e648fdea2689cc50cf2d556e401a30b40a1ca9d9d3e6eedd664c1efaa44192d06dcd893e43d76f5
6
+ metadata.gz: eff7ca406eeb081d6dcac3fe394e44577fdfdfa41428ecfb2068fd7de5288204df78081ff1e5bc41f5594c43194e8b20797ae6361cf7ffa028faf7301b085dd9
7
+ data.tar.gz: d06b2e6d23e5eaac2b5c42cc9b433ef6e5ea25961e28dbe760d51b3fee5aadb2d5f68e76e1a7b1b066ecbcdc129b079c00e7e8427d7e31f4fe65950239eae9b5
@@ -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,28 @@
1
+ name: windows
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: windows-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: [ '2.7.x', '2.6.x', '2.5.x' ]
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ with:
14
+ submodules: true
15
+ - name: Set up Ruby
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ - name: Install dependencies
20
+ run: |
21
+ gem install bundler --no-document
22
+ bundle install
23
+ - name: Build package
24
+ run: bundle exec rake build
25
+ - name: Install package
26
+ run: |
27
+ gem install pkg/curses-*.gem
28
+ ruby -r curses -e 'puts Curses::VERSION'
@@ -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
@@ -6,8 +6,11 @@ notifications:
6
6
  - drbrain@segment7.net
7
7
  - shugo@ruby-lang.org
8
8
  rvm:
9
- - 2.2.7
10
- - 2.3.4
11
- - 2.4.1
9
+ - 2.2.10
10
+ - 2.3.8
11
+ - 2.4.5
12
+ - 2.5.3
13
+ - 2.6.1
12
14
  - ruby-head
15
+ before_install: gem install bundler -v '<2'
13
16
  script: rake compile
data/History.md CHANGED
@@ -1,3 +1,43 @@
1
+ ### 1.4.0 / 2020-12-10
2
+
3
+ New features:
4
+
5
+ * Remove fat binary support for newer versions of Ruby
6
+
7
+ ### 1.3.2 / 2019-12-20
8
+
9
+ Bug fixes:
10
+
11
+ * Drop rb_safe_level check for Ruby 2.7 by Eric Wong.
12
+ * Try libtinfow first. Issue #52 by Marco Sirabella.
13
+
14
+ ### 1.3.1 / 2019-04-21
15
+
16
+ Bug fixes:
17
+
18
+ * Check whether sizeof(WINDOW) is available to avoid build failures on macOS.
19
+ Issue #48 reported by chdiza.
20
+
21
+ ### 1.3.0 / 2019-04-16
22
+
23
+ New features:
24
+
25
+ * Add Curses::Form and Curses::Field.
26
+
27
+ Bug fixes:
28
+
29
+ * Fix TravisCI issues by amatsuda and znz.
30
+ * Fix typo in sample/menu.rb by binford2k.
31
+ * Ctrl-/ should return ^_ on Windows.
32
+ * Workaround for new Windows console.
33
+ https://github.com/Bill-Gray/PDCurses/pull/108
34
+
35
+ ### 1.2.7 / 2019-01-10
36
+
37
+ Bug fixes:
38
+
39
+ * Add curses.so for Ruby 2.5/2.6 on x86-mingw32.
40
+
1
41
  ### 1.2.6 / 2019-01-09
2
42
 
3
43
  New features:
data/README.md CHANGED
@@ -18,7 +18,7 @@ with the release of Ruby 2.1.0. (see [ruby/ruby@9c5b2fd][2])
18
18
  ## Install
19
19
 
20
20
  $ gem install curses
21
-
21
+
22
22
  Requires ncurses or ncursesw (with wide character support).
23
23
  On Debian based distributions, you can install it with apt:
24
24
 
@@ -28,6 +28,9 @@ Or
28
28
 
29
29
  $ apt install libncursesw5-dev
30
30
 
31
+ On mingw, `gem install curses` will install pre-built PDCurses, so you
32
+ don't need to install extra libraries.
33
+
31
34
  ## Documentation
32
35
 
33
36
  See [https://www.rubydoc.info/gems/curses](https://www.rubydoc.info/gems/curses).
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
@@ -1,17 +1,16 @@
1
1
  Gem::Specification.new { |s|
2
2
  s.name = "curses"
3
- s.version = "1.2.6"
3
+ s.version = "1.4.0"
4
4
  s.author = ["Shugo Maeda", 'Eric Hodel']
5
5
  s.email = ["shugo@ruby-lang.org", 'drbrain@segment7.net']
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
  }
@@ -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
@@ -84,6 +96,10 @@ static VALUE cMouseEvent;
84
96
  static VALUE cItem;
85
97
  static VALUE cMenu;
86
98
  #endif
99
+ #ifdef HAVE_FORM
100
+ static VALUE cField;
101
+ static VALUE cForm;
102
+ #endif
87
103
  static VALUE eError;
88
104
  static VALUE eSystemError;
89
105
  static VALUE eBadArgumentError;
@@ -199,6 +215,7 @@ static VALUE window_attroff(VALUE obj, VALUE attrs);
199
215
  static VALUE window_attron(VALUE obj, VALUE attrs);
200
216
  static VALUE window_attrset(VALUE obj, VALUE attrs);
201
217
 
218
+ NORETURN(static void no_window(void));
202
219
  static void
203
220
  no_window(void)
204
221
  {
@@ -206,8 +223,6 @@ no_window(void)
206
223
  }
207
224
 
208
225
  #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
226
  TypedData_Get_Struct((obj), struct windata, &windata_type, (winp));\
212
227
  if ((winp)->window == 0) no_window();\
213
228
  } while (0)
@@ -227,7 +242,7 @@ window_memsize(const void *p)
227
242
  const struct windata *winp = p;
228
243
  size_t size = sizeof(*winp);
229
244
  if (!winp) return 0;
230
- if (winp->window && winp->window != stdscr) size += sizeof(winp->window);
245
+ if (winp->window && winp->window != stdscr) size += CURSES_SIZEOF_WINDOW;
231
246
  return size;
232
247
  }
233
248
 
@@ -843,7 +858,7 @@ getstr_func(void *arg)
843
858
  /*
844
859
  * Document-method: Curses.getstr
845
860
  *
846
- * This is equivalent to a series f Curses::Window.getch calls
861
+ * This is equivalent to a series of Curses::Window.getch calls
847
862
  *
848
863
  */
849
864
  static VALUE
@@ -1425,6 +1440,7 @@ struct mousedata {
1425
1440
  MEVENT *mevent;
1426
1441
  };
1427
1442
 
1443
+ NORETURN(static void no_mevent(void));
1428
1444
  static void
1429
1445
  no_mevent(void)
1430
1446
  {
@@ -1432,8 +1448,6 @@ no_mevent(void)
1432
1448
  }
1433
1449
 
1434
1450
  #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
1451
  TypedData_Get_Struct((obj), struct mousedata, &mousedata_type, (data));\
1438
1452
  if ((data)->mevent == 0) no_mevent();\
1439
1453
  } while (0)
@@ -1452,7 +1466,7 @@ curses_mousedata_memsize(const void *p)
1452
1466
  const struct mousedata *mdata = p;
1453
1467
  size_t size = sizeof(*mdata);
1454
1468
  if (!mdata) return 0;
1455
- if (mdata->mevent) size += sizeof(mdata->mevent);
1469
+ if (mdata->mevent) size += CURSES_SIZEOF_MEVENT;
1456
1470
  return size;
1457
1471
  }
1458
1472
 
@@ -2400,7 +2414,7 @@ wgetstr_func(void *_arg)
2400
2414
  /*
2401
2415
  * Document-method: Curses::Window.getstr
2402
2416
  *
2403
- * This is equivalent to a series f Curses::Window.getch calls
2417
+ * This is equivalent to a series of Curses::Window.getch calls
2404
2418
  *
2405
2419
  */
2406
2420
  static VALUE
@@ -3028,8 +3042,6 @@ no_item(void)
3028
3042
  }
3029
3043
 
3030
3044
  #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
3045
  TypedData_Get_Struct((obj), struct itemdata, &itemdata_type, (itemp));\
3034
3046
  if ((itemp)->item == 0) no_item();\
3035
3047
  } while (0)
@@ -3049,7 +3061,7 @@ item_memsize(const void *p)
3049
3061
  const struct itemdata *itemp = p;
3050
3062
  size_t size = sizeof(*itemp);
3051
3063
  if (!itemp) return 0;
3052
- if (itemp->item) size += sizeof(itemp->item);
3064
+ if (itemp->item) size += CURSES_SIZEOF_ITEM;
3053
3065
  return size;
3054
3066
  }
3055
3067
 
@@ -3139,6 +3151,83 @@ item_description_m(VALUE obj)
3139
3151
  return rb_external_str_new_with_enc(desc, strlen(desc), terminal_encoding);
3140
3152
  }
3141
3153
 
3154
+ /*
3155
+ * Document-method: Curses::Item#set_opts
3156
+ *
3157
+ * call-seq:
3158
+ * set_opts(opts)
3159
+ *
3160
+ * Set the option bits of the item.
3161
+ */
3162
+ static VALUE
3163
+ item_set_opts(VALUE obj, VALUE opts)
3164
+ {
3165
+ struct itemdata *itemp;
3166
+ int error;
3167
+
3168
+ GetITEM(obj, itemp);
3169
+ error = set_item_opts(itemp->item, NUM2INT(opts));
3170
+ check_curses_error(error);
3171
+ return obj;
3172
+ }
3173
+
3174
+ /*
3175
+ * Document-method: Curses::Item#opts_on
3176
+ *
3177
+ * call-seq:
3178
+ * opts_on(opts)
3179
+ *
3180
+ * Turn on the option bits of the item.
3181
+ */
3182
+ static VALUE
3183
+ item_opts_on_m(VALUE obj, VALUE opts)
3184
+ {
3185
+ struct itemdata *itemp;
3186
+ int error;
3187
+
3188
+ GetITEM(obj, itemp);
3189
+ error = item_opts_on(itemp->item, NUM2INT(opts));
3190
+ check_curses_error(error);
3191
+ return obj;
3192
+ }
3193
+
3194
+ /*
3195
+ * Document-method: Curses::Item#opts_off
3196
+ *
3197
+ * call-seq:
3198
+ * opts_off(opts)
3199
+ *
3200
+ * Turn off the option bits of the item.
3201
+ */
3202
+ static VALUE
3203
+ item_opts_off_m(VALUE obj, VALUE opts)
3204
+ {
3205
+ struct itemdata *itemp;
3206
+ int error;
3207
+
3208
+ GetITEM(obj, itemp);
3209
+ error = item_opts_off(itemp->item, NUM2INT(opts));
3210
+ check_curses_error(error);
3211
+ return obj;
3212
+ }
3213
+
3214
+ /*
3215
+ * Document-method: Curses::Item#opts
3216
+ *
3217
+ * call-seq:
3218
+ * opts
3219
+ *
3220
+ * Get the current option bits of the item.
3221
+ */
3222
+ static VALUE
3223
+ item_opts_m(VALUE obj, VALUE opts)
3224
+ {
3225
+ struct itemdata *itemp;
3226
+
3227
+ GetITEM(obj, itemp);
3228
+ return INT2NUM(item_opts(itemp->item));
3229
+ }
3230
+
3142
3231
  struct menudata {
3143
3232
  MENU *menu;
3144
3233
  VALUE items;
@@ -3151,8 +3240,6 @@ no_menu(void)
3151
3240
  }
3152
3241
 
3153
3242
  #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
3243
  TypedData_Get_Struct((obj), struct menudata, &menudata_type, (menup));\
3157
3244
  if ((menup)->menu == 0) no_menu();\
3158
3245
  } while (0)
@@ -3183,7 +3270,7 @@ menu_memsize(const void *p)
3183
3270
  const struct menudata *menup = p;
3184
3271
  size_t size = sizeof(*menup);
3185
3272
  if (!menup) return 0;
3186
- if (menup->menu) size += sizeof(menup->menu);
3273
+ if (menup->menu) size += CURSES_SIZEOF_MENU;
3187
3274
  return size;
3188
3275
  }
3189
3276
 
@@ -3205,7 +3292,7 @@ menu_s_allocate(VALUE class)
3205
3292
  * Document-method: Curses::Menu.new
3206
3293
  *
3207
3294
  * call-seq:
3208
- * new(name, description)
3295
+ * new(items)
3209
3296
  *
3210
3297
  * Construct a new Curses::Menu.
3211
3298
  */
@@ -3215,6 +3302,7 @@ menu_initialize(VALUE obj, VALUE items)
3215
3302
  struct menudata *menup;
3216
3303
  ITEM **menu_items;
3217
3304
  int i;
3305
+ ID id_new;
3218
3306
 
3219
3307
  Check_Type(items, T_ARRAY);
3220
3308
  curses_init_screen();
@@ -3222,19 +3310,25 @@ menu_initialize(VALUE obj, VALUE items)
3222
3310
  if (menup->menu) {
3223
3311
  rb_raise(rb_eRuntimeError, "already initialized menu");
3224
3312
  }
3313
+ menup->items = rb_ary_new();
3225
3314
  menu_items = ALLOC_N(ITEM *, RARRAY_LEN(items) + 1);
3315
+ CONST_ID(id_new, "new");
3226
3316
  for (i = 0; i < RARRAY_LEN(items); i++) {
3317
+ VALUE item = RARRAY_AREF(items, i);
3227
3318
  struct itemdata *itemp;
3228
3319
 
3229
- GetITEM(RARRAY_AREF(items, i), itemp);
3320
+ if (RB_TYPE_P(item, T_ARRAY)) {
3321
+ item = rb_apply(cItem, id_new, item);
3322
+ }
3323
+ GetITEM(item, itemp);
3230
3324
  menu_items[i] = itemp->item;
3325
+ rb_ary_push(menup->items, item);
3231
3326
  }
3232
3327
  menu_items[RARRAY_LEN(items)] = NULL;
3233
3328
  menup->menu = new_menu(menu_items);
3234
3329
  if (menup->menu == NULL) {
3235
3330
  check_curses_error(errno);
3236
3331
  }
3237
- menup->items = rb_ary_dup(items);
3238
3332
 
3239
3333
  return obj;
3240
3334
  }
@@ -3426,200 +3520,1075 @@ menu_set_current_item(VALUE obj, VALUE item)
3426
3520
  return item;
3427
3521
  }
3428
3522
 
3429
- #endif /* HAVE_MENU */
3430
-
3431
3523
  /*
3432
- * Document-method: Curses.keyboard_encoding
3433
- * call-seq: Curses.keyboard_encoding
3524
+ * Document-method: Curses::Menu#set_win
3434
3525
  *
3435
- * Returns the encoding for keyboard input.
3526
+ * call-seq:
3527
+ * set_win=(win)
3528
+ *
3529
+ * Set the window of the menu.
3436
3530
  */
3437
3531
  static VALUE
3438
- curses_get_keyboard_encoding(VALUE obj)
3532
+ menu_set_win(VALUE obj, VALUE win)
3439
3533
  {
3440
- return rb_enc_from_encoding(keyboard_encoding);
3534
+ struct menudata *menup;
3535
+ struct windata *winp;
3536
+
3537
+ GetMENU(obj, menup);
3538
+ GetWINDOW(win, winp);
3539
+ set_menu_win(menup->menu, winp->window);
3540
+ return win;
3441
3541
  }
3442
3542
 
3443
3543
  /*
3444
- * Document-method: Curses.keyboard_encoding=
3445
- * call-seq: Curses.keyboard_encoding = encoding
3544
+ * Document-method: Curses::Menu#set_sub
3446
3545
  *
3447
- * Sets the encoding for keyboard input.
3546
+ * call-seq:
3547
+ * set_sub=(win)
3548
+ *
3549
+ * Set the subwindow of the menu.
3448
3550
  */
3449
3551
  static VALUE
3450
- curses_set_keyboard_encoding(VALUE obj, VALUE enc)
3552
+ menu_set_sub(VALUE obj, VALUE win)
3451
3553
  {
3452
- keyboard_encoding = rb_to_encoding(enc);
3453
- return enc;
3554
+ struct menudata *menup;
3555
+ struct windata *winp;
3556
+
3557
+ GetMENU(obj, menup);
3558
+ GetWINDOW(win, winp);
3559
+ set_menu_sub(menup->menu, winp->window);
3560
+ return win;
3454
3561
  }
3455
3562
 
3456
3563
  /*
3457
- * Document-method: Curses.terminal_encoding
3458
- * call-seq: Curses.terminal_encoding
3564
+ * Document-method: Curses::Menu#scale
3459
3565
  *
3460
- * Returns the encoding for terminal output.
3566
+ * call-seq:
3567
+ * scale
3568
+ *
3569
+ * Return the minimum rows and columns required for the subwindow of the menu.
3461
3570
  */
3462
3571
  static VALUE
3463
- curses_get_terminal_encoding(VALUE obj)
3572
+ menu_scale(VALUE obj)
3464
3573
  {
3465
- return rb_enc_from_encoding(terminal_encoding);
3574
+ struct menudata *menup;
3575
+ int error, rows, columns;
3576
+
3577
+ GetMENU(obj, menup);
3578
+ error = scale_menu(menup->menu, &rows, &columns);
3579
+ check_curses_error(error);
3580
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(columns));
3466
3581
  }
3467
3582
 
3468
3583
  /*
3469
- * Document-method: Curses.terminal_encoding=
3470
- * call-seq: Curses.terminal_encoding = encoding
3584
+ * Document-method: Curses::Menu#set_format
3471
3585
  *
3472
- * Sets the encoding for terminal output.
3586
+ * call-seq:
3587
+ * set_format(rows, cols)
3588
+ *
3589
+ * Set the maximum size of the menu.
3473
3590
  */
3474
3591
  static VALUE
3475
- curses_set_terminal_encoding(VALUE obj, VALUE enc)
3592
+ menu_set_format(VALUE obj, VALUE rows, VALUE cols)
3476
3593
  {
3477
- terminal_encoding = rb_to_encoding(enc);
3478
- return enc;
3594
+ struct menudata *menup;
3595
+ int error;
3596
+
3597
+ GetMENU(obj, menup);
3598
+ error = set_menu_format(menup->menu, NUM2INT(rows), NUM2INT(cols));
3599
+ check_curses_error(error);
3600
+ return obj;
3479
3601
  }
3480
3602
 
3481
3603
  /*
3482
- * Document-method: Curses.unget_char
3483
- * call-seq: unget_char(ch)
3604
+ * Document-method: Curses::Menu#format
3484
3605
  *
3485
- * Places +ch+ back onto the input queue to be returned by
3486
- * the next call to Curses.get_char etc.
3606
+ * call-seq:
3607
+ * format
3487
3608
  *
3488
- * There is just one input queue for all windows.
3609
+ * Get the maximum size of the menu.
3489
3610
  */
3490
3611
  static VALUE
3491
- curses_unget_char(VALUE obj, VALUE ch)
3612
+ menu_format_m(VALUE obj)
3492
3613
  {
3493
- ID id_ord;
3494
- unsigned int c;
3614
+ struct menudata *menup;
3615
+ int rows, cols;
3495
3616
 
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;
3617
+ GetMENU(obj, menup);
3618
+ menu_format(menup->menu, &rows, &cols);
3619
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(cols));
3514
3620
  }
3515
3621
 
3622
+ /*
3623
+ * Document-method: Curses::Menu#set_opts
3624
+ *
3625
+ * call-seq:
3626
+ * set_opts(opts)
3627
+ *
3628
+ * Set the option bits of the menu.
3629
+ */
3516
3630
  static VALUE
3517
- keyboard_uint_chr(unsigned int ch)
3631
+ menu_set_opts(VALUE obj, VALUE opts)
3518
3632
  {
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
- };
3633
+ struct menudata *menup;
3634
+ int error;
3527
3635
 
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;
3636
+ GetMENU(obj, menup);
3637
+ error = set_menu_opts(menup->menu, NUM2INT(opts));
3638
+ check_curses_error(error);
3639
+ return obj;
3534
3640
  }
3535
- #endif
3536
3641
 
3537
3642
  /*
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.
3643
+ * Document-method: Curses::Menu#opts_on
3544
3644
  *
3545
- * See Curses::Key to all the function KEY_* available
3645
+ * call-seq:
3646
+ * opts_on(opts)
3546
3647
  *
3648
+ * Turn on the option bits of the menu.
3547
3649
  */
3548
3650
  static VALUE
3549
- curses_get_char(VALUE obj)
3651
+ menu_opts_on_m(VALUE obj, VALUE opts)
3550
3652
  {
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;
3653
+ struct menudata *menup;
3654
+ int error;
3565
3655
 
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
3656
+ GetMENU(obj, menup);
3657
+ error = menu_opts_on(menup->menu, NUM2INT(opts));
3658
+ check_curses_error(error);
3659
+ return obj;
3578
3660
  }
3579
3661
 
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)
3662
+ /*
3663
+ * Document-method: Curses::Menu#opts_off
3664
+ *
3665
+ * call-seq:
3666
+ * opts_off(opts)
3667
+ *
3668
+ * Turn off the option bits of the menu.
3669
+ */
3670
+ static VALUE
3671
+ menu_opts_off_m(VALUE obj, VALUE opts)
3590
3672
  {
3591
- struct wget_wch_arg *arg = (struct wget_wch_arg *) _arg;
3592
- arg->retval = wget_wch(arg->win, &arg->ch);
3593
- return 0;
3673
+ struct menudata *menup;
3674
+ int error;
3675
+
3676
+ GetMENU(obj, menup);
3677
+ error = menu_opts_off(menup->menu, NUM2INT(opts));
3678
+ check_curses_error(error);
3679
+ return obj;
3594
3680
  }
3595
- #endif
3596
3681
 
3597
3682
  /*
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.
3683
+ * Document-method: Curses::Menu#opts
3604
3684
  *
3605
- * See Curses::Key to all the function KEY_* available
3685
+ * call-seq:
3686
+ * opts
3606
3687
  *
3688
+ * Get the current option bits of the menu.
3607
3689
  */
3608
3690
  static VALUE
3609
- window_get_char(VALUE obj)
3691
+ menu_opts_m(VALUE obj, VALUE opts)
3610
3692
  {
3611
- #ifdef HAVE_WGET_WCH
3612
- struct windata *winp;
3613
- struct wget_wch_arg arg;
3693
+ struct menudata *menup;
3614
3694
 
3615
- GetWINDOW(obj, winp);
3616
- arg.win = winp->window;
3617
- rb_thread_call_without_gvl(wget_wch_func, &arg, RUBY_UBF_IO, 0);
3618
- switch (arg.retval) {
3619
- case OK:
3620
- return keyboard_uint_chr(arg.ch);
3621
- case KEY_CODE_YES:
3622
- return UINT2NUM(arg.ch);
3695
+ GetMENU(obj, menup);
3696
+ return INT2NUM(menu_opts(menup->menu));
3697
+ }
3698
+ #endif /* HAVE_MENU */
3699
+
3700
+ #ifdef HAVE_FORM
3701
+ struct fielddata {
3702
+ FIELD *field;
3703
+ };
3704
+
3705
+ NORETURN(static void no_field(void));
3706
+ static void
3707
+ no_field(void)
3708
+ {
3709
+ rb_raise(rb_eRuntimeError, "already deleted field");
3710
+ }
3711
+
3712
+ #define GetFIELD(obj, fieldp) do {\
3713
+ TypedData_Get_Struct((obj), struct fielddata, &fielddata_type, (fieldp));\
3714
+ if ((fieldp)->field == 0) no_field();\
3715
+ } while (0)
3716
+
3717
+ static void
3718
+ field_free(void *p)
3719
+ {
3720
+ struct fielddata *fieldp = p;
3721
+ if (fieldp->field) free_field(fieldp->field);
3722
+ fieldp->field = 0;
3723
+ xfree(fieldp);
3724
+ }
3725
+
3726
+ static size_t
3727
+ field_memsize(const void *p)
3728
+ {
3729
+ const struct fielddata *fieldp = p;
3730
+ size_t size = sizeof(*fieldp);
3731
+ if (!fieldp) return 0;
3732
+ if (fieldp->field) size += CURSES_SIZEOF_FIELD;
3733
+ return size;
3734
+ }
3735
+
3736
+ static const rb_data_type_t fielddata_type = {
3737
+ "fielddata",
3738
+ {0, field_free, field_memsize,}
3739
+ };
3740
+
3741
+ /* returns a Curses::Menu object */
3742
+ static VALUE
3743
+ field_s_allocate(VALUE class)
3744
+ {
3745
+ struct fielddata *fieldp;
3746
+
3747
+ return TypedData_Make_Struct(class, struct fielddata, &fielddata_type, fieldp);
3748
+ }
3749
+
3750
+ /*
3751
+ * Document-method: Curses::Field.new
3752
+ *
3753
+ * call-seq:
3754
+ * new(height, width, toprow, leftcol, offscreen, nbuffers)
3755
+ *
3756
+ * Construct a new Curses::Field.
3757
+ */
3758
+ static VALUE
3759
+ field_initialize(VALUE obj, VALUE height, VALUE width,
3760
+ VALUE toprow, VALUE leftcol, VALUE offscreen, VALUE nbuffers)
3761
+ {
3762
+ struct fielddata *fieldp;
3763
+
3764
+ curses_init_screen();
3765
+ TypedData_Get_Struct(obj, struct fielddata, &fielddata_type, fieldp);
3766
+ if (fieldp->field) {
3767
+ rb_raise(rb_eRuntimeError, "already initialized field");
3768
+ }
3769
+ fieldp->field = new_field(NUM2INT(height), NUM2INT(width),
3770
+ NUM2INT(toprow), NUM2INT(leftcol),
3771
+ NUM2INT(offscreen), NUM2INT(nbuffers));
3772
+ if (fieldp->field == NULL) {
3773
+ check_curses_error(errno);
3774
+ }
3775
+
3776
+ return obj;
3777
+ }
3778
+
3779
+ /*
3780
+ * Document-method: Curses::Field#set_buffer
3781
+ *
3782
+ * call-seq:
3783
+ * set_buffer(buf, value)
3784
+ *
3785
+ * Set the numbered buffer of the field.
3786
+ */
3787
+ static VALUE
3788
+ field_set_buffer(VALUE obj, VALUE buf, VALUE value)
3789
+ {
3790
+ struct fielddata *fieldp;
3791
+
3792
+ GetFIELD(obj, fieldp);
3793
+ value = rb_str_export_to_enc(value, terminal_encoding);
3794
+ set_field_buffer(fieldp->field, NUM2INT(buf), StringValueCStr(value));
3795
+
3796
+ return obj;
3797
+ }
3798
+
3799
+ /*
3800
+ * Document-method: Curses::Field#buffer
3801
+ *
3802
+ * call-seq:
3803
+ * buffer(buf)
3804
+ *
3805
+ * Get the numbered buffer of the field.
3806
+ */
3807
+ static VALUE
3808
+ field_buffer_m(VALUE obj, VALUE buf)
3809
+ {
3810
+ struct fielddata *fieldp;
3811
+ char *s;
3812
+
3813
+ GetFIELD(obj, fieldp);
3814
+ s = field_buffer(fieldp->field, NUM2INT(buf));
3815
+ return rb_external_str_new_with_enc(s, strlen(s), terminal_encoding);
3816
+ }
3817
+
3818
+ /*
3819
+ * Document-method: Curses::Field#set_fore
3820
+ *
3821
+ * call-seq:
3822
+ * set_fore(attr)
3823
+ *
3824
+ * Set the foreground attribute of the field.
3825
+ */
3826
+ static VALUE
3827
+ field_set_fore(VALUE obj, VALUE attr)
3828
+ {
3829
+ struct fielddata *fieldp;
3830
+
3831
+ GetFIELD(obj, fieldp);
3832
+ set_field_fore(fieldp->field, NUM2CHTYPE(attr));
3833
+
3834
+ return attr;
3835
+ }
3836
+
3837
+ /*
3838
+ * Document-method: Curses::Field#fore
3839
+ *
3840
+ * call-seq:
3841
+ * fore
3842
+ *
3843
+ * Get the foreground attribute of the field.
3844
+ */
3845
+ static VALUE
3846
+ field_get_fore(VALUE obj)
3847
+ {
3848
+ struct fielddata *fieldp;
3849
+
3850
+ GetFIELD(obj, fieldp);
3851
+ return CHTYPE2NUM(field_fore(fieldp->field));
3852
+ }
3853
+
3854
+ /*
3855
+ * Document-method: Curses::Field#set_back
3856
+ *
3857
+ * call-seq:
3858
+ * set_back(attr)
3859
+ *
3860
+ * Set the background attribute of the field.
3861
+ */
3862
+ static VALUE
3863
+ field_set_back(VALUE obj, VALUE attr)
3864
+ {
3865
+ struct fielddata *fieldp;
3866
+
3867
+ GetFIELD(obj, fieldp);
3868
+ set_field_back(fieldp->field, NUM2CHTYPE(attr));
3869
+
3870
+ return attr;
3871
+ }
3872
+
3873
+ /*
3874
+ * Document-method: Curses::Field#back
3875
+ *
3876
+ * call-seq:
3877
+ * back
3878
+ *
3879
+ * Get the background attribute of the field.
3880
+ */
3881
+ static VALUE
3882
+ field_get_back(VALUE obj)
3883
+ {
3884
+ struct fielddata *fieldp;
3885
+
3886
+ GetFIELD(obj, fieldp);
3887
+ return CHTYPE2NUM(field_back(fieldp->field));
3888
+ }
3889
+
3890
+ /*
3891
+ * Document-method: Curses::Field#opts_on
3892
+ *
3893
+ * call-seq:
3894
+ * opts_on(opts)
3895
+ *
3896
+ * Turn on the given option bits.
3897
+ */
3898
+ static VALUE
3899
+ field_opts_on_m(VALUE obj, VALUE opts)
3900
+ {
3901
+ struct fielddata *fieldp;
3902
+
3903
+ GetFIELD(obj, fieldp);
3904
+ field_opts_on(fieldp->field, NUM2INT(opts));
3905
+
3906
+ return opts;
3907
+ }
3908
+
3909
+ /*
3910
+ * Document-method: Curses::Field#opts_off
3911
+ *
3912
+ * call-seq:
3913
+ * opts_off(opts)
3914
+ *
3915
+ * Turn off the given option bits.
3916
+ */
3917
+ static VALUE
3918
+ field_opts_off_m(VALUE obj, VALUE opts)
3919
+ {
3920
+ struct fielddata *fieldp;
3921
+
3922
+ GetFIELD(obj, fieldp);
3923
+ field_opts_off(fieldp->field, NUM2INT(opts));
3924
+
3925
+ return opts;
3926
+ }
3927
+
3928
+ /*
3929
+ * Document-method: Curses::Field#opts
3930
+ *
3931
+ * call-seq:
3932
+ * opts
3933
+ *
3934
+ * Get the current option bits.
3935
+ */
3936
+ static VALUE
3937
+ field_opts_m(VALUE obj)
3938
+ {
3939
+ struct fielddata *fieldp;
3940
+
3941
+ GetFIELD(obj, fieldp);
3942
+ return INT2NUM(field_opts(fieldp->field));
3943
+ }
3944
+
3945
+ static VALUE
3946
+ field_height(VALUE obj)
3947
+ {
3948
+ struct fielddata *fieldp;
3949
+ int error, val;
3950
+
3951
+ GetFIELD(obj, fieldp);
3952
+ error = field_info(fieldp->field, &val, NULL, NULL, NULL, NULL, NULL);
3953
+ check_curses_error(error);
3954
+ return INT2NUM(val);
3955
+ }
3956
+
3957
+ static VALUE
3958
+ field_width(VALUE obj)
3959
+ {
3960
+ struct fielddata *fieldp;
3961
+ int error, val;
3962
+
3963
+ GetFIELD(obj, fieldp);
3964
+ error = field_info(fieldp->field, NULL, &val, NULL, NULL, NULL, NULL);
3965
+ check_curses_error(error);
3966
+ return INT2NUM(val);
3967
+ }
3968
+
3969
+ static VALUE
3970
+ field_toprow(VALUE obj)
3971
+ {
3972
+ struct fielddata *fieldp;
3973
+ int error, val;
3974
+
3975
+ GetFIELD(obj, fieldp);
3976
+ error = field_info(fieldp->field, NULL, NULL, &val, NULL, NULL, NULL);
3977
+ check_curses_error(error);
3978
+ return INT2NUM(val);
3979
+ }
3980
+
3981
+ static VALUE
3982
+ field_leftcol(VALUE obj)
3983
+ {
3984
+ struct fielddata *fieldp;
3985
+ int error, val;
3986
+
3987
+ GetFIELD(obj, fieldp);
3988
+ error = field_info(fieldp->field, NULL, NULL, NULL, &val, NULL, NULL);
3989
+ check_curses_error(error);
3990
+ return INT2NUM(val);
3991
+ }
3992
+
3993
+ static VALUE
3994
+ field_offscreen(VALUE obj)
3995
+ {
3996
+ struct fielddata *fieldp;
3997
+ int error, val;
3998
+
3999
+ GetFIELD(obj, fieldp);
4000
+ error = field_info(fieldp->field, NULL, NULL, NULL, NULL, &val, NULL);
4001
+ check_curses_error(error);
4002
+ return INT2NUM(val);
4003
+ }
4004
+
4005
+ static VALUE
4006
+ field_nbuffers(VALUE obj)
4007
+ {
4008
+ struct fielddata *fieldp;
4009
+ int error, val;
4010
+
4011
+ GetFIELD(obj, fieldp);
4012
+ error = field_info(fieldp->field, NULL, NULL, NULL, NULL, NULL, &val);
4013
+ check_curses_error(error);
4014
+ return INT2NUM(val);
4015
+ }
4016
+
4017
+ static VALUE
4018
+ field_dynamic_height(VALUE obj)
4019
+ {
4020
+ struct fielddata *fieldp;
4021
+ int error, val;
4022
+
4023
+ GetFIELD(obj, fieldp);
4024
+ error = dynamic_field_info(fieldp->field, &val, NULL, NULL);
4025
+ check_curses_error(error);
4026
+ return INT2NUM(val);
4027
+ }
4028
+
4029
+ static VALUE
4030
+ field_dynamic_width(VALUE obj)
4031
+ {
4032
+ struct fielddata *fieldp;
4033
+ int error, val;
4034
+
4035
+ GetFIELD(obj, fieldp);
4036
+ error = dynamic_field_info(fieldp->field, NULL, &val, NULL);
4037
+ check_curses_error(error);
4038
+ return INT2NUM(val);
4039
+ }
4040
+
4041
+ static VALUE
4042
+ field_max(VALUE obj)
4043
+ {
4044
+ struct fielddata *fieldp;
4045
+ int error, val;
4046
+
4047
+ GetFIELD(obj, fieldp);
4048
+ error = dynamic_field_info(fieldp->field, NULL, NULL, &val);
4049
+ check_curses_error(error);
4050
+ return INT2NUM(val);
4051
+ }
4052
+
4053
+ static VALUE
4054
+ field_set_max(VALUE obj, VALUE max)
4055
+ {
4056
+ struct fielddata *fieldp;
4057
+ int error;
4058
+
4059
+ GetFIELD(obj, fieldp);
4060
+ error = set_max_field(fieldp->field, NUM2INT(max));
4061
+ check_curses_error(error);
4062
+ return max;
4063
+ }
4064
+
4065
+ #define TYPE_CODE_ALPHA 1
4066
+ #define TYPE_CODE_ALNUM 2
4067
+ #define TYPE_CODE_ENUM 3
4068
+ #define TYPE_CODE_INTEGER 4
4069
+ #define TYPE_CODE_NUMERIC 5
4070
+ #define TYPE_CODE_REGEXP 6
4071
+
4072
+ static VALUE
4073
+ field_set_type(int argc, VALUE *argv, VALUE obj)
4074
+ {
4075
+ struct fielddata *fieldp;
4076
+ VALUE type;
4077
+ int type_code;
4078
+ int error;
4079
+
4080
+ if (argc < 1) {
4081
+ rb_raise(rb_eArgError,
4082
+ "wrong number of arguments (given %d, expected 1)", argc);
4083
+ }
4084
+ type_code = NUM2INT(argv[0]);
4085
+ GetFIELD(obj, fieldp);
4086
+ switch (type_code) {
4087
+ case TYPE_CODE_ALPHA:
4088
+ {
4089
+ VALUE width;
4090
+ rb_scan_args(argc, argv, "11", &type, &width);
4091
+ error = set_field_type(fieldp->field, TYPE_ALPHA,
4092
+ NIL_P(width) ? 0 : NUM2INT(width));
4093
+ }
4094
+ break;
4095
+ case TYPE_CODE_ALNUM:
4096
+ {
4097
+ VALUE width;
4098
+ rb_scan_args(argc, argv, "11", &type, &width);
4099
+ error = set_field_type(fieldp->field, TYPE_ALNUM,
4100
+ NIL_P(width) ? 0 : NUM2INT(width));
4101
+ }
4102
+ break;
4103
+ #if 0
4104
+ case TYPE_CODE_ENUM:
4105
+ {
4106
+ /* TODO: consider how valuelist should be allocated? */
4107
+ }
4108
+ break;
4109
+ #endif
4110
+ case TYPE_CODE_INTEGER:
4111
+ {
4112
+ VALUE padding, vmin, vmax;
4113
+ rb_scan_args(argc, argv, "13", &type, &padding, &vmin, &vmax);
4114
+ error = set_field_type(fieldp->field, TYPE_INTEGER,
4115
+ NIL_P(padding) ? 0 : NUM2INT(padding),
4116
+ NIL_P(vmin) ? INT_MIN : NUM2INT(vmin),
4117
+ NIL_P(vmax) ? INT_MAX : NUM2INT(vmax));
4118
+ }
4119
+ break;
4120
+ case TYPE_CODE_NUMERIC:
4121
+ {
4122
+ VALUE padding, vmin, vmax;
4123
+ rb_scan_args(argc, argv, "13", &type, &padding, &vmin, &vmax);
4124
+ error = set_field_type(fieldp->field, TYPE_INTEGER,
4125
+ NIL_P(padding) ? 0 : NUM2INT(padding),
4126
+ NIL_P(vmin) ? INT_MIN : NUM2INT(vmin),
4127
+ NIL_P(vmax) ? INT_MAX : NUM2INT(vmax));
4128
+ }
4129
+ break;
4130
+ #if 0
4131
+ case TYPE_CODE_REGEXP:
4132
+ {
4133
+ /* TODO: consider how regexp should be allocated? */
4134
+ }
4135
+ break;
4136
+ #endif
4137
+ default:
4138
+ rb_raise(rb_eArgError, "unknwon type: %d", type_code);
4139
+ break;
4140
+ }
4141
+ check_curses_error(error);
4142
+ return obj;
4143
+ }
4144
+
4145
+ struct formdata {
4146
+ FORM *form;
4147
+ VALUE fields;
4148
+ };
4149
+
4150
+ NORETURN(static void no_form(void));
4151
+ static void
4152
+ no_form(void)
4153
+ {
4154
+ rb_raise(rb_eRuntimeError, "already deleted form");
4155
+ }
4156
+
4157
+ #define GetFORM(obj, formp) do {\
4158
+ TypedData_Get_Struct((obj), struct formdata, &formdata_type, (formp));\
4159
+ if ((formp)->form == 0) no_form();\
4160
+ } while (0)
4161
+
4162
+ static void
4163
+ form_gc_mark(void *p)
4164
+ {
4165
+ struct formdata *formp = p;
4166
+
4167
+ rb_gc_mark(formp->fields);
4168
+ }
4169
+
4170
+ static void
4171
+ form_free(void *p)
4172
+ {
4173
+ struct formdata *formp = p;
4174
+ FIELD **fields = form_fields(formp->form);
4175
+ if (formp->form) free_form(formp->form);
4176
+ xfree(fields);
4177
+ formp->form = 0;
4178
+ formp->fields = Qnil;
4179
+ xfree(formp);
4180
+ }
4181
+
4182
+ static size_t
4183
+ form_memsize(const void *p)
4184
+ {
4185
+ const struct formdata *formp = p;
4186
+ size_t size = sizeof(*formp);
4187
+ if (!formp) return 0;
4188
+ if (formp->form) size += CURSES_SIZEOF_FORM;
4189
+ return size;
4190
+ }
4191
+
4192
+ static const rb_data_type_t formdata_type = {
4193
+ "formdata",
4194
+ {form_gc_mark, form_free, form_memsize,}
4195
+ };
4196
+
4197
+ /* returns a Curses::Form object */
4198
+ static VALUE
4199
+ form_s_allocate(VALUE class)
4200
+ {
4201
+ struct formdata *formp;
4202
+
4203
+ return TypedData_Make_Struct(class, struct formdata, &formdata_type, formp);
4204
+ }
4205
+
4206
+ /*
4207
+ * Document-method: Curses::Form.new
4208
+ *
4209
+ * call-seq:
4210
+ * new(fields)
4211
+ *
4212
+ * Construct a new Curses::Form.
4213
+ */
4214
+ static VALUE
4215
+ form_initialize(VALUE obj, VALUE fields)
4216
+ {
4217
+ struct formdata *formp;
4218
+ FIELD **form_fields;
4219
+ int i;
4220
+
4221
+ Check_Type(fields, T_ARRAY);
4222
+ curses_init_screen();
4223
+ TypedData_Get_Struct(obj, struct formdata, &formdata_type, formp);
4224
+ if (formp->form) {
4225
+ rb_raise(rb_eRuntimeError, "already initialized form");
4226
+ }
4227
+ formp->fields = rb_ary_new();
4228
+ form_fields = ALLOC_N(FIELD *, RARRAY_LEN(fields) + 1);
4229
+ for (i = 0; i < RARRAY_LEN(fields); i++) {
4230
+ VALUE field = RARRAY_AREF(fields, i);
4231
+ struct fielddata *fieldp;
4232
+
4233
+ GetFIELD(field, fieldp);
4234
+ form_fields[i] = fieldp->field;
4235
+ rb_ary_push(formp->fields, field);
4236
+ }
4237
+ form_fields[RARRAY_LEN(fields)] = NULL;
4238
+ formp->form = new_form(form_fields);
4239
+ if (formp->form == NULL) {
4240
+ check_curses_error(errno);
4241
+ }
4242
+
4243
+ return obj;
4244
+ }
4245
+
4246
+ /*
4247
+ * Document-method: Curses::Form#post
4248
+ *
4249
+ * call-seq:
4250
+ * post
4251
+ *
4252
+ * Post the form.
4253
+ */
4254
+ static VALUE
4255
+ form_post(VALUE obj)
4256
+ {
4257
+ struct formdata *formp;
4258
+ int error;
4259
+
4260
+ GetFORM(obj, formp);
4261
+ error = post_form(formp->form);
4262
+ check_curses_error(error);
4263
+
4264
+ return obj;
4265
+ }
4266
+
4267
+ /*
4268
+ * Document-method: Curses::Form#unpost
4269
+ *
4270
+ * call-seq:
4271
+ * unpost
4272
+ *
4273
+ * Unpost the form.
4274
+ */
4275
+ static VALUE
4276
+ form_unpost(VALUE obj)
4277
+ {
4278
+ struct formdata *formp;
4279
+ int error;
4280
+
4281
+ GetFORM(obj, formp);
4282
+ error = unpost_form(formp->form);
4283
+ check_curses_error(error);
4284
+
4285
+ return obj;
4286
+ }
4287
+
4288
+ /*
4289
+ * Document-method: Curses::Form#driver
4290
+ *
4291
+ * call-seq:
4292
+ * driver(command)
4293
+ *
4294
+ * Perform the command on the form.
4295
+ */
4296
+ static VALUE
4297
+ form_driver_m(VALUE obj, VALUE command)
4298
+ {
4299
+ struct formdata *formp;
4300
+ int error, c;
4301
+
4302
+ GetFORM(obj, formp);
4303
+ if (FIXNUM_P(command)) {
4304
+ c = NUM2INT(command);
4305
+ }
4306
+ else {
4307
+ ID id_ord;
4308
+
4309
+ StringValue(command);
4310
+ CONST_ID(id_ord, "ord");
4311
+ c = NUM2INT(rb_funcall(command, id_ord, 0));
4312
+ }
4313
+ #ifdef HAVE_FORM_DRIVER_W
4314
+ error = form_driver_w(formp->form,
4315
+ FIXNUM_P(command) ? KEY_CODE_YES : OK,
4316
+ c);
4317
+ #else
4318
+ error = form_driver(formp->form, c);
4319
+ #endif
4320
+ check_curses_error(error);
4321
+
4322
+ return obj;
4323
+ }
4324
+
4325
+ /*
4326
+ * Document-method: Curses::Form#set_win
4327
+ *
4328
+ * call-seq:
4329
+ * set_win=(win)
4330
+ *
4331
+ * Set the window of the form.
4332
+ */
4333
+ static VALUE
4334
+ form_set_win(VALUE obj, VALUE win)
4335
+ {
4336
+ struct formdata *formp;
4337
+ struct windata *winp;
4338
+
4339
+ GetFORM(obj, formp);
4340
+ GetWINDOW(win, winp);
4341
+ set_form_win(formp->form, winp->window);
4342
+ return win;
4343
+ }
4344
+
4345
+ /*
4346
+ * Document-method: Curses::Form#set_sub
4347
+ *
4348
+ * call-seq:
4349
+ * set_sub=(win)
4350
+ *
4351
+ * Set the subwindow of the form.
4352
+ */
4353
+ static VALUE
4354
+ form_set_sub(VALUE obj, VALUE win)
4355
+ {
4356
+ struct formdata *formp;
4357
+ struct windata *winp;
4358
+
4359
+ GetFORM(obj, formp);
4360
+ GetWINDOW(win, winp);
4361
+ set_form_sub(formp->form, winp->window);
4362
+ return win;
4363
+ }
4364
+
4365
+ /*
4366
+ * Document-method: Curses::Form#scale
4367
+ *
4368
+ * call-seq:
4369
+ * scale
4370
+ *
4371
+ * Return the minimum rows and columns required for the subwindow of the form.
4372
+ */
4373
+ static VALUE
4374
+ form_scale(VALUE obj)
4375
+ {
4376
+ struct formdata *formp;
4377
+ int error, rows, columns;
4378
+
4379
+ GetFORM(obj, formp);
4380
+ error = scale_form(formp->form, &rows, &columns);
4381
+ check_curses_error(error);
4382
+ return rb_assoc_new(INT2NUM(rows), INT2NUM(columns));
4383
+ }
4384
+
4385
+ #endif /* HAVE_FORM */
4386
+
4387
+ /*
4388
+ * Document-method: Curses.keyboard_encoding
4389
+ * call-seq: Curses.keyboard_encoding
4390
+ *
4391
+ * Returns the encoding for keyboard input.
4392
+ */
4393
+ static VALUE
4394
+ curses_get_keyboard_encoding(VALUE obj)
4395
+ {
4396
+ return rb_enc_from_encoding(keyboard_encoding);
4397
+ }
4398
+
4399
+ /*
4400
+ * Document-method: Curses.keyboard_encoding=
4401
+ * call-seq: Curses.keyboard_encoding = encoding
4402
+ *
4403
+ * Sets the encoding for keyboard input.
4404
+ */
4405
+ static VALUE
4406
+ curses_set_keyboard_encoding(VALUE obj, VALUE enc)
4407
+ {
4408
+ keyboard_encoding = rb_to_encoding(enc);
4409
+ return enc;
4410
+ }
4411
+
4412
+ /*
4413
+ * Document-method: Curses.terminal_encoding
4414
+ * call-seq: Curses.terminal_encoding
4415
+ *
4416
+ * Returns the encoding for terminal output.
4417
+ */
4418
+ static VALUE
4419
+ curses_get_terminal_encoding(VALUE obj)
4420
+ {
4421
+ return rb_enc_from_encoding(terminal_encoding);
4422
+ }
4423
+
4424
+ /*
4425
+ * Document-method: Curses.terminal_encoding=
4426
+ * call-seq: Curses.terminal_encoding = encoding
4427
+ *
4428
+ * Sets the encoding for terminal output.
4429
+ */
4430
+ static VALUE
4431
+ curses_set_terminal_encoding(VALUE obj, VALUE enc)
4432
+ {
4433
+ terminal_encoding = rb_to_encoding(enc);
4434
+ return enc;
4435
+ }
4436
+
4437
+ /*
4438
+ * Document-method: Curses.unget_char
4439
+ * call-seq: unget_char(ch)
4440
+ *
4441
+ * Places +ch+ back onto the input queue to be returned by
4442
+ * the next call to Curses.get_char etc.
4443
+ *
4444
+ * There is just one input queue for all windows.
4445
+ */
4446
+ static VALUE
4447
+ curses_unget_char(VALUE obj, VALUE ch)
4448
+ {
4449
+ ID id_ord;
4450
+ unsigned int c;
4451
+
4452
+ curses_stdscr();
4453
+ if (FIXNUM_P(ch)) {
4454
+ ungetch(NUM2UINT(ch));
4455
+ }
4456
+ else {
4457
+ StringValue(ch);
4458
+ CONST_ID(id_ord, "ord");
4459
+ c = NUM2UINT(rb_funcall(ch, id_ord, 0));
4460
+ #ifdef HAVE_UNGET_WCH
4461
+ unget_wch(c);
4462
+ #else
4463
+ if (c > 0xff) {
4464
+ rb_raise(rb_eRangeError, "Out of range: %u", c);
4465
+ }
4466
+ ungetch(c);
4467
+ #endif
4468
+ }
4469
+ return Qnil;
4470
+ }
4471
+
4472
+ static VALUE
4473
+ keyboard_uint_chr(unsigned int ch)
4474
+ {
4475
+ return rb_enc_uint_chr(ch, keyboard_encoding);
4476
+ }
4477
+
4478
+ #if defined(HAVE_GET_WCH) || defined(HAVE_WGET_WCH)
4479
+ static VALUE
4480
+ key_code_value(unsigned int ch)
4481
+ {
4482
+ #ifdef CTL_FSLASH
4483
+ if (ch == CTL_FSLASH) {
4484
+ return keyboard_uint_chr(0x1F);
4485
+ }
4486
+ #endif
4487
+ return UINT2NUM(ch);
4488
+ }
4489
+ #endif
4490
+
4491
+ #ifdef HAVE_GET_WCH
4492
+ struct get_wch_arg {
4493
+ int retval;
4494
+ wint_t ch;
4495
+ };
4496
+
4497
+ static void *
4498
+ get_wch_func(void *_arg)
4499
+ {
4500
+ struct get_wch_arg *arg = (struct get_wch_arg *) _arg;
4501
+ arg->retval = get_wch(&arg->ch);
4502
+ return 0;
4503
+ }
4504
+ #endif
4505
+
4506
+ /*
4507
+ * Document-method: Curses.get_char
4508
+ *
4509
+ * Read and returns a character or function key from the window.
4510
+ * A single or multibyte character is represented by a String, and
4511
+ * a function key is represented by an Integer.
4512
+ * Returns nil if no input is ready.
4513
+ *
4514
+ * See Curses::Key to all the function KEY_* available
4515
+ *
4516
+ */
4517
+ static VALUE
4518
+ curses_get_char(VALUE obj)
4519
+ {
4520
+ #ifdef HAVE_GET_WCH
4521
+ struct get_wch_arg arg;
4522
+
4523
+ curses_stdscr();
4524
+ rb_thread_call_without_gvl(get_wch_func, &arg, RUBY_UBF_IO, 0);
4525
+ switch (arg.retval) {
4526
+ case OK:
4527
+ return keyboard_uint_chr(arg.ch);
4528
+ case KEY_CODE_YES:
4529
+ return key_code_value(arg.ch);
4530
+ }
4531
+ return Qnil;
4532
+ #else
4533
+ int c;
4534
+
4535
+ curses_stdscr();
4536
+ rb_thread_call_without_gvl(getch_func, &c, RUBY_UBF_IO, 0);
4537
+ if (c > 0xff) {
4538
+ return INT2NUM(c);
4539
+ }
4540
+ else if (c >= 0) {
4541
+ return keyboard_uint_chr(c);
4542
+ }
4543
+ else {
4544
+ return Qnil;
4545
+ }
4546
+ #endif
4547
+ }
4548
+
4549
+
4550
+ #ifdef HAVE_WGET_WCH
4551
+ struct wget_wch_arg {
4552
+ WINDOW *win;
4553
+ int retval;
4554
+ wint_t ch;
4555
+ };
4556
+
4557
+ static void *
4558
+ wget_wch_func(void *_arg)
4559
+ {
4560
+ struct wget_wch_arg *arg = (struct wget_wch_arg *) _arg;
4561
+ arg->retval = wget_wch(arg->win, &arg->ch);
4562
+ return 0;
4563
+ }
4564
+ #endif
4565
+
4566
+ /*
4567
+ * Document-method: Curses::Window.get_char
4568
+ *
4569
+ * Read and returns a character or function key from the window.
4570
+ * A single or multibyte character is represented by a String, and
4571
+ * a function key is represented by an Integer.
4572
+ * Returns nil if no input is ready.
4573
+ *
4574
+ * See Curses::Key to all the function KEY_* available
4575
+ *
4576
+ */
4577
+ static VALUE
4578
+ window_get_char(VALUE obj)
4579
+ {
4580
+ #ifdef HAVE_WGET_WCH
4581
+ struct windata *winp;
4582
+ struct wget_wch_arg arg;
4583
+
4584
+ GetWINDOW(obj, winp);
4585
+ arg.win = winp->window;
4586
+ rb_thread_call_without_gvl(wget_wch_func, &arg, RUBY_UBF_IO, 0);
4587
+ switch (arg.retval) {
4588
+ case OK:
4589
+ return keyboard_uint_chr(arg.ch);
4590
+ case KEY_CODE_YES:
4591
+ return key_code_value(arg.ch);
3623
4592
  }
3624
4593
  return Qnil;
3625
4594
  #else
@@ -3980,6 +4949,10 @@ Init_curses(void)
3980
4949
  rb_define_method(cItem, "==", item_eq, 1);
3981
4950
  rb_define_method(cItem, "name", item_name_m, 0);
3982
4951
  rb_define_method(cItem, "description", item_description_m, 0);
4952
+ rb_define_method(cItem, "set_opts", item_set_opts, 1);
4953
+ rb_define_method(cItem, "opts_on", item_opts_on_m, 1);
4954
+ rb_define_method(cItem, "opts_off", item_opts_off_m, 1);
4955
+ rb_define_method(cItem, "opts", item_opts_m, 0);
3983
4956
 
3984
4957
  cMenu = rb_define_class_under(mCurses, "Menu", rb_cData);
3985
4958
  rb_define_alloc_func(cMenu, menu_s_allocate);
@@ -3992,6 +4965,54 @@ Init_curses(void)
3992
4965
  rb_define_method(cMenu, "items=", menu_set_items, 1);
3993
4966
  rb_define_method(cMenu, "current_item", menu_get_current_item, 0);
3994
4967
  rb_define_method(cMenu, "current_item=", menu_set_current_item, 1);
4968
+ rb_define_method(cMenu, "set_win", menu_set_win, 1);
4969
+ rb_define_method(cMenu, "set_sub", menu_set_sub, 1);
4970
+ rb_define_method(cMenu, "scale", menu_scale, 0);
4971
+ rb_define_method(cMenu, "set_format", menu_set_format, 2);
4972
+ rb_define_method(cMenu, "format", menu_format_m, 0);
4973
+ rb_define_method(cMenu, "set_opts", menu_set_opts, 1);
4974
+ rb_define_method(cMenu, "opts_on", menu_opts_on_m, 1);
4975
+ rb_define_method(cMenu, "opts_off", menu_opts_off_m, 1);
4976
+ rb_define_method(cMenu, "opts", menu_opts_m, 0);
4977
+ #endif
4978
+
4979
+ #ifdef HAVE_FORM
4980
+ cField = rb_define_class_under(mCurses, "Field", rb_cData);
4981
+ rb_define_alloc_func(cField, field_s_allocate);
4982
+ rb_define_method(cField, "initialize", field_initialize, 6);
4983
+ rb_define_method(cField, "set_buffer", field_set_buffer, 2);
4984
+ rb_define_method(cField, "buffer", field_buffer_m, 1);
4985
+ rb_define_method(cField, "set_fore", field_set_fore, 1);
4986
+ rb_define_method(cField, "fore=", field_set_fore, 1);
4987
+ rb_define_method(cField, "fore", field_get_fore, 0);
4988
+ rb_define_method(cField, "set_back", field_set_back, 1);
4989
+ rb_define_method(cField, "back=", field_set_back, 1);
4990
+ rb_define_method(cField, "back", field_get_back, 0);
4991
+ rb_define_method(cField, "opts_on", field_opts_on_m, 1);
4992
+ rb_define_method(cField, "opts_off", field_opts_off_m, 1);
4993
+ rb_define_method(cField, "opts", field_opts_m, 0);
4994
+ rb_define_method(cField, "height", field_height, 0);
4995
+ rb_define_method(cField, "width", field_width, 0);
4996
+ rb_define_method(cField, "toprow", field_toprow, 0);
4997
+ rb_define_method(cField, "leftcol", field_leftcol, 0);
4998
+ rb_define_method(cField, "offscreen", field_offscreen, 0);
4999
+ rb_define_method(cField, "nbuffers", field_nbuffers, 0);
5000
+ rb_define_method(cField, "dynamic_height", field_dynamic_height, 0);
5001
+ rb_define_method(cField, "dynamic_width", field_dynamic_width, 0);
5002
+ rb_define_method(cField, "max", field_max, 0);
5003
+ rb_define_method(cField, "set_max", field_set_max, 1);
5004
+ rb_define_method(cField, "max=", field_set_max, 1);
5005
+ rb_define_method(cField, "set_type", field_set_type, -1);
5006
+
5007
+ cForm = rb_define_class_under(mCurses, "Form", rb_cData);
5008
+ rb_define_alloc_func(cForm, form_s_allocate);
5009
+ rb_define_method(cForm, "initialize", form_initialize, 1);
5010
+ rb_define_method(cForm, "post", form_post, 0);
5011
+ rb_define_method(cForm, "unpost", form_unpost, 0);
5012
+ rb_define_method(cForm, "driver", form_driver_m, 1);
5013
+ rb_define_method(cForm, "set_win", form_set_win, 1);
5014
+ rb_define_method(cForm, "set_sub", form_set_sub, 1);
5015
+ rb_define_method(cForm, "scale", form_scale, 0);
3995
5016
  #endif
3996
5017
 
3997
5018
  #define rb_curses_define_error(c) do { \
@@ -5482,6 +6503,17 @@ Init_curses(void)
5482
6503
  #endif
5483
6504
 
5484
6505
  #ifdef HAVE_MENU
6506
+ rb_curses_define_const(O_ONEVALUE);
6507
+ rb_curses_define_const(O_SHOWDESC);
6508
+ rb_curses_define_const(O_ROWMAJOR);
6509
+ rb_curses_define_const(O_IGNORECASE);
6510
+ rb_curses_define_const(O_SHOWMATCH);
6511
+ rb_curses_define_const(O_NONCYCLIC);
6512
+ #ifdef O_MOUSE_MENU
6513
+ rb_curses_define_const(O_MOUSE_MENU);
6514
+ #endif
6515
+ rb_curses_define_const(O_SELECTABLE);
6516
+
5485
6517
  rb_curses_define_const(REQ_LEFT_ITEM);
5486
6518
  rb_curses_define_const(REQ_RIGHT_ITEM);
5487
6519
  rb_curses_define_const(REQ_UP_ITEM);
@@ -5500,5 +6532,93 @@ Init_curses(void)
5500
6532
  rb_curses_define_const(REQ_NEXT_MATCH);
5501
6533
  rb_curses_define_const(REQ_PREV_MATCH);
5502
6534
  #endif
6535
+
6536
+ #ifdef HAVE_FORM
6537
+ rb_curses_define_const(O_VISIBLE);
6538
+ rb_curses_define_const(O_ACTIVE);
6539
+ rb_curses_define_const(O_PUBLIC);
6540
+ rb_curses_define_const(O_EDIT);
6541
+ rb_curses_define_const(O_WRAP);
6542
+ rb_curses_define_const(O_BLANK);
6543
+ rb_curses_define_const(O_AUTOSKIP);
6544
+ rb_curses_define_const(O_NULLOK);
6545
+ rb_curses_define_const(O_PASSOK);
6546
+ rb_curses_define_const(O_STATIC);
6547
+ #ifdef O_DYNAMIC_JUSTIFY
6548
+ rb_curses_define_const(O_DYNAMIC_JUSTIFY);
6549
+ #endif
6550
+ #ifdef O_NO_LEFT_STRIP
6551
+ rb_curses_define_const(O_NO_LEFT_STRIP);
6552
+ #endif
6553
+
6554
+ rb_define_const(mCurses, "TYPE_ALPHA", INT2NUM(TYPE_CODE_ALPHA));
6555
+ rb_define_const(mCurses, "TYPE_ALNUM", INT2NUM(TYPE_CODE_ALNUM));
6556
+ rb_define_const(mCurses, "TYPE_ENUM", INT2NUM(TYPE_CODE_ENUM));
6557
+ rb_define_const(mCurses, "TYPE_INTEGER", INT2NUM(TYPE_CODE_INTEGER));
6558
+ rb_define_const(mCurses, "TYPE_NUMERIC", INT2NUM(TYPE_CODE_NUMERIC));
6559
+ rb_define_const(mCurses, "TYPE_REGEXP", INT2NUM(TYPE_CODE_REGEXP));
6560
+
6561
+ rb_curses_define_const(REQ_NEXT_PAGE);
6562
+ rb_curses_define_const(REQ_PREV_PAGE);
6563
+ rb_curses_define_const(REQ_FIRST_PAGE);
6564
+ rb_curses_define_const(REQ_LAST_PAGE);
6565
+
6566
+ rb_curses_define_const(REQ_NEXT_FIELD);
6567
+ rb_curses_define_const(REQ_PREV_FIELD);
6568
+ rb_curses_define_const(REQ_FIRST_FIELD);
6569
+ rb_curses_define_const(REQ_LAST_FIELD);
6570
+ rb_curses_define_const(REQ_SNEXT_FIELD);
6571
+ rb_curses_define_const(REQ_SPREV_FIELD);
6572
+ rb_curses_define_const(REQ_SFIRST_FIELD);
6573
+ rb_curses_define_const(REQ_SLAST_FIELD);
6574
+ rb_curses_define_const(REQ_LEFT_FIELD);
6575
+ rb_curses_define_const(REQ_RIGHT_FIELD);
6576
+ rb_curses_define_const(REQ_UP_FIELD);
6577
+ rb_curses_define_const(REQ_DOWN_FIELD);
6578
+
6579
+ rb_curses_define_const(REQ_NEXT_CHAR);
6580
+ rb_curses_define_const(REQ_PREV_CHAR);
6581
+ rb_curses_define_const(REQ_NEXT_LINE);
6582
+ rb_curses_define_const(REQ_PREV_LINE);
6583
+ rb_curses_define_const(REQ_NEXT_WORD);
6584
+ rb_curses_define_const(REQ_PREV_WORD);
6585
+ rb_curses_define_const(REQ_BEG_FIELD);
6586
+ rb_curses_define_const(REQ_END_FIELD);
6587
+ rb_curses_define_const(REQ_BEG_LINE);
6588
+ rb_curses_define_const(REQ_END_LINE);
6589
+ rb_curses_define_const(REQ_LEFT_CHAR);
6590
+ rb_curses_define_const(REQ_RIGHT_CHAR);
6591
+ rb_curses_define_const(REQ_UP_CHAR);
6592
+ rb_curses_define_const(REQ_DOWN_CHAR);
6593
+
6594
+ rb_curses_define_const(REQ_NEW_LINE);
6595
+ rb_curses_define_const(REQ_INS_CHAR);
6596
+ rb_curses_define_const(REQ_INS_LINE);
6597
+ rb_curses_define_const(REQ_DEL_CHAR);
6598
+ rb_curses_define_const(REQ_DEL_PREV);
6599
+ rb_curses_define_const(REQ_DEL_LINE);
6600
+ rb_curses_define_const(REQ_DEL_WORD);
6601
+ rb_curses_define_const(REQ_CLR_EOL);
6602
+ rb_curses_define_const(REQ_CLR_EOF);
6603
+ rb_curses_define_const(REQ_CLR_FIELD);
6604
+ rb_curses_define_const(REQ_OVL_MODE);
6605
+ rb_curses_define_const(REQ_INS_MODE);
6606
+ rb_curses_define_const(REQ_SCR_FLINE);
6607
+ rb_curses_define_const(REQ_SCR_BLINE);
6608
+ rb_curses_define_const(REQ_SCR_FPAGE);
6609
+ rb_curses_define_const(REQ_SCR_BPAGE);
6610
+ rb_curses_define_const(REQ_SCR_FHPAGE);
6611
+ rb_curses_define_const(REQ_SCR_BHPAGE);
6612
+ rb_curses_define_const(REQ_SCR_FCHAR);
6613
+ rb_curses_define_const(REQ_SCR_BCHAR);
6614
+ rb_curses_define_const(REQ_SCR_HFLINE);
6615
+ rb_curses_define_const(REQ_SCR_HBLINE);
6616
+ rb_curses_define_const(REQ_SCR_HFHALF);
6617
+ rb_curses_define_const(REQ_SCR_HBHALF);
6618
+
6619
+ rb_curses_define_const(REQ_VALIDATION);
6620
+ rb_curses_define_const(REQ_NEXT_CHOICE);
6621
+ rb_curses_define_const(REQ_PREV_CHOICE);
6622
+ #endif
5503
6623
  #undef rb_curses_define_const
5504
6624
  }