curses 1.2.4-x64-mingw32 → 1.2.6-x64-mingw32

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3942e9bb5b162a3b2f30e8a7382f50a55a707c48
4
- data.tar.gz: cac972460c75447444cf1350667540b59b5de241
2
+ SHA256:
3
+ metadata.gz: 7bb3dd270ad4f93cae57905835ba9b11c1a51fbdcb9ad69470fc3f7c499ab849
4
+ data.tar.gz: 3cf24f622f92200499a25741ac0af0ba63b044ac40885b8af32bb153bd895929
5
5
  SHA512:
6
- metadata.gz: '059c62ea6cad59b2b97fae03a13045bb39671eea3ffa60235c368ced1b944e8c8d741278769b6ad9d55e9b69cd20f88becfdae46ea6245fa4bb27672bc93a941'
7
- data.tar.gz: 9d2fdf8a47aef0570cdc17998e99736936e0f314085145920992efefbbffd1dd4178a5bc9f46d41639aaba174c41d2d6c94458f480c5f058bc79cd6063eaa3d2
6
+ metadata.gz: d2088ff0b2e17335c7f7a411551043c8fdeef4280f0dc9a82d03c24e173f63a70d5707bb65daa69e074818690ac820f6b721f99b65c5c81f110b830869fa5da4
7
+ data.tar.gz: 046d768a50c5f0e2d0b13cd1a1ea78a71ba065111dd132fc32db55967ea8647b1fa95de5f31b31804b9b66f8afd04d013b03542f0b95efc166c65469fac551b4
data/History.md CHANGED
@@ -1,5 +1,32 @@
1
+ ### 1.2.6 / 2019-01-09
2
+
3
+ New features:
4
+
5
+ * Add Curses::Menu and Curses::Item.
6
+
7
+ Bug fixes:
8
+
9
+ * Link PDCurses statically to avoid LoadError on mingw.
10
+ * Use https for documentation link. Pull request #43 by stomar.
11
+ * Fix typo in example code. Pull request #44 by stomar.
12
+
13
+ ### 1.2.5 / 2018-10-16
14
+
15
+ New features:
16
+
17
+ * Add mvderwin and derwin methods to Window. Pull request #37 by meschbach.
18
+ * Add documentation link. Pull request #39 by atshakil.
19
+
20
+ Bug fixes:
21
+
22
+ * Favor ncursesw over curses. Pull request #40 by DivineDominion.
23
+
1
24
  ### 1.2.4 / 2017-09-13
2
25
 
26
+ New features:
27
+
28
+ * Update PDCurses.
29
+
3
30
  Bug fixes:
4
31
 
5
32
  * Fix the path of pdcurses.dll for i386-mingw. (Issue #36)
data/README.md CHANGED
@@ -28,6 +28,10 @@ Or
28
28
 
29
29
  $ apt install libncursesw5-dev
30
30
 
31
+ ## Documentation
32
+
33
+ See [https://www.rubydoc.info/gems/curses](https://www.rubydoc.info/gems/curses).
34
+
31
35
  ## Developers
32
36
 
33
37
  After checking out the repo, run `bundle install` to install dependencies.
data/Rakefile CHANGED
@@ -28,11 +28,11 @@ namespace :build do
28
28
  sh "nmake -f vcwin32.mak clean all WIDE=Y DLL=Y"
29
29
  cp %w[pdcurses.dll pdcurses.lib], "../../#{RUBY_PLATFORM}/PDCurses"
30
30
  else
31
- sh "make -f mingwin32.mak clean all WIDE=Y DLL=Y"
32
- cp "pdcurses.dll", "../../x86-mingw32/PDCurses"
31
+ sh "make -f mingwin32.mak clean all WIDE=Y DLL=N"
32
+ cp "pdcurses.a", "../../x86-mingw32/PDCurses/libpdcurses.a"
33
33
 
34
- sh "make -f mingwin32.mak clean all _w64=1 WIDE=Y DLL=Y"
35
- cp "pdcurses.dll", "../../x64-mingw32/PDCurses"
34
+ sh "make -f mingwin32.mak clean all _w64=1 WIDE=Y DLL=N"
35
+ cp "pdcurses.a", "../../x64-mingw32/PDCurses/libpdcurses.a"
36
36
  end
37
37
  end
38
38
  end
@@ -71,14 +71,16 @@ Rake::ExtensionTask.new(spec.name, spec) do |ext|
71
71
  'x64-mingw32' => '--with-curses-lib=' +
72
72
  File.expand_path("vendor/x64-mingw32/PDCurses", __dir__)
73
73
  }
74
- ext.cross_compiling do |_spec|
75
- bin_file = "vendor/#{_spec.platform}/PDCurses/pdcurses.dll"
76
- _spec.files += [bin_file]
77
- stage_file = "#{ext.tmp_dir}/#{_spec.platform}/stage/#{bin_file}"
78
- stage_dir = File.dirname(stage_file)
79
- directory stage_dir
80
- file stage_file => [stage_dir, bin_file] do
81
- cp bin_file, stage_file
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
82
84
  end
83
85
  end
84
86
  end
data/curses.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new { |s|
2
2
  s.name = "curses"
3
- s.version = "1.2.4"
3
+ s.version = "1.2.6"
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"
data/ext/curses/curses.c CHANGED
@@ -20,12 +20,12 @@
20
20
  #include "ruby/io.h"
21
21
  #include "ruby/thread.h"
22
22
 
23
- #if defined(HAVE_NCURSES_H)
24
- # include <ncurses.h>
25
- #elif defined(HAVE_NCURSESW_CURSES_H)
23
+ #if defined(HAVE_NCURSESW_CURSES_H)
26
24
  # include <ncursesw/curses.h>
27
25
  #elif defined(HAVE_NCURSES_CURSES_H)
28
26
  # include <ncurses/curses.h>
27
+ #elif defined(HAVE_NCURSES_H)
28
+ # include <ncurses.h>
29
29
  #elif defined(HAVE_CURSES_COLR_CURSES_H)
30
30
  # ifdef HAVE_STDARG_PROTOTYPES
31
31
  # include <stdarg.h>
@@ -51,6 +51,16 @@
51
51
  # endif
52
52
  #endif
53
53
 
54
+ #if defined(HAVE_NCURSESW_MENU_H)
55
+ # include <ncursesw/menu.h>
56
+ #elif defined(HAVE_NCURSES_MENU_H)
57
+ # include <ncurses/menu.h>
58
+ #elif defined(HAVE_CURSES_MENU_H)
59
+ # include <curses/menu.h>
60
+ #elif defined(HAVE_MENU_H)
61
+ # include <menu.h>
62
+ #endif
63
+
54
64
  #ifdef HAVE_INIT_COLOR
55
65
  # define USE_COLOR 1
56
66
  #endif
@@ -70,12 +80,117 @@ static VALUE cPad;
70
80
  #ifdef USE_MOUSE
71
81
  static VALUE cMouseEvent;
72
82
  #endif
83
+ #ifdef HAVE_MENU
84
+ static VALUE cItem;
85
+ static VALUE cMenu;
86
+ #endif
87
+ static VALUE eError;
88
+ static VALUE eSystemError;
89
+ static VALUE eBadArgumentError;
90
+ static VALUE ePostedError;
91
+ static VALUE eConnectedError;
92
+ static VALUE eBadStateError;
93
+ static VALUE eNoRoomError;
94
+ static VALUE eNotPostedError;
95
+ static VALUE eUnknownCommandError;
96
+ static VALUE eNoMatchError;
97
+ static VALUE eNotSelectableError;
98
+ static VALUE eNotConnectedError;
99
+ static VALUE eRequestDeniedError;
100
+ static VALUE eInvalidFieldError;
101
+ static VALUE eCurrentError;
73
102
 
74
103
  static VALUE rb_stdscr;
75
104
 
76
105
  static rb_encoding *keyboard_encoding;
77
106
  static rb_encoding *terminal_encoding;
78
107
 
108
+ #ifndef E_OK
109
+ #define E_OK 0
110
+ #endif
111
+
112
+ static void
113
+ check_curses_error(int error)
114
+ {
115
+ switch (error) {
116
+ case E_OK:
117
+ break;
118
+ #ifdef E_SYSTEM_ERROR
119
+ case E_SYSTEM_ERROR:
120
+ rb_raise(eSystemError, "A system error occurred");
121
+ break;
122
+ #endif
123
+ #ifdef E_BAD_ARGUMENT
124
+ case E_BAD_ARGUMENT:
125
+ rb_raise(eBadArgumentError, "Incorrect or out-of-range argument");
126
+ break;
127
+ #endif
128
+ #ifdef E_POSTED
129
+ case E_POSTED:
130
+ rb_raise(ePostedError, "The menu has already been posted");
131
+ break;
132
+ #endif
133
+ #ifdef E_CONNECTED
134
+ case E_CONNECTED:
135
+ rb_raise(eConnectedError, "The field is already connected to a form");
136
+ break;
137
+ #endif
138
+ #ifdef E_BAD_STATE
139
+ case E_BAD_STATE:
140
+ rb_raise(eBadStateError, "Called from an initialization or termination function");
141
+ break;
142
+ #endif
143
+ #ifdef E_NO_ROOM
144
+ case E_NO_ROOM:
145
+ rb_raise(eNoRoomError, "Form is too large for its window");
146
+ break;
147
+ #endif
148
+ #ifdef E_NOT_POSTED
149
+ case E_NOT_POSTED:
150
+ rb_raise(eNotPostedError, "The menu has not been posted");
151
+ break;
152
+ #endif
153
+ #ifdef E_UNKNOWN_COMMAND
154
+ case E_UNKNOWN_COMMAND:
155
+ rb_raise(eUnknownCommandError, "Unknown command");
156
+ break;
157
+ #endif
158
+ #ifdef E_NO_MATCH
159
+ case E_NO_MATCH:
160
+ rb_raise(eNoMatchError, "Character failed to match");
161
+ break;
162
+ #endif
163
+ #ifdef E_NOT_SELECTABLE
164
+ case E_NOT_SELECTABLE:
165
+ rb_raise(eNotSelectableError, "The designated item cannot be selected");
166
+ break;
167
+ #endif
168
+ #ifdef E_NOT_CONNECTED
169
+ case E_NOT_CONNECTED:
170
+ rb_raise(eNotConnectedError, "No fields or items are connected");
171
+ break;
172
+ #endif
173
+ #ifdef E_REQUEST_DENIED
174
+ case E_REQUEST_DENIED:
175
+ rb_raise(eRequestDeniedError, "The request could not be processed");
176
+ break;
177
+ #endif
178
+ #ifdef E_INVALID_FIELD
179
+ case E_INVALID_FIELD:
180
+ rb_raise(eInvalidFieldError, "Contents of a field is not valid");
181
+ break;
182
+ #endif
183
+ #ifdef E_CURRENT
184
+ case E_CURRENT:
185
+ rb_raise(eCurrentError, "The field is the current field");
186
+ break;
187
+ #endif
188
+ default:
189
+ rb_raise(eError, "Unknown error");
190
+ break;
191
+ }
192
+ }
193
+
79
194
  struct windata {
80
195
  WINDOW *window;
81
196
  };
@@ -1589,6 +1704,38 @@ window_subwin(VALUE obj, VALUE height, VALUE width, VALUE top, VALUE left)
1589
1704
  return win;
1590
1705
  }
1591
1706
 
1707
+ #ifdef HAVE_DERWIN
1708
+ /*
1709
+ * Document-method: Curses::Window.derwin
1710
+ * call-seq: derwin(height, width, relative_top, relative_left)
1711
+ *
1712
+ * Construct a new subwindow with constraints of
1713
+ * +height+ lines, +width+ columns, begin at +top+ line, and begin +left+ most column
1714
+ * relative to the parent window.
1715
+ *
1716
+ */
1717
+ static VALUE
1718
+ window_derwin(VALUE obj, VALUE height, VALUE width, VALUE top, VALUE left)
1719
+ {
1720
+ struct windata *winp;
1721
+ WINDOW *window;
1722
+ VALUE win;
1723
+ int h, w, t, l;
1724
+
1725
+ h = NUM2INT(height);
1726
+ w = NUM2INT(width);
1727
+ t = NUM2INT(top);
1728
+ l = NUM2INT(left);
1729
+ GetWINDOW(obj, winp);
1730
+ window = derwin(winp->window, h, w, t, l);
1731
+ win = prep_window(rb_obj_class(obj), window);
1732
+
1733
+ return win;
1734
+ }
1735
+ #else
1736
+ #define window_derwin rb_f_notimplement
1737
+ #endif
1738
+
1592
1739
  /*
1593
1740
  * Document-method: Curses::Window.close
1594
1741
  *
@@ -1854,6 +2001,28 @@ window_move(VALUE obj, VALUE y, VALUE x)
1854
2001
  return Qnil;
1855
2002
  }
1856
2003
 
2004
+ #ifdef HAVE_MVDERWIN
2005
+ /*
2006
+ * Document-method: Curses::Window.move_relative
2007
+ * call-seq: move_relative(x,y)
2008
+ *
2009
+ * Moves the derived or subwindow inside its parent window. The screen-relative
2010
+ * parameters of the window are not changed.
2011
+ */
2012
+ static VALUE
2013
+ window_move_relative(VALUE obj, VALUE y, VALUE x)
2014
+ {
2015
+ struct windata *winp;
2016
+
2017
+ GetWINDOW(obj, winp);
2018
+ mvderwin(winp->window, NUM2INT(y), NUM2INT(x));
2019
+
2020
+ return Qnil;
2021
+ }
2022
+ #else
2023
+ #define window_move_relative rb_f_notimplement
2024
+ #endif
2025
+
1857
2026
  /*
1858
2027
  * Document-method: Curses::Window.setpos
1859
2028
  * call-seq: setpos(y, x)
@@ -2845,6 +3014,420 @@ pad_noutrefresh(VALUE obj, VALUE pminrow, VALUE pmincol, VALUE sminrow,
2845
3014
  }
2846
3015
  #endif /* HAVE_NEWPAD */
2847
3016
 
3017
+ #ifdef HAVE_MENU
3018
+ /*--------------------------- class Item ----------------------------*/
3019
+
3020
+ struct itemdata {
3021
+ ITEM *item;
3022
+ };
3023
+
3024
+ static void
3025
+ no_item(void)
3026
+ {
3027
+ rb_raise(rb_eRuntimeError, "already deleted item");
3028
+ }
3029
+
3030
+ #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
+ TypedData_Get_Struct((obj), struct itemdata, &itemdata_type, (itemp));\
3034
+ if ((itemp)->item == 0) no_item();\
3035
+ } while (0)
3036
+
3037
+ static void
3038
+ item_free(void *p)
3039
+ {
3040
+ struct itemdata *itemp = p;
3041
+ if (itemp->item) free_item(itemp->item);
3042
+ itemp->item = 0;
3043
+ xfree(itemp);
3044
+ }
3045
+
3046
+ static size_t
3047
+ item_memsize(const void *p)
3048
+ {
3049
+ const struct itemdata *itemp = p;
3050
+ size_t size = sizeof(*itemp);
3051
+ if (!itemp) return 0;
3052
+ if (itemp->item) size += sizeof(itemp->item);
3053
+ return size;
3054
+ }
3055
+
3056
+ static const rb_data_type_t itemdata_type = {
3057
+ "itemdata",
3058
+ {0, item_free, item_memsize,}
3059
+ };
3060
+
3061
+ /* returns a Curses::Item object */
3062
+ static VALUE
3063
+ item_s_allocate(VALUE class)
3064
+ {
3065
+ struct itemdata *itemp;
3066
+
3067
+ return TypedData_Make_Struct(class, struct itemdata, &itemdata_type, itemp);
3068
+ }
3069
+
3070
+ /*
3071
+ * Document-method: Curses::Item.new
3072
+ *
3073
+ * call-seq:
3074
+ * new(name, description)
3075
+ *
3076
+ * Construct a new Curses::Item.
3077
+ */
3078
+ static VALUE
3079
+ item_initialize(VALUE obj, VALUE name, VALUE description)
3080
+ {
3081
+ struct itemdata *itemp;
3082
+
3083
+ curses_init_screen();
3084
+ TypedData_Get_Struct(obj, struct itemdata, &itemdata_type, itemp);
3085
+ if (itemp->item) {
3086
+ rb_raise(rb_eRuntimeError, "already initialized item");
3087
+ }
3088
+ name = rb_str_export_to_enc(name, terminal_encoding);
3089
+ description = rb_str_export_to_enc(description, terminal_encoding);
3090
+ itemp->item = new_item(StringValueCStr(name),
3091
+ StringValueCStr(description));
3092
+ if (itemp->item == NULL) {
3093
+ check_curses_error(errno);
3094
+ }
3095
+
3096
+ return obj;
3097
+ }
3098
+
3099
+ static VALUE
3100
+ item_new(ITEM *item)
3101
+ {
3102
+ VALUE obj = item_s_allocate(cItem);
3103
+ struct itemdata *itemp;
3104
+
3105
+ TypedData_Get_Struct(obj, struct itemdata, &itemdata_type, itemp);
3106
+ itemp->item = item;
3107
+ return obj;
3108
+ }
3109
+
3110
+ static VALUE
3111
+ item_eq(VALUE obj, VALUE other)
3112
+ {
3113
+ struct itemdata *item1, *item2;
3114
+
3115
+ GetITEM(obj, item1);
3116
+ GetITEM(other, item2);
3117
+ return item1->item == item2->item ? Qtrue : Qfalse;
3118
+ }
3119
+
3120
+ static VALUE
3121
+ item_name_m(VALUE obj)
3122
+ {
3123
+ struct itemdata *itemp;
3124
+ const char *name;
3125
+
3126
+ GetITEM(obj, itemp);
3127
+ name = item_name(itemp->item);
3128
+ return rb_external_str_new_with_enc(name, strlen(name), terminal_encoding);
3129
+ }
3130
+
3131
+ static VALUE
3132
+ item_description_m(VALUE obj)
3133
+ {
3134
+ struct itemdata *itemp;
3135
+ const char *desc;
3136
+
3137
+ GetITEM(obj, itemp);
3138
+ desc = item_description(itemp->item);
3139
+ return rb_external_str_new_with_enc(desc, strlen(desc), terminal_encoding);
3140
+ }
3141
+
3142
+ struct menudata {
3143
+ MENU *menu;
3144
+ VALUE items;
3145
+ };
3146
+
3147
+ static void
3148
+ no_menu(void)
3149
+ {
3150
+ rb_raise(rb_eRuntimeError, "already deleted menu");
3151
+ }
3152
+
3153
+ #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
+ TypedData_Get_Struct((obj), struct menudata, &menudata_type, (menup));\
3157
+ if ((menup)->menu == 0) no_menu();\
3158
+ } while (0)
3159
+
3160
+ static void
3161
+ menu_gc_mark(void *p)
3162
+ {
3163
+ struct menudata *menup = p;
3164
+
3165
+ rb_gc_mark(menup->items);
3166
+ }
3167
+
3168
+ static void
3169
+ menu_free(void *p)
3170
+ {
3171
+ struct menudata *menup = p;
3172
+ ITEM **items = menu_items(menup->menu);
3173
+ if (menup->menu) free_menu(menup->menu);
3174
+ xfree(items);
3175
+ menup->menu = 0;
3176
+ menup->items = Qnil;
3177
+ xfree(menup);
3178
+ }
3179
+
3180
+ static size_t
3181
+ menu_memsize(const void *p)
3182
+ {
3183
+ const struct menudata *menup = p;
3184
+ size_t size = sizeof(*menup);
3185
+ if (!menup) return 0;
3186
+ if (menup->menu) size += sizeof(menup->menu);
3187
+ return size;
3188
+ }
3189
+
3190
+ static const rb_data_type_t menudata_type = {
3191
+ "menudata",
3192
+ {menu_gc_mark, menu_free, menu_memsize,}
3193
+ };
3194
+
3195
+ /* returns a Curses::Menu object */
3196
+ static VALUE
3197
+ menu_s_allocate(VALUE class)
3198
+ {
3199
+ struct menudata *menup;
3200
+
3201
+ return TypedData_Make_Struct(class, struct menudata, &menudata_type, menup);
3202
+ }
3203
+
3204
+ /*
3205
+ * Document-method: Curses::Menu.new
3206
+ *
3207
+ * call-seq:
3208
+ * new(name, description)
3209
+ *
3210
+ * Construct a new Curses::Menu.
3211
+ */
3212
+ static VALUE
3213
+ menu_initialize(VALUE obj, VALUE items)
3214
+ {
3215
+ struct menudata *menup;
3216
+ ITEM **menu_items;
3217
+ int i;
3218
+
3219
+ Check_Type(items, T_ARRAY);
3220
+ curses_init_screen();
3221
+ TypedData_Get_Struct(obj, struct menudata, &menudata_type, menup);
3222
+ if (menup->menu) {
3223
+ rb_raise(rb_eRuntimeError, "already initialized menu");
3224
+ }
3225
+ menu_items = ALLOC_N(ITEM *, RARRAY_LEN(items) + 1);
3226
+ for (i = 0; i < RARRAY_LEN(items); i++) {
3227
+ struct itemdata *itemp;
3228
+
3229
+ GetITEM(RARRAY_AREF(items, i), itemp);
3230
+ menu_items[i] = itemp->item;
3231
+ }
3232
+ menu_items[RARRAY_LEN(items)] = NULL;
3233
+ menup->menu = new_menu(menu_items);
3234
+ if (menup->menu == NULL) {
3235
+ check_curses_error(errno);
3236
+ }
3237
+ menup->items = rb_ary_dup(items);
3238
+
3239
+ return obj;
3240
+ }
3241
+
3242
+ /*
3243
+ * Document-method: Curses::Menu#post
3244
+ *
3245
+ * call-seq:
3246
+ * post
3247
+ *
3248
+ * Post the menu.
3249
+ */
3250
+ static VALUE
3251
+ menu_post(VALUE obj)
3252
+ {
3253
+ struct menudata *menup;
3254
+ int error;
3255
+
3256
+ GetMENU(obj, menup);
3257
+ error = post_menu(menup->menu);
3258
+ check_curses_error(error);
3259
+
3260
+ return obj;
3261
+ }
3262
+
3263
+ /*
3264
+ * Document-method: Curses::Menu#unpost
3265
+ *
3266
+ * call-seq:
3267
+ * unpost
3268
+ *
3269
+ * Unpost the menu.
3270
+ */
3271
+ static VALUE
3272
+ menu_unpost(VALUE obj)
3273
+ {
3274
+ struct menudata *menup;
3275
+ int error;
3276
+
3277
+ GetMENU(obj, menup);
3278
+ error = unpost_menu(menup->menu);
3279
+ check_curses_error(error);
3280
+
3281
+ return obj;
3282
+ }
3283
+
3284
+ /*
3285
+ * Document-method: Curses::Menu#driver
3286
+ *
3287
+ * call-seq:
3288
+ * driver(command)
3289
+ *
3290
+ * Perform the command on the menu.
3291
+ */
3292
+ static VALUE
3293
+ menu_driver_m(VALUE obj, VALUE command)
3294
+ {
3295
+ struct menudata *menup;
3296
+ int error;
3297
+
3298
+ GetMENU(obj, menup);
3299
+ error = menu_driver(menup->menu, NUM2INT(command));
3300
+ check_curses_error(error);
3301
+
3302
+ return obj;
3303
+ }
3304
+
3305
+ /*
3306
+ * Document-method: Curses::Menu#item_count
3307
+ *
3308
+ * call-seq:
3309
+ * item_count
3310
+ *
3311
+ * Returns the count of items in the menu.
3312
+ */
3313
+ static VALUE
3314
+ menu_item_count(VALUE obj)
3315
+ {
3316
+ struct menudata *menup;
3317
+
3318
+ GetMENU(obj, menup);
3319
+ return INT2NUM(item_count(menup->menu));
3320
+ }
3321
+
3322
+ /*
3323
+ * Document-method: Curses::Menu#items
3324
+ *
3325
+ * call-seq:
3326
+ * items
3327
+ *
3328
+ * Returns the items of the menu.
3329
+ */
3330
+ static VALUE
3331
+ menu_get_items(VALUE obj)
3332
+ {
3333
+ struct menudata *menup;
3334
+ ITEM **items;
3335
+ int count, i;
3336
+ VALUE ary;
3337
+
3338
+ GetMENU(obj, menup);
3339
+ items = menu_items(menup->menu);
3340
+ if (items == NULL) {
3341
+ return Qnil;
3342
+ }
3343
+ count = item_count(menup->menu);
3344
+ ary = rb_ary_new();
3345
+ for (i = 0; i < count; i++) {
3346
+ rb_ary_push(ary, item_new(items[i]));
3347
+ }
3348
+ return ary;
3349
+ }
3350
+
3351
+ /*
3352
+ * Document-method: Curses::Menu#items=
3353
+ *
3354
+ * call-seq:
3355
+ * items=(items)
3356
+ *
3357
+ * Returns the items of the menu.
3358
+ */
3359
+ static VALUE
3360
+ menu_set_items(VALUE obj, VALUE items)
3361
+ {
3362
+ struct menudata *menup;
3363
+ ITEM **old_items, **new_items;
3364
+ int i, error;
3365
+
3366
+ Check_Type(items, T_ARRAY);
3367
+ GetMENU(obj, menup);
3368
+ old_items = menu_items(menup->menu);
3369
+ new_items = ALLOC_N(ITEM*, RARRAY_LEN(items) + 1);
3370
+ for (i = 0; i < RARRAY_LEN(items); i++) {
3371
+ struct itemdata *itemp;
3372
+ GetITEM(RARRAY_AREF(items, i), itemp);
3373
+ new_items[i] = itemp->item;
3374
+ }
3375
+ new_items[RARRAY_LEN(items)] = NULL;
3376
+ error = set_menu_items(menup->menu, new_items);
3377
+ if (error != E_OK) {
3378
+ xfree(new_items);
3379
+ check_curses_error(error);
3380
+ return items;
3381
+ }
3382
+ xfree(old_items);
3383
+ menup->items = rb_ary_dup(items);
3384
+ return items;
3385
+ }
3386
+
3387
+ /*
3388
+ * Document-method: Curses::Menu#current_item
3389
+ *
3390
+ * call-seq:
3391
+ * current_item
3392
+ *
3393
+ * Returns the current item.
3394
+ */
3395
+ static VALUE
3396
+ menu_get_current_item(VALUE obj)
3397
+ {
3398
+ struct menudata *menup;
3399
+ ITEM *item;
3400
+
3401
+ GetMENU(obj, menup);
3402
+ item = current_item(menup->menu);
3403
+ if (item == NULL) {
3404
+ return Qnil;
3405
+ }
3406
+ return item_new(item);
3407
+ }
3408
+
3409
+ /*
3410
+ * Document-method: Curses::Menu#current_item=
3411
+ *
3412
+ * call-seq:
3413
+ * current_item=(item)
3414
+ *
3415
+ * Sets the current item.
3416
+ */
3417
+ static VALUE
3418
+ menu_set_current_item(VALUE obj, VALUE item)
3419
+ {
3420
+ struct menudata *menup;
3421
+ struct itemdata *itemp;
3422
+
3423
+ GetMENU(obj, menup);
3424
+ GetITEM(item, itemp);
3425
+ set_current_item(menup->menu, itemp->item);
3426
+ return item;
3427
+ }
3428
+
3429
+ #endif /* HAVE_MENU */
3430
+
2848
3431
  /*
2849
3432
  * Document-method: Curses.keyboard_encoding
2850
3433
  * call-seq: Curses.keyboard_encoding
@@ -3311,6 +3894,7 @@ Init_curses(void)
3311
3894
  rb_define_alloc_func(cWindow, window_s_allocate);
3312
3895
  rb_define_method(cWindow, "initialize", window_initialize, 4);
3313
3896
  rb_define_method(cWindow, "subwin", window_subwin, 4);
3897
+ rb_define_method(cWindow, "derwin", window_derwin, 4);
3314
3898
  rb_define_method(cWindow, "close", window_close, 0);
3315
3899
  rb_define_method(cWindow, "clear", window_clear, 0);
3316
3900
  rb_define_method(cWindow, "erase", window_erase, 0);
@@ -3325,6 +3909,7 @@ Init_curses(void)
3325
3909
  rb_define_method(cWindow, "line_touched?", window_line_touched, 1);
3326
3910
  rb_define_method(cWindow, "box", window_box, -1);
3327
3911
  rb_define_method(cWindow, "move", window_move, 2);
3912
+ rb_define_method(cWindow, "move_relative", window_move_relative, 2);
3328
3913
  rb_define_method(cWindow, "setpos", window_setpos, 2);
3329
3914
  #if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET)
3330
3915
  rb_define_method(cWindow, "color_set", window_color_set, 1);
@@ -3388,6 +3973,47 @@ Init_curses(void)
3388
3973
  rb_undef_method(cPad, "subwin");
3389
3974
  #endif
3390
3975
 
3976
+ #ifdef HAVE_MENU
3977
+ cItem = rb_define_class_under(mCurses, "Item", rb_cData);
3978
+ rb_define_alloc_func(cItem, item_s_allocate);
3979
+ rb_define_method(cItem, "initialize", item_initialize, 2);
3980
+ rb_define_method(cItem, "==", item_eq, 1);
3981
+ rb_define_method(cItem, "name", item_name_m, 0);
3982
+ rb_define_method(cItem, "description", item_description_m, 0);
3983
+
3984
+ cMenu = rb_define_class_under(mCurses, "Menu", rb_cData);
3985
+ rb_define_alloc_func(cMenu, menu_s_allocate);
3986
+ rb_define_method(cMenu, "initialize", menu_initialize, 1);
3987
+ rb_define_method(cMenu, "post", menu_post, 0);
3988
+ rb_define_method(cMenu, "unpost", menu_unpost, 0);
3989
+ rb_define_method(cMenu, "driver", menu_driver_m, 1);
3990
+ rb_define_method(cMenu, "item_count", menu_item_count, 0);
3991
+ rb_define_method(cMenu, "items", menu_get_items, 0);
3992
+ rb_define_method(cMenu, "items=", menu_set_items, 1);
3993
+ rb_define_method(cMenu, "current_item", menu_get_current_item, 0);
3994
+ rb_define_method(cMenu, "current_item=", menu_set_current_item, 1);
3995
+ #endif
3996
+
3997
+ #define rb_curses_define_error(c) do { \
3998
+ e##c = rb_define_class_under(mCurses, #c, eError); \
3999
+ } while (0)
4000
+
4001
+ eError = rb_define_class_under(mCurses, "Error", rb_eStandardError);
4002
+ rb_curses_define_error(SystemError);
4003
+ rb_curses_define_error(BadArgumentError);
4004
+ rb_curses_define_error(PostedError);
4005
+ rb_curses_define_error(ConnectedError);
4006
+ rb_curses_define_error(BadStateError);
4007
+ rb_curses_define_error(NoRoomError);
4008
+ rb_curses_define_error(NotPostedError);
4009
+ rb_curses_define_error(UnknownCommandError);
4010
+ rb_curses_define_error(NoMatchError);
4011
+ rb_curses_define_error(NotSelectableError);
4012
+ rb_curses_define_error(NotConnectedError);
4013
+ rb_curses_define_error(RequestDeniedError);
4014
+ rb_curses_define_error(InvalidFieldError);
4015
+ rb_curses_define_error(CurrentError);
4016
+
3391
4017
  #define rb_curses_define_const(c) rb_define_const(mCurses,#c,CHTYPE2NUM(c))
3392
4018
 
3393
4019
  #ifdef USE_COLOR
@@ -4854,5 +5480,25 @@ Init_curses(void)
4854
5480
  rb_curses_define_const(PDC_KEY_MODIFIER_ALT);
4855
5481
  rb_curses_define_const(PDC_KEY_MODIFIER_NUMLOCK);
4856
5482
  #endif
5483
+
5484
+ #ifdef HAVE_MENU
5485
+ rb_curses_define_const(REQ_LEFT_ITEM);
5486
+ rb_curses_define_const(REQ_RIGHT_ITEM);
5487
+ rb_curses_define_const(REQ_UP_ITEM);
5488
+ rb_curses_define_const(REQ_DOWN_ITEM);
5489
+ rb_curses_define_const(REQ_SCR_ULINE);
5490
+ rb_curses_define_const(REQ_SCR_DLINE);
5491
+ rb_curses_define_const(REQ_SCR_DPAGE);
5492
+ rb_curses_define_const(REQ_SCR_UPAGE);
5493
+ rb_curses_define_const(REQ_FIRST_ITEM);
5494
+ rb_curses_define_const(REQ_LAST_ITEM);
5495
+ rb_curses_define_const(REQ_NEXT_ITEM);
5496
+ rb_curses_define_const(REQ_PREV_ITEM);
5497
+ rb_curses_define_const(REQ_TOGGLE_ITEM);
5498
+ rb_curses_define_const(REQ_CLEAR_PATTERN);
5499
+ rb_curses_define_const(REQ_BACK_PATTERN);
5500
+ rb_curses_define_const(REQ_NEXT_MATCH);
5501
+ rb_curses_define_const(REQ_PREV_MATCH);
5502
+ #endif
4857
5503
  #undef rb_curses_define_const
4858
5504
  }
@@ -59,7 +59,7 @@ if header_library
59
59
  getbkgd getnstr init isendwin keyname keypad resizeterm
60
60
  scrl set setscrreg ungetch addnwstr
61
61
  wattroff wattron wattrset wbkgd wbkgdset wdeleteln wgetnstr
62
- wresize wscrl wsetscrreg werase redrawwin waddnwstr
62
+ wresize wscrl wsetscrreg werase redrawwin waddnwstr mvderwin derwin
63
63
  touchwin untouchwin wtouchln is_linetouched is_wintouched
64
64
  def_prog_mode reset_prog_mode timeout wtimeout nodelay
65
65
  init_color wcolor_set use_default_colors assume_default_colors
@@ -141,6 +141,15 @@ if header_library
141
141
  $defs << '-DPDC_DLL_BUILD'
142
142
  end
143
143
 
144
+ if (have_header("ncursesw/menu.h") ||
145
+ have_header("ncurses/menu.h") ||
146
+ have_header("curses/menu.h") ||
147
+ have_header("menu.h")) &&
148
+ (have_library("menuw", "new_menu") ||
149
+ have_library("menu", "new_menu"))
150
+ $defs << '-DHAVE_MENU'
151
+ end
152
+
144
153
  if RUBY_VERSION >= '2.1'
145
154
  create_header
146
155
  create_makefile("curses")
data/lib/2.3/curses.so CHANGED
Binary file
data/lib/2.4/curses.so CHANGED
Binary file
data/lib/2.5/curses.so ADDED
Binary file
data/lib/2.6/curses.so ADDED
Binary file
data/lib/curses.rb CHANGED
@@ -21,3 +21,76 @@ end
21
21
  if pdcurses_bundled
22
22
  Curses.keyboard_encoding = Encoding::UTF_8
23
23
  end
24
+
25
+ if defined?(Curses::Menu)
26
+ class Curses::Menu
27
+ def left_item
28
+ driver(Curses::REQ_LEFT_ITEM)
29
+ end
30
+
31
+ def right_item
32
+ driver(Curses::REQ_RIGHT_ITEM)
33
+ end
34
+
35
+ def up_item
36
+ driver(Curses::REQ_UP_ITEM)
37
+ end
38
+
39
+ def down_item
40
+ driver(Curses::REQ_DOWN_ITEM)
41
+ end
42
+
43
+ def scroll_up_line
44
+ driver(Curses::REQ_SCR_ULINE)
45
+ end
46
+
47
+ def scroll_down_line
48
+ driver(Curses::REQ_SCR_DLINE)
49
+ end
50
+
51
+ def scroll_up_page
52
+ driver(Curses::REQ_SCR_UPAGE)
53
+ end
54
+
55
+ def scroll_down_page
56
+ driver(Curses::REQ_SCR_DPAGE)
57
+ end
58
+
59
+ def first_item
60
+ driver(Curses::REQ_FIRST_ITEM)
61
+ end
62
+
63
+ def last_item
64
+ driver(Curses::REQ_LAST_ITEM)
65
+ end
66
+
67
+ def next_item
68
+ driver(Curses::REQ_NEXT_ITEM)
69
+ end
70
+
71
+ def prev_item
72
+ driver(Curses::REQ_PREV_ITEM)
73
+ end
74
+
75
+ def toggle_item
76
+ driver(Curses::REQ_TOGGLE_ITEM)
77
+ end
78
+
79
+ def clear_pattern
80
+ driver(Curses::REQ_CLEAR_PATTERN)
81
+ end
82
+
83
+ def back_pattern
84
+ driver(Curses::REQ_BACK_PATTERN)
85
+ end
86
+
87
+ def next_match
88
+ driver(Curses::REQ_NEXT_MATCH)
89
+ end
90
+
91
+ def prev_match
92
+ driver(Curses::REQ_PREV_MATCH)
93
+ end
94
+ end
95
+ end
96
+
data/sample/menu.rb ADDED
@@ -0,0 +1,32 @@
1
+ require "curses"
2
+
3
+ Curses.init_screen
4
+ Curses.cbreak
5
+ Curses.noecho
6
+ Curses.stdscr.keypad = true
7
+ at_exit do
8
+ Curses.cloes_screen
9
+ end
10
+
11
+ menu = Curses::Menu.new([
12
+ Curses::Item.new("Apple", "Red fruit"),
13
+ Curses::Item.new("Orange", "Orange fruit"),
14
+ Curses::Item.new("Banana", "Yellow fruit")
15
+ ])
16
+ menu.post
17
+
18
+ while ch = Curses.getch
19
+ begin
20
+ case ch
21
+ when Curses::KEY_UP, ?k
22
+ menu.up_item
23
+ when Curses::KEY_DOWN, ?j
24
+ menu.down_item
25
+ else
26
+ break
27
+ end
28
+ rescue Curses::RequestDeniedError
29
+ end
30
+ end
31
+
32
+ menu.unpost
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curses
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.6
5
5
  platform: x64-mingw32
6
6
  authors:
7
7
  - Shugo Maeda
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-13 00:00:00.000000000 Z
12
+ date: 2019-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -75,16 +75,17 @@ files:
75
75
  - ext/curses/curses.c
76
76
  - ext/curses/depend
77
77
  - ext/curses/extconf.rb
78
- - lib/2.2/curses.so
79
78
  - lib/2.3/curses.so
80
79
  - lib/2.4/curses.so
80
+ - lib/2.5/curses.so
81
+ - lib/2.6/curses.so
81
82
  - lib/curses.rb
82
83
  - sample/hello.rb
84
+ - sample/menu.rb
83
85
  - sample/mouse.rb
84
86
  - sample/rain.rb
85
87
  - sample/view.rb
86
88
  - sample/view2.rb
87
- - vendor/x64-mingw32/PDCurses/pdcurses.dll
88
89
  homepage: https://github.com/ruby/curses
89
90
  licenses:
90
91
  - Ruby
@@ -98,18 +99,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
99
  requirements:
99
100
  - - ">="
100
101
  - !ruby/object:Gem::Version
101
- version: '2.2'
102
+ version: '2.3'
102
103
  - - "<"
103
104
  - !ruby/object:Gem::Version
104
- version: '2.5'
105
+ version: 2.7.dev
105
106
  required_rubygems_version: !ruby/object:Gem::Requirement
106
107
  requirements:
107
108
  - - ">="
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
111
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.6.12
112
+ rubygems_version: 3.0.1
113
113
  signing_key:
114
114
  specification_version: 4
115
115
  summary: A Ruby binding for curses, ncurses, and PDCurses. curses is an extension
data/lib/2.2/curses.so DELETED
Binary file