Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added a wrapper for ncurses menu functionality.

  • Loading branch information...
commit 294b422fa81e224c098df2f30af572c29d9562de 1 parent cc4d158
@eclubb eclubb authored
View
4 ext/ncurses/extconf.rb
@@ -127,5 +127,9 @@
if have_header("form.h")
have_library("form", "new_form")
end
+puts "checking for the menu library..."
+if have_header("menu.h")
+ have_library("menu", "new_menu")
+end
create_makefile('ncurses')
View
1,141 ext/ncurses/menu_wrap.c
@@ -0,0 +1,1141 @@
+/*
+ * This is a curses menu wrapper as part of ncurses-ruby.
+ * It borrows heavily from form_wrap.c.
+ * Contributed by Earle Clubb <eclubb@valcom.com>
+ * Valcom Inc. <http://www.valcom.com>
+ * Copyright 2007
+ *
+ * This module is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this module; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_MENU_H
+
+#include "menu_wrap.h"
+#include "ncurses_wrap.h"
+
+VALUE mMenu;
+VALUE cITEM;
+VALUE cMENU;
+
+void init_menu_err_codes(void)
+{
+ /* The routine succeeded. */
+ MENU_DEF_CONST(E_OK);
+ /* System error occurred (see errno). */
+ MENU_DEF_CONST(E_SYSTEM_ERROR);
+ /* Routine detected an incorrect or out-of-range argument. */
+ MENU_DEF_CONST(E_BAD_ARGUMENT);
+ /* The menu is already posted. */
+ MENU_DEF_CONST(E_POSTED);
+ /* Routine was called from an initialization or termination function. */
+ MENU_DEF_CONST(E_BAD_STATE);
+ /* Menu is too large for its window. */
+ MENU_DEF_CONST(E_NO_ROOM);
+ /* The menu has not been posted. */
+ MENU_DEF_CONST(E_NOT_POSTED);
+ /* The menu driver code saw an unknown request code. */
+ MENU_DEF_CONST(E_UNKNOWN_COMMAND);
+ /* Character failed to match. */
+ MENU_DEF_CONST(E_NO_MATCH);
+ /* The designated item cannot be selected. */
+ MENU_DEF_CONST(E_NOT_SELECTABLE);
+ /* No items are connected to the menu. */
+ MENU_DEF_CONST(E_NOT_CONNECTED);
+ /* The menu driver could not process the request.} */
+ MENU_DEF_CONST(E_REQUEST_DENIED);
+}
+
+
+/*
+ * Menu driver request characters - menu_driver(3x) man page
+ */
+void init_menu_req_constants(void)
+{
+ /* Move left to an item. */
+ MENU_DEF_CONST(REQ_LEFT_ITEM);
+ /* Move right to an item. */
+ MENU_DEF_CONST(REQ_RIGHT_ITEM);
+ /* Move up to an item. */
+ MENU_DEF_CONST(REQ_UP_ITEM);
+ /* Move down to an item. */
+ MENU_DEF_CONST(REQ_DOWN_ITEM);
+ /* Scroll up a line. */
+ MENU_DEF_CONST(REQ_SCR_ULINE);
+ /* Scroll down a line. */
+ MENU_DEF_CONST(REQ_SCR_DLINE);
+ /* Scroll up a page. */
+ MENU_DEF_CONST(REQ_SCR_UPAGE);
+ /* Scroll down a page. */
+ MENU_DEF_CONST(REQ_SCR_DPAGE);
+ /* Move to the first item. */
+ MENU_DEF_CONST(REQ_FIRST_ITEM);
+ /* Move to the last item. */
+ MENU_DEF_CONST(REQ_LAST_ITEM);
+ /* Move to the next item. */
+ MENU_DEF_CONST(REQ_NEXT_ITEM);
+ /* Move to the previous item. */
+ MENU_DEF_CONST(REQ_PREV_ITEM);
+ /* Select/deselect an item. */
+ MENU_DEF_CONST(REQ_TOGGLE_ITEM);
+ /* Clear the menu pattern buffer. */
+ MENU_DEF_CONST(REQ_CLEAR_PATTERN);
+ /* Delete the previous character from the pattern buffer. */
+ MENU_DEF_CONST(REQ_BACK_PATTERN);
+ /* Move to the next item matching the pattern match. */
+ MENU_DEF_CONST(REQ_NEXT_MATCH);
+ /* Move to the previous item matching the pattern match. */
+ MENU_DEF_CONST(REQ_PREV_MATCH);
+}
+
+
+/*
+ * Item options - mitem_opts(3x) man page
+ */
+void init_item_opts_constants(void)
+{
+ /* Item may be selected during menu processing. */
+ MENU_DEF_CONST(O_SELECTABLE);
+}
+
+
+/*
+ * Menu options - menu_opts(3x) man page
+ */
+void init_menu_opts_constants(void)
+{
+ /* Only one item can be selected for this menu. */
+ MENU_DEF_CONST(O_ONEVALUE);
+ /* Display the item descriptions when the menu is posted. */
+ MENU_DEF_CONST(O_SHOWDESC);
+ /* Display the menu in row-major order. */
+ MENU_DEF_CONST(O_ROWMAJOR);
+ /* Ignore the case when pattern-matching. */
+ MENU_DEF_CONST(O_IGNORECASE);
+ /* Move the cursor to within the item name while pattern-matching. */
+ MENU_DEF_CONST(O_SHOWMATCH);
+ /* Don’t wrap around next-item and previous-item, requests to the other end of the menu. */
+ MENU_DEF_CONST(O_NONCYCLIC);
+}
+
+
+/*
+ * ITEM wrapper
+ */
+static VALUE wrap_item(ITEM *item)
+{
+ if (item == 0) return Qnil;
+ {
+ VALUE items_hash = rb_iv_get(mMenu, "@items_hash");
+ VALUE item_address = INT2NUM((long)(item));
+ VALUE rb_item = rb_hash_aref(items_hash, item_address);
+
+ if (rb_item == Qnil)
+ {
+ rb_item = Data_Wrap_Struct(cITEM, 0, 0, item);
+ rb_iv_set(rb_item, "@destroyed", Qfalse);
+ rb_hash_aset(items_hash, item_address, rb_item);
+ }
+ return rb_item;
+ }
+}
+static ITEM *get_item(VALUE rb_item)
+{
+ ITEM *item;
+
+ if (rb_item == Qnil) return 0;
+ if (rb_iv_get(rb_item, "@destroyed") == Qtrue)
+ {
+ rb_raise(rb_eRuntimeError, "Attempt to access a destroyed item");
+ return 0;
+ }
+ Data_Get_Struct(rb_item, ITEM, item);
+ return item;
+}
+
+
+/*
+ * MENU wrapper
+ */
+static VALUE wrap_menu(MENU *menu)
+{
+ if (menu == 0) return Qnil;
+ {
+ VALUE menus_hash = rb_iv_get(mMenu, "@menus_hash");
+ VALUE menu_address = INT2NUM((long)(menu));
+ VALUE rb_menu = rb_hash_aref(menus_hash, menu_address);
+
+ if (rb_menu == Qnil)
+ {
+ rb_menu = Data_Wrap_Struct(cMENU, 0, 0, menu);
+ rb_iv_set(rb_menu, "@destroyed", Qfalse);
+ rb_hash_aset(menus_hash, menu_address, rb_menu);
+ }
+ return rb_menu;
+ }
+}
+static MENU *get_menu(VALUE rb_menu)
+{
+ MENU *menu;
+
+ if (rb_menu == Qnil) return 0;
+ if (rb_iv_get(rb_menu, "@destroyed") == Qtrue)
+ {
+ rb_raise(rb_eRuntimeError, "Attempt to access a destroyed menu");
+ return 0;
+ }
+ Data_Get_Struct(rb_menu, MENU, menu);
+ return menu;
+}
+
+
+/*
+ * Proc objects are registered using hashes (one for each type of hook)
+ * The key in the hash is the address of the ncurses "object" and the value is
+ * the Proc object.
+ */
+#define ITEM_INIT_HOOK 0
+#define ITEM_TERM_HOOK 1
+#define MENU_INIT_HOOK 2
+#define MENU_TERM_HOOK 3
+#define PROC_HASHES_COUNT 4
+static VALUE get_proc_hash(int hook)
+{
+ VALUE arr = rb_iv_get(mMenu, "@proc_hashes");
+ VALUE hash = rb_ary_entry(arr, (long)hook);
+
+ if (hash == Qnil)
+ rb_raise(rb_eRuntimeError, "Invalid proc hash.");
+ return hash;
+}
+
+/*
+ * Returns an existing Ruby Proc for a given owning "object" and hook type.
+ * Qnil will be returned if no Proc was associated with the owner
+ */
+static VALUE get_proc(void *owner, int hook)
+{
+ if (owner == 0) return Qnil;
+ {
+ VALUE owner_address = INT2NUM((long)(owner));
+ VALUE proc_hash = get_proc_hash(hook);
+ VALUE proc = rb_hash_aref(proc_hash, owner_address);
+
+ return proc;
+ }
+}
+
+/*
+ * Registers the Proc object with a given owner "object" and hook type.
+ * If proc is Qnil, the hook is unregistered instead.
+ */
+static void reg_proc(void *owner, int hook, VALUE proc)
+{
+ if (owner == NULL) return;
+ {
+ VALUE proc_hash = get_proc_hash(hook);
+ VALUE owner_address = INT2NUM((long)(owner));
+
+ if (proc == Qnil)
+ rb_hash_delete(proc_hash, owner_address);
+ else
+ rb_hash_aset(proc_hash, owner_address, proc);
+ }
+}
+
+
+/*
+ * Menu creation/destruction functions - menu_new(3X) man page
+ */
+static VALUE rbncurs_m_new_menu(VALUE dummy, VALUE rb_item_array)
+{
+ long n = RARRAY(rb_item_array)->len;
+ /* Will ncurses free this array? If not, must do it after calling free_menu(). */
+ ITEM **items = ALLOC_N(ITEM*, (n+1));
+ long i;
+
+ for (i=0; i<n; i++)
+ items[i] = get_item(rb_ary_entry(rb_item_array, i));
+ items[n] = NULL;
+ return wrap_menu(new_menu(items));
+}
+
+static VALUE rbncurs_c_free_menu(VALUE rb_menu)
+{
+ VALUE menus_hash = rb_iv_get(mMenu, "@menus_hash");
+ MENU *menu = get_menu(rb_menu);
+ VALUE menu_address = INT2NUM((long)(menu));
+
+ rb_funcall(menus_hash, rb_intern("delete"), 1, menu_address);
+ rb_iv_set(rb_menu, "@destroyed", Qtrue);
+ return INT2NUM(free_menu(menu));
+}
+static VALUE rbncurs_m_free_menu(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_free_menu(rb_menu); }
+
+
+/*
+ * Menu post/unpost functions - menu_post(3X) man page
+ */
+static VALUE rbncurs_c_post_menu(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(post_menu(menu));
+}
+static VALUE rbncurs_m_post_menu(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_post_menu(rb_menu); }
+
+static VALUE rbncurs_c_unpost_menu(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(unpost_menu(menu));
+}
+static VALUE rbncurs_m_unpost_menu(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_unpost_menu(rb_menu); }
+
+
+/*
+ * Menu driver - menu_driver(3X) man page
+ */
+static VALUE rbncurs_c_menu_driver(VALUE rb_menu, VALUE c)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(menu_driver(menu, NUM2INT(c)));
+}
+static VALUE rbncurs_m_menu_driver(VALUE dummy, VALUE rb_menu, VALUE c)
+{ return rbncurs_c_menu_driver(rb_menu, c); }
+
+
+/*
+ * Current menu item get/set functions - mitem_current(3X) man page
+ */
+static VALUE rbncurs_c_current_item(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return wrap_item(current_item(menu));
+}
+static VALUE rbncurs_m_current_item(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_current_item(rb_menu); }
+
+static VALUE rbncurs_c_set_current_item(VALUE rb_menu, VALUE rb_item)
+{
+ MENU *menu = get_menu(rb_menu);
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(set_current_item(menu, item));
+}
+static VALUE rbncurs_m_set_current_item(VALUE dummy, VALUE rb_menu, VALUE rb_item)
+{ return rbncurs_c_set_current_item(rb_menu, rb_item); }
+
+static VALUE rbncurs_c_top_row(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(top_row(menu));
+}
+static VALUE rbncurs_m_top_row(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_top_row(rb_menu); }
+
+static VALUE rbncurs_c_set_top_row(VALUE rb_menu, VALUE n)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_top_row(menu, NUM2INT(n)));
+}
+static VALUE rbncurs_m_set_top_row(VALUE dummy, VALUE rb_menu, VALUE rb_item)
+{ return rbncurs_c_set_top_row(rb_menu, rb_item); }
+
+static VALUE rbncurs_c_item_index(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(item_index(item));
+}
+static VALUE rbncurs_m_item_index(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_index(rb_item); }
+
+
+/*
+ * Item creation/destruction functions - mitem_new(3X) man page
+ */
+static VALUE rbncurs_m_new_item(VALUE dummy, VALUE name, VALUE description)
+{ return wrap_item(new_item(STR2CSTR(name), STR2CSTR(description))); }
+
+static VALUE rbncurs_c_free_item(VALUE rb_item)
+{
+ VALUE items_hash = rb_iv_get(mMenu, "@items_hash");
+ ITEM *item = get_item(rb_item);
+ VALUE item_address = INT2NUM((long)(item));
+ rb_funcall(items_hash, rb_intern("delete"), 1, item_address);
+ rb_iv_set(rb_item, "@destroyed", Qtrue);
+ return INT2NUM(free_item(item));
+}
+static VALUE rbncurs_m_free_item(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_free_item(rb_item); }
+
+
+/*
+ * Item-menu connection make/break functions - menu_items(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_items(VALUE rb_menu, VALUE rb_item_array)
+{
+ long n = RARRAY(rb_item_array)->len;
+ /* If ncurses does not free memory used by the previous array of strings, */
+ /* we will have to do it now. */
+ ITEM **items = ALLOC_N(ITEM*, (n+1));
+ long i;
+ MENU *menu = NULL;
+
+ for (i=0; i<n; i++)
+ items[i] = get_item(rb_ary_entry(rb_item_array, i));
+ items[n] = NULL;
+ menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_items(menu, items));
+}
+static VALUE rbncurs_m_set_menu_items(VALUE dummy, VALUE rb_menu, VALUE rb_item_array)
+{ return rbncurs_c_set_menu_items(rb_menu, rb_item_array); }
+
+static VALUE rbncurs_c_menu_items(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ ITEM **items = menu_items(menu);
+ VALUE arr = Qundef;
+ int i;
+
+ if (items == NULL)
+ rb_raise(rb_eRuntimeError, "Error retrieving menu items");
+ arr = rb_ary_new();
+ i=0;
+ while (items[i] != NULL)
+ rb_ary_push(arr, wrap_item(items[i++]));
+ return arr;
+}
+static VALUE rbncurs_m_menu_items(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_items(rb_menu); }
+
+static VALUE rbncurs_c_item_count(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(item_count(menu));
+}
+static VALUE rbncurs_m_item_count(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_item_count(rb_menu); }
+
+
+/*
+ * Item/menu hook get/set functions - menu_hook(3X) man page
+ */
+static void item_init_hook(MENU *menu)
+{
+ /* Find the Proc object associated with this menu */
+ VALUE proc = get_proc(menu, ITEM_INIT_HOOK);
+
+ if (proc != Qnil)
+ {
+ VALUE rb_menu = wrap_menu(menu);
+ rb_funcall(proc, rb_intern("call"), 1, rb_menu);
+ }
+}
+static VALUE rbncurs_c_set_item_init(VALUE rb_menu, VALUE proc)
+{
+ MENU *menu = NULL;
+
+ if (!rb_obj_is_kind_of(rb_menu, cMENU))
+ rb_raise(rb_eArgError, "arg1 must be a MENU object");
+ if (!rb_obj_is_kind_of(proc, rb_cProc))
+ rb_raise(rb_eArgError, "arg2 must be a Proc object");
+ menu = get_menu(rb_menu);
+ reg_proc(menu, ITEM_INIT_HOOK, proc);
+ if (proc != Qnil)
+ return INT2NUM(set_item_init(menu, item_init_hook));
+ else
+ return INT2NUM(set_item_init(menu, NULL));
+}
+static VALUE rbncurs_m_set_item_init(VALUE dummy, VALUE rb_menu, VALUE proc)
+{ return rbncurs_c_set_item_init(rb_menu, proc); }
+
+static VALUE rbncurs_c_item_init(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return get_proc(menu, ITEM_INIT_HOOK);
+}
+static VALUE rbncurs_m_item_init(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_item_init(rb_menu); }
+
+static void item_term_hook(MENU *menu)
+{
+ /* Find the Proc object associated with this menu */
+ VALUE proc = get_proc(menu, ITEM_TERM_HOOK);
+
+ if (proc != Qnil)
+ {
+ VALUE rb_menu = wrap_menu(menu);
+ rb_funcall(proc, rb_intern("call"), 1, rb_menu);
+ }
+}
+static VALUE rbncurs_c_set_item_term(VALUE rb_menu, VALUE proc)
+{
+ MENU *menu = NULL;
+
+ if (!rb_obj_is_kind_of(rb_menu, cMENU))
+ rb_raise(rb_eArgError, "arg1 must be a MENU object");
+ if (!rb_obj_is_kind_of(proc, rb_cProc))
+ rb_raise(rb_eArgError, "arg2 must be a Proc object");
+ menu = get_menu(rb_menu);
+ reg_proc(menu, ITEM_TERM_HOOK, proc);
+ if (proc != Qnil)
+ return INT2NUM(set_item_term(menu, item_term_hook));
+ else
+ return INT2NUM(set_item_term(menu, NULL));
+}
+static VALUE rbncurs_m_set_item_term(VALUE dummy, VALUE rb_menu, VALUE proc)
+{ return rbncurs_c_set_item_term(rb_menu, proc); }
+
+static VALUE rbncurs_c_item_term(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return get_proc(menu, ITEM_TERM_HOOK);
+}
+static VALUE rbncurs_m_item_term(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_item_term(rb_menu); }
+
+static void menu_init_hook(MENU *menu)
+{
+ /* Find the Proc object associated with this menu */
+ VALUE proc = get_proc(menu, MENU_INIT_HOOK);
+
+ if (proc != Qnil)
+ {
+ VALUE rb_menu = wrap_menu(menu);
+ rb_funcall(proc, rb_intern("call"), 1, rb_menu);
+ }
+}
+static VALUE rbncurs_c_set_menu_init(VALUE rb_menu, VALUE proc) {
+ MENU *menu = NULL;
+
+ if (!rb_obj_is_kind_of(rb_menu, cMENU))
+ rb_raise(rb_eArgError, "arg1 must be a MENU object");
+ if (!rb_obj_is_kind_of(proc, rb_cProc))
+ rb_raise(rb_eArgError, "arg2 must be a Proc object");
+ menu = get_menu(rb_menu);
+ reg_proc(menu, MENU_INIT_HOOK, proc);
+ if (proc != Qnil)
+ return INT2NUM(set_menu_init(menu, menu_init_hook));
+ else
+ return INT2NUM(set_menu_init(menu, NULL));
+}
+static VALUE rbncurs_m_set_menu_init(VALUE dummy, VALUE rb_menu, VALUE proc)
+{ return rbncurs_c_set_menu_init(rb_menu, proc); }
+
+static VALUE rbncurs_c_menu_init(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return get_proc(menu, MENU_INIT_HOOK);
+}
+static VALUE rbncurs_m_menu_init(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_init(rb_menu); }
+
+static void menu_term_hook(MENU *menu)
+{
+ /* Find the Proc object associated with this menu */
+ VALUE proc = get_proc(menu, MENU_TERM_HOOK);
+
+ if (proc != Qnil)
+ {
+ VALUE rb_menu = wrap_menu(menu);
+ rb_funcall(proc, rb_intern("call"), 1, rb_menu);
+ }
+}
+static VALUE rbncurs_c_set_menu_term(VALUE rb_menu, VALUE proc)
+{
+ MENU *menu = NULL;
+
+ if (!rb_obj_is_kind_of(rb_menu, cMENU))
+ rb_raise(rb_eArgError, "arg1 must be a MENU object");
+ if (!rb_obj_is_kind_of(proc, rb_cProc))
+ rb_raise(rb_eArgError, "arg2 must be a Proc object");
+ menu = get_menu(rb_menu);
+ reg_proc(menu, MENU_TERM_HOOK, proc);
+ if (proc != Qnil)
+ return INT2NUM(set_menu_term(menu, menu_term_hook));
+ else
+ return INT2NUM(set_menu_term(menu, NULL));
+}
+static VALUE rbncurs_m_set_menu_term(VALUE dummy, VALUE rb_menu, VALUE proc)
+{ return rbncurs_c_set_menu_term(rb_menu, proc); }
+
+static VALUE rbncurs_c_menu_term(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return get_proc(menu, MENU_TERM_HOOK);
+}
+static VALUE rbncurs_m_menu_term(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_term(rb_menu); }
+
+
+/*
+ * Item option get/set functions - mitem_opts(3X) man page
+ */
+static VALUE rbncurs_c_set_item_opts(VALUE rb_item, VALUE opts)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(set_item_opts(item, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_set_item_opts(VALUE dummy, VALUE rb_item, VALUE opts)
+{ return rbncurs_c_set_item_opts(rb_item, opts); }
+
+static VALUE rbncurs_c_item_opts_on(VALUE rb_item, VALUE opts)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(item_opts_on(item, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_item_opts_on(VALUE dummy, VALUE rb_item, VALUE opts)
+{ return rbncurs_c_item_opts_on(rb_item, opts); }
+
+static VALUE rbncurs_c_item_opts_off(VALUE rb_item, VALUE opts)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(item_opts_off(item, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_item_opts_off(VALUE dummy, VALUE rb_item, VALUE opts)
+{ return rbncurs_c_item_opts_off(rb_item, opts); }
+
+static VALUE rbncurs_c_item_opts(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(item_opts(item));
+}
+static VALUE rbncurs_m_item_opts(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_opts(rb_item); }
+
+
+/*
+ * Menu option get/set functions - menu_opts(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_opts(VALUE rb_menu, VALUE opts)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_opts(menu, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_set_menu_opts(VALUE dummy, VALUE rb_menu, VALUE opts)
+{ return rbncurs_c_set_menu_opts(rb_menu, opts); }
+
+static VALUE rbncurs_c_menu_opts_on(VALUE rb_menu, VALUE opts)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(menu_opts_on(menu, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_menu_opts_on(VALUE dummy, VALUE rb_menu, VALUE opts)
+{ return rbncurs_c_menu_opts_on(rb_menu, opts); }
+
+static VALUE rbncurs_c_menu_opts_off(VALUE rb_menu, VALUE opts)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(menu_opts_off(menu, NUM2INT(opts)));
+}
+static VALUE rbncurs_m_menu_opts_off(VALUE dummy, VALUE rb_menu, VALUE opts)
+{ return rbncurs_c_menu_opts_off(rb_menu, opts); }
+
+static VALUE rbncurs_c_menu_opts(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(menu_opts(menu));
+}
+static VALUE rbncurs_m_menu_opts(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_opts(rb_menu); }
+
+
+/*
+ * Printable menu request name handling functions - menu_requestname(3X) man page
+ */
+static VALUE rbncurs_c_menu_request_name(VALUE request)
+{
+ return rb_str_new2(menu_request_name(NUM2INT(request)));
+}
+static VALUE rbncurs_m_menu_request_name(VALUE dummy, VALUE request)
+{ return rbncurs_c_menu_request_name(request); }
+
+static VALUE rbncurs_c_menu_request_by_name(VALUE name)
+{
+ return INT2NUM(menu_request_by_name(STR2CSTR(name)));
+}
+static VALUE rbncurs_m_menu_request_by_name(VALUE dummy, VALUE name)
+{ return rbncurs_c_menu_request_by_name(name); }
+
+
+/*
+ * (Sub)window association make/break functions - menu_win(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_win(VALUE rb_menu, VALUE rb_win)
+{
+ MENU *menu = get_menu(rb_menu);
+ WINDOW *win = get_window(rb_win);
+ return INT2NUM(set_menu_win(menu, win));
+}
+static VALUE rbncurs_m_set_menu_win(VALUE dummy, VALUE rb_menu, VALUE rb_win)
+{ return rbncurs_c_set_menu_win(rb_menu, rb_win); }
+
+static VALUE rbncurs_c_menu_win(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return wrap_window(menu_win(menu));
+}
+static VALUE rbncurs_m_menu_win(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_win(rb_menu); }
+
+static VALUE rbncurs_c_set_menu_sub(VALUE rb_menu, VALUE rb_sub)
+{
+ MENU *menu = get_menu(rb_menu);
+ WINDOW *win = get_window(rb_sub);
+ return INT2NUM(set_menu_sub(menu, win));
+}
+static VALUE rbncurs_m_set_menu_sub(VALUE dummy, VALUE rb_menu, VALUE rb_sub)
+{ return rbncurs_c_set_menu_sub(rb_menu, rb_sub); }
+
+static VALUE rbncurs_c_menu_sub(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return wrap_window(menu_sub(menu));
+}
+static VALUE rbncurs_m_menu_sub(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_sub(rb_menu); }
+
+static VALUE rbncurs_c_scale_menu(VALUE rb_menu, VALUE rows, VALUE columns)
+{
+ MENU *menu = get_menu(rb_menu);
+
+ if (rb_obj_is_instance_of(rows, rb_cArray) != Qtrue ||
+ rb_obj_is_instance_of(columns, rb_cArray) != Qtrue)
+ {
+ rb_raise(rb_eArgError, "rows and columns arguments must be empty Arrays");
+ return Qnil;
+ }
+ else
+ {
+ int vals[2] = {0,0};
+ int result = scale_menu(menu, &vals[0],&vals[1]);
+
+ rb_ary_push(rows, INT2NUM(vals[0]));
+ rb_ary_push(columns, INT2NUM(vals[1]));
+ return INT2NUM(result);
+ }
+}
+static VALUE rbncurs_m_scale_menu(VALUE dummy, VALUE rb_menu, VALUE rows, VALUE columns)
+{ return rbncurs_c_scale_menu(rb_menu, rows, columns); }
+
+
+/*
+ * Menu cursor positioning functions - menu_cursor(3X) man page
+ */
+static VALUE rbncurs_c_pos_menu_cursor(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(pos_menu_cursor(menu));
+}
+static VALUE rbncurs_m_pos_menu_cursor(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_pos_menu_cursor(rb_menu); }
+
+
+/*
+ * Item name/description retrieval functions - mitem_name(3X) man page
+ */
+static VALUE rbncurs_c_item_name(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return rb_str_new2(item_name(item));
+}
+static VALUE rbncurs_m_item_name(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_name(rb_item); }
+
+static VALUE rbncurs_c_item_description(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return rb_str_new2(item_description(item));
+}
+static VALUE rbncurs_m_item_description(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_description(rb_item); }
+
+
+/*
+ * Item value get/set functions - mitem_value(3X) man page
+ */
+static VALUE rbncurs_c_set_item_value(VALUE rb_item, VALUE value)
+{
+ ITEM *item = get_item(rb_item);
+ return INT2NUM(set_item_value(item, RTEST(value)));
+}
+static VALUE rbncurs_m_set_item_value(VALUE dummy, VALUE rb_item, VALUE value)
+{ return rbncurs_c_set_item_value(rb_item, value); }
+
+static VALUE rbncurs_c_item_value(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return (item_value(item)) ? Qtrue: Qfalse;
+}
+static VALUE rbncurs_m_item_value(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_value(rb_item); }
+
+
+/*
+ * Item visibility retrieval function - mitem_visible(3X) man page
+ */
+static VALUE rbncurs_c_item_visible(VALUE rb_item)
+{
+ ITEM *item = get_item(rb_item);
+ return (item_visible(item)) ? Qtrue: Qfalse;
+}
+static VALUE rbncurs_m_item_visible(VALUE dummy, VALUE rb_item)
+{ return rbncurs_c_item_visible(rb_item); }
+
+
+/*
+ * Menu attribute get/set functions - menu_attributes(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_fore(VALUE rb_menu, VALUE attr)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_fore(menu, NUM2ULONG(attr)));
+}
+static VALUE rbncurs_m_set_menu_fore(VALUE dummy, VALUE rb_menu, VALUE attr)
+{ return rbncurs_c_set_menu_fore(rb_menu, attr); }
+
+static VALUE rbncurs_c_menu_fore(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return ULONG2NUM(menu_fore(menu));
+}
+static VALUE rbncurs_m_menu_fore(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_fore(rb_menu); }
+
+static VALUE rbncurs_c_set_menu_back(VALUE rb_menu, VALUE attr)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_back(menu, NUM2ULONG(attr)));
+}
+static VALUE rbncurs_m_set_menu_back(VALUE dummy, VALUE rb_menu, VALUE attr)
+{ return rbncurs_c_set_menu_back(rb_menu, attr); }
+
+static VALUE rbncurs_c_menu_back(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return ULONG2NUM(menu_back(menu));
+}
+static VALUE rbncurs_m_menu_back(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_back(rb_menu); }
+
+static VALUE rbncurs_c_set_menu_grey(VALUE rb_menu, VALUE attr)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_grey(menu, NUM2ULONG(attr)));
+}
+static VALUE rbncurs_m_set_menu_grey(VALUE dummy, VALUE rb_menu, VALUE attr)
+{ return rbncurs_c_set_menu_grey(rb_menu, attr); }
+
+static VALUE rbncurs_c_menu_grey(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return ULONG2NUM(menu_grey(menu));
+}
+static VALUE rbncurs_m_menu_grey(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_grey(rb_menu); }
+
+static VALUE rbncurs_c_set_menu_pad(VALUE rb_menu, VALUE pad)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_pad(menu, NUM2INT(pad)));
+}
+static VALUE rbncurs_m_set_menu_pad(VALUE dummy, VALUE rb_menu, VALUE pad)
+{ return rbncurs_c_set_menu_pad(rb_menu, pad); }
+
+static VALUE rbncurs_c_menu_pad(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(menu_pad(menu));
+}
+static VALUE rbncurs_m_menu_pad(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_pad(rb_menu); }
+
+
+/*
+ * Menu format get/set functions - menu_format(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_format(VALUE rb_menu, VALUE rows, VALUE cols)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_format(menu, NUM2INT(rows), NUM2INT(cols)));
+}
+static VALUE rbncurs_m_set_menu_format(VALUE dummy, VALUE rb_menu, VALUE rows, VALUE cols)
+{ return rbncurs_c_set_menu_format(rb_menu, rows, cols); }
+
+static VALUE rbncurs_c_menu_format(VALUE rb_menu, VALUE rows, VALUE cols)
+{
+ if (rb_obj_is_instance_of(rows, rb_cArray) != Qtrue ||
+ rb_obj_is_instance_of(cols, rb_cArray) != Qtrue)
+ {
+ rb_raise(rb_eArgError, "rows and cols arguments must be empty Arrays");
+ return Qnil;
+ }
+ else
+ {
+ MENU *menu = get_menu(rb_menu);
+ int vals[2] = {0,0};
+
+ menu_format(menu, &vals[0], &vals[1]);
+ rb_ary_push(rows, INT2NUM(vals[0]));
+ rb_ary_push(cols, INT2NUM(vals[1]));
+ return Qnil;
+ }
+}
+static VALUE rbncurs_m_menu_format(VALUE dummy, VALUE rb_menu, VALUE rows, VALUE cols)
+{ return rbncurs_c_menu_format(rb_menu, rows, cols); }
+
+
+/*
+ * Menu mark get/set functions - menu_mark(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_mark(VALUE rb_menu, VALUE value)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_mark(menu, STR2CSTR(value)));
+}
+static VALUE rbncurs_m_set_menu_mark(VALUE dummy, VALUE rb_field, VALUE value)
+{ return rbncurs_c_set_menu_mark(rb_field, value); }
+
+static VALUE rbncurs_c_menu_mark(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return rb_str_new2(menu_mark(menu));
+}
+static VALUE rbncurs_m_menu_mark(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_mark(rb_menu); }
+
+
+/*
+ * Menu pattern get/set functions - menu_pattern(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_pattern(VALUE rb_menu, VALUE pattern)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_pattern(menu, STR2CSTR(pattern)));
+}
+static VALUE rbncurs_m_set_menu_pattern(VALUE dummy, VALUE rb_menu, VALUE pattern)
+{ return rbncurs_c_set_menu_pattern(rb_menu, pattern); }
+
+static VALUE rbncurs_c_menu_pattern(VALUE rb_menu)
+{
+ MENU *menu = get_menu(rb_menu);
+ return rb_str_new2(menu_pattern(menu));
+}
+static VALUE rbncurs_m_menu_pattern(VALUE dummy, VALUE rb_menu)
+{ return rbncurs_c_menu_pattern(rb_menu); }
+
+
+/*
+ * Menu spacing get/set functions - menu_spacing(3X) man page
+ */
+static VALUE rbncurs_c_set_menu_spacing(VALUE rb_menu, VALUE spc_description,
+ VALUE spc_rows, VALUE spc_cols)
+{
+ MENU *menu = get_menu(rb_menu);
+ return INT2NUM(set_menu_spacing(menu, NUM2INT(spc_description),
+ NUM2INT(spc_rows), NUM2INT(spc_cols)));
+}
+static VALUE rbncurs_m_set_menu_spacing(VALUE dummy, VALUE rb_menu, VALUE spc_description,
+ VALUE spc_rows, VALUE spc_cols)
+{ return rbncurs_c_set_menu_spacing(rb_menu, spc_description, spc_rows, spc_cols); }
+
+static VALUE rbncurs_c_menu_spacing(VALUE rb_menu, VALUE spc_description,
+ VALUE spc_rows, VALUE spc_cols)
+{
+ if (rb_obj_is_instance_of(spc_description, rb_cArray) != Qtrue ||
+ rb_obj_is_instance_of(spc_rows, rb_cArray) != Qtrue ||
+ rb_obj_is_instance_of(spc_cols, rb_cArray) != Qtrue)
+ {
+ rb_raise(rb_eArgError, "spc_description, spc_rows, and spc_cols arguments must be empty Arrays");
+ return Qnil;
+ }
+ else
+ {
+ MENU *menu = get_menu(rb_menu);
+ int vals[3] = {0,0,0};
+
+ int result = menu_spacing(menu, &vals[0], &vals[1], &vals[2]);
+ rb_ary_push(spc_description, INT2NUM(vals[0]));
+ rb_ary_push(spc_rows, INT2NUM(vals[1]));
+ rb_ary_push(spc_cols, INT2NUM(vals[2]));
+ return INT2NUM(result);
+ }
+}
+static VALUE rbncurs_m_menu_spacing(VALUE dummy, VALUE rb_menu, VALUE spc_description,
+ VALUE spc_rows, VALUE spc_cols)
+{ return rbncurs_c_menu_spacing(rb_menu, spc_description, spc_rows, spc_cols); }
+
+
+/*
+ * Menu initialization function
+ */
+void init_menu(void)
+{
+ mMenu = rb_define_module_under(mNcurses, "Menu");
+
+ MENU_SNG_FUNC(current_item, 1);
+ MENU_SNG_FUNC(free_item, 1);
+ MENU_SNG_FUNC(free_menu, 1);
+ MENU_SNG_FUNC(item_count, 1);
+ MENU_SNG_FUNC(item_description, 1);
+ MENU_SNG_FUNC(item_index, 1);
+ MENU_SNG_FUNC(item_init, 1);
+ MENU_SNG_FUNC(item_name, 1);
+ MENU_SNG_FUNC(item_opts, 1);
+ MENU_SNG_FUNC(item_opts_off, 2);
+ MENU_SNG_FUNC(item_opts_on, 2);
+ MENU_SNG_FUNC(item_term, 1);
+ /* MENU_SNG_FUNC(item_userptr, 1); */
+ MENU_SNG_FUNC(item_value, 1);
+ MENU_SNG_FUNC(item_visible, 1);
+ MENU_SNG_FUNC(menu_back, 1);
+ MENU_SNG_FUNC(menu_driver, 2);
+ MENU_SNG_FUNC(menu_fore, 1);
+ MENU_SNG_FUNC(menu_format, 3);
+ MENU_SNG_FUNC(menu_grey, 1);
+ MENU_SNG_FUNC(menu_init, 1);
+ MENU_SNG_FUNC(menu_items, 1);
+ MENU_SNG_FUNC(menu_mark, 1);
+ MENU_SNG_FUNC(menu_opts, 1);
+ MENU_SNG_FUNC(menu_opts_off, 2);
+ MENU_SNG_FUNC(menu_opts_on, 2);
+ MENU_SNG_FUNC(menu_pad, 1);
+ MENU_SNG_FUNC(menu_pattern, 1);
+ MENU_SNG_FUNC(menu_request_by_name, 1);
+ MENU_SNG_FUNC(menu_request_name, 1);
+ MENU_SNG_FUNC(menu_sub, 1);
+ MENU_SNG_FUNC(menu_spacing, 4);
+ MENU_SNG_FUNC(menu_term, 1);
+ /* MENU_SNG_FUNC(menu_userptr, 1); */
+ MENU_SNG_FUNC(menu_win, 1);
+ MENU_SNG_FUNC(new_item, 2);
+ MENU_SNG_FUNC(new_menu, 1);
+ MENU_SNG_FUNC(pos_menu_cursor, 1);
+ MENU_SNG_FUNC(post_menu, 1);
+ MENU_SNG_FUNC(scale_menu, 3);
+ MENU_SNG_FUNC(set_current_item, 2);
+ MENU_SNG_FUNC(set_item_init, 2);
+ MENU_SNG_FUNC(set_item_opts, 2);
+ MENU_SNG_FUNC(set_item_term, 2);
+ /* MENU_SNG_FUNC(set_item_userptr, 2); */
+ MENU_SNG_FUNC(set_item_value, 2);
+ MENU_SNG_FUNC(set_menu_back, 2);
+ MENU_SNG_FUNC(set_menu_fore, 2);
+ MENU_SNG_FUNC(set_menu_format, 3);
+ MENU_SNG_FUNC(set_menu_grey, 2);
+ MENU_SNG_FUNC(set_menu_init, 2);
+ MENU_SNG_FUNC(set_menu_items, 2);
+ MENU_SNG_FUNC(set_menu_mark, 2);
+ MENU_SNG_FUNC(set_menu_opts, 2);
+ MENU_SNG_FUNC(set_menu_pad, 2);
+ MENU_SNG_FUNC(set_menu_pattern, 2);
+ MENU_SNG_FUNC(set_menu_sub, 2);
+ MENU_SNG_FUNC(set_menu_spacing, 4);
+ MENU_SNG_FUNC(set_menu_term, 2);
+ /* MENU_SNG_FUNC(set_menu_userptr, 2); */
+ MENU_SNG_FUNC(set_menu_win, 2);
+ MENU_SNG_FUNC(set_top_row, 2);
+ MENU_SNG_FUNC(top_row, 1);
+ MENU_SNG_FUNC(unpost_menu, 1);
+
+ init_menu_err_codes();
+ init_menu_req_constants();
+ init_menu_opts_constants();
+ init_item_opts_constants();
+
+ /* Hashes to store registered blocks (Proc) */
+ {
+ VALUE hashes = rb_iv_set(mMenu, "@proc_hashes", rb_ary_new());
+ int i;
+
+ for (i = 0; i < PROC_HASHES_COUNT; i++)
+ rb_ary_push(hashes, rb_hash_new());
+ }
+
+ /* Menus */
+ rb_iv_set(mMenu, "@menus_hash", rb_hash_new());
+ cMENU = rb_define_class_under(mMenu, "MENU", rb_cObject);
+ rb_define_singleton_method(cMENU, "new", (&rbncurs_m_new_menu), 1);
+
+ RB_CLASS_METH(cMENU, NULL, current_item, 0);
+ RB_CLASS_METH(cMENU, "free", free_menu, 0);
+ RB_CLASS_METH(cMENU, NULL, item_count, 0);
+ RB_CLASS_METH(cMENU, NULL, item_init, 0);
+ RB_CLASS_METH(cMENU, NULL, item_term, 0);
+ RB_CLASS_METH(cMENU, "back", menu_back, 0);
+ RB_CLASS_METH(cMENU, "driver", menu_driver, 1);
+ RB_CLASS_METH(cMENU, "fore", menu_fore, 0);
+ RB_CLASS_METH(cMENU, "format", menu_format, 2);
+ RB_CLASS_METH(cMENU, "grey", menu_grey, 0);
+ RB_CLASS_METH(cMENU, "init", menu_init, 0);
+ RB_CLASS_METH(cMENU, "items", menu_items, 0);
+ RB_CLASS_METH(cMENU, "mark", menu_mark, 0);
+ RB_CLASS_METH(cMENU, "opts", menu_opts, 0);
+ RB_CLASS_METH(cMENU, "opts_off", menu_opts_off, 1);
+ RB_CLASS_METH(cMENU, "opts_on", menu_opts_on, 1);
+ RB_CLASS_METH(cMENU, "pad", menu_pad, 0);
+ RB_CLASS_METH(cMENU, "pattern", menu_pattern, 0);
+ RB_CLASS_METH(cMENU, "sub", menu_sub, 0);
+ RB_CLASS_METH(cMENU, "spacing", menu_spacing, 3);
+ RB_CLASS_METH(cMENU, "term", menu_term, 0);
+ /* RB_CLASS_METH(cMENU, "userptr", menu_userptr, 0); */
+ RB_CLASS_METH(cMENU, "win", menu_win, 0);
+ RB_CLASS_METH(cMENU, "pos_cursor", pos_menu_cursor, 0);
+ RB_CLASS_METH(cMENU, "post", post_menu, 0);
+ RB_CLASS_METH(cMENU, "scale", scale_menu, 2);
+ RB_CLASS_METH(cMENU, "current_item=", set_current_item, 1);
+ RB_CLASS_METH(cMENU, "item_init=", set_item_init, 1);
+ RB_CLASS_METH(cMENU, "item_term=", set_item_term, 1);
+ RB_CLASS_METH(cMENU, "back=", set_menu_back, 1);
+ RB_CLASS_METH(cMENU, "fore=", set_menu_fore, 1);
+ RB_CLASS_METH(cMENU, "set_format", set_menu_format, 2);
+ RB_CLASS_METH(cMENU, "grey=", set_menu_grey, 1);
+ RB_CLASS_METH(cMENU, "init=", set_menu_init, 1);
+ RB_CLASS_METH(cMENU, "items=", set_menu_items, 1);
+ RB_CLASS_METH(cMENU, "mark=", set_menu_mark, 1);
+ RB_CLASS_METH(cMENU, "opts=", set_menu_opts, 1);
+ RB_CLASS_METH(cMENU, "pad=", set_menu_pad, 1);
+ RB_CLASS_METH(cMENU, "pattern=", set_menu_pattern, 1);
+ RB_CLASS_METH(cMENU, "sub=", set_menu_sub, 1);
+ RB_CLASS_METH(cMENU, "set_spacing", set_menu_spacing, 3);
+ RB_CLASS_METH(cMENU, "term=", set_menu_term, 1);
+ /* RB_CLASS_METH(cMENU, "userptr=", set_menu_userptr, 1); */
+ RB_CLASS_METH(cMENU, "win=", set_menu_win, 1);
+ RB_CLASS_METH(cMENU, "top_row=", set_top_row, 1);
+ RB_CLASS_METH(cMENU, NULL, top_row, 0);
+ RB_CLASS_METH(cMENU, "unpost", unpost_menu, 0);
+
+ /* Items */
+ rb_iv_set(mMenu, "@items_hash", rb_hash_new());
+ cITEM = rb_define_class_under(mMenu, "ITEM", rb_cObject);
+ rb_define_singleton_method(cITEM, "new", (&rbncurs_m_new_item), 2);
+
+ RB_CLASS_METH(cITEM, "free", free_item, 0);
+ RB_CLASS_METH(cITEM, "description", item_description, 0);
+ RB_CLASS_METH(cITEM, "index", item_index, 0);
+ RB_CLASS_METH(cITEM, "name", item_name, 0);
+ RB_CLASS_METH(cITEM, "opts", item_opts, 0);
+ RB_CLASS_METH(cITEM, "opts_off", item_opts_off, 1);
+ RB_CLASS_METH(cITEM, "opts_on", item_opts_on, 1);
+ /* RB_CLASS_METH(cITEM, "userptr", item_userptr, 0); */
+ RB_CLASS_METH(cITEM, "value", item_value, 0);
+ RB_CLASS_METH(cITEM, "visible?", item_visible, 0);
+ RB_CLASS_METH(cITEM, "opts=", set_item_opts, 1);
+ /* RB_CLASS_METH(cITEM, "userptr=", set_item_userptr, 1); */
+ RB_CLASS_METH(cITEM, "value=", set_item_value, 1);
+}
+
+#endif
View
49 ext/ncurses/menu_wrap.h
@@ -0,0 +1,49 @@
+/*
+ * This is a curses menu wrapper as part of ncurses-ruby.
+ * It borrows heavily from form_wrap.h.
+ * Contributed by Earle Clubb <eclubb@valcom.com>
+ * Valcom Inc. <http://www.valcom.com>
+ * Copyright 2007
+ *
+ * This module is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this module; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#if !defined(MENU_HH) && defined(HAVE_MENU_H)
+#define MENU_HH
+
+#include <menu.h>
+#include <ruby.h>
+
+extern VALUE mMenu;
+extern VALUE cITEM;
+extern VALUE cMENU;
+
+#define MENU_DEF_CONST(name) \
+ rb_define_const(mMenu, #name, INT2NUM(name));
+
+#define MENU_SNG_FUNC(name, nargs) \
+ rb_define_singleton_method(mMenu, #name, &rbncurs_m_ ## name, nargs)
+
+#define RB_CLASS_METH(class, alt_name, name, nargs) \
+ rb_define_method(class, #name, (&rbncurs_c_ ## name), nargs); \
+ if (alt_name != NULL) \
+ rb_define_method(class, alt_name, (&rbncurs_c_ ## name), nargs); \
+
+//void init_menu_req_constants(void);
+//void init_menu_opts_constants(void);
+void init_menu(void);
+
+#endif
View
7 ext/ncurses/ncurses_wrap.c
@@ -323,6 +323,10 @@ static VALUE rbncurs_winnstr(VALUE dummy, VALUE rb_win, VALUE rb_chstr, VALUE rb
#include "form_wrap.h" /* needs init_form */
#endif
+#ifdef HAVE_MENU_H
+#include "menu_wrap.h" /* needs init_menu */
+#endif
+
static
void
init_functions_0(void)
@@ -2730,4 +2734,7 @@ static void Init_ncurses_full(void)
#ifdef HAVE_FORM_H
init_form();
#endif
+#ifdef HAVE_MENU_H
+ init_menu();
+#endif
}
View
20 lib/ncurses.rb
@@ -127,6 +127,26 @@ def user_object=(obj)
class FIELDTYPE
end
end
+
+ module Menu
+ class MENU
+ attr_reader :user_object
+
+ # This placeholder replaces the menu_userptr function in curses
+ def user_object=(obj)
+ @user_object = obj
+ end
+ end
+
+ class ITEM
+ attr_reader :user_object
+
+ # This placeholder replaces the item_userptr function in curses
+ def user_object=(obj)
+ @user_object = obj
+ end
+ end
+ end
end
def Ncurses.inchnstr(str,n)
Ncurses.winchnstr(Ncurses.stdscr, str, n)
Please sign in to comment.
Something went wrong with that request. Please try again.