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

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