やすしです。

signal_setup_arg()への patchです。

- rubyの世界を汚さない。
- 関数を直接呼ぶ。(superしない)
- add-onの widgetからでも簡単に付け足せる。
- add-onと coreでの差が無い。
- limitがない(fixed sizeの arrayとかじゃない)

が、満せてると自分では思うんですが‥。

すべての singalを試していないので、testしていただければ助かります。

御意見を頂ければ幸いです。
--
          yashi

diff -u --new-file --recursive gtk/src/init.c gtk-new/src/init.c --- gtk/src/init.c Thu Mar 30 15:52:46 2000 +++ gtk-new/src/init.c Mon May 15 21:02:44 2000 @@ -14,6 +14,7 @@ #include "global.h" EXTERN VALUE rb_argv, rb_argv0; +GHashTable *arg_setup_func_table; static void gtkerr(mesg) @@ -22,6 +23,12 @@ rb_raise(rb_eRuntimeError, "%s", mesg); } +static gint +comp_func(gconstpointer a, gconstpointer b) +{ + return a == b ? TRUE : FALSE; +} + void Init_gtk() { @@ -30,9 +37,6 @@ gtk_set_locale(); - Init_gtk_gtk(); - Init_gtk_gdk(); - argc = RARRAY(rb_argv)->len; argv = ALLOCA_N(char*,argc+1); argv[0] = STR2CSTR(rb_argv0); @@ -45,6 +49,17 @@ } } argc++; + + gtk_init(&argc, &argv); + + /* initialize hash table for signal id and argument setup function + since signal id is guint, this hash use direct hash func. + this has to be setup befor Init_gtk_gtk() yashi May 15, 2000 */ + arg_setup_func_table = g_hash_table_new(g_direct_hash, comp_func); + + Init_gtk_gtk(); + Init_gtk_gdk(); + { /* Gdk modifies sighandlers, sigh */ #ifdef NT @@ -66,8 +81,6 @@ sigfunc[5] = signal(SIGPIPE, SIG_IGN); sigfunc[6] = signal(SIGTERM, SIG_IGN); #endif - - gtk_init(&argc, &argv); #ifdef NT signal(SIGINT, sigfunc[0]); diff -u --new-file --recursive gtk/src/rbgtk.h gtk-new/src/rbgtk.h --- gtk/src/rbgtk.h Thu Mar 30 17:19:28 2000 +++ gtk-new/src/rbgtk.h Mon May 15 20:36:26 2000 @@ -29,6 +29,8 @@ #define RGTEST(v) (((VALUE)(v) != Qnil) && ((VALUE)(v) != Qfalse)) +extern GHashTable *arg_setup_func_table; + extern void notimplemented _((void)) NORETURN; extern VALUE glist2ary(GList* list); diff -u --new-file --recursive gtk/src/rbgtkclist.c gtk-new/src/rbgtkclist.c --- gtk/src/rbgtkclist.c Thu Mar 30 17:46:47 2000 +++ gtk-new/src/rbgtkclist.c Mon May 15 22:06:52 2000 @@ -655,8 +655,25 @@ return (retval==GTK_VISIBILITY_NONE) ? Qnil : INT2NUM(retval); } +static void +signal_args_setup_select_row(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + if (GTK_VALUE_POINTER(params[2])) + rb_ary_push(args, make_gdkevent(GTK_VALUE_POINTER(params[2]))); + else + rb_ary_push(args, Qnil); + return; +} + + void Init_gtk_clist() { + GtkType clist; + gCList = rb_define_class_under(mGtk, "CList", gContainer); /* Signals */ @@ -764,7 +781,16 @@ rb_define_method(gCList, "vadjustment", clist_get_vadjustment, 0); rb_define_method(gCList, "get_vadjustment", clist_get_vadjustment, 0); rb_define_method(gCList, "row_is_visible", clist_row_is_visible, 1); + + /* argument handler for singnals */ + clist = gtk_clist_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("select_row", clist), + signal_args_setup_select_row); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("unselect_row", clist), + signal_args_setup_select_row); - /* child initialization */ - Init_gtk_ctree(); + /* child initialization */ + Init_gtk_ctree(); } diff -u --new-file --recursive gtk/src/rbgtkeditable.c gtk-new/src/rbgtkeditable.c --- gtk/src/rbgtkeditable.c Thu Mar 30 16:17:45 2000 +++ gtk-new/src/rbgtkeditable.c Mon May 15 21:50:53 2000 @@ -193,8 +193,116 @@ return INT2NUM(GTK_EDITABLE(get_widget(self))->selection_end_pos); } +static void +signal_setup_insert_text(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, rb_str_new(GTK_VALUE_STRING(params[0]), + GTK_VALUE_INT(params[1]))); + rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[2]))); + + return; +} + +static void +signal_setup_delete_text(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + + return; +} + +static void +signal_setup_set_editable(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, GTK_VALUE_BOOL(params[0])? Qtrue: Qfalse); + return; +} + +static void +signal_setup_move_cursor(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_move_word(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); + return; +} + +static void +signal_setup_move_page(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_move_to_row(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_move_to_column(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_kill_char(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_kill_word(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + +static void +signal_setup_kill_line(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); + return; +} + void Init_gtk_editable() { + GtkType editable; + gEditable = rb_define_class_under(mGtk, "Editable", gWidget); rb_define_const(gEditable, "SIGNAL_ACTIVATE", rb_str_new2("activate")); @@ -222,6 +330,42 @@ rb_define_method(gEditable, "has_selection?", edit_has_selection_p, 0); rb_define_method(gEditable, "selection_start_pos", edit_selection_start_pos, 0); rb_define_method(gEditable, "selection_end_pos", edit_selection_end_pos, 0); + + /* argument handler for singnals */ + editable = gtk_editable_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("insert_text", editable), + signal_setup_insert_text); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("delete_text", editable), + signal_setup_delete_text); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("set_editable", editable), + signal_setup_set_editable); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_cursor", editable), + signal_setup_move_cursor); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_word", editable), + signal_setup_move_word); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_page", editable), + signal_setup_move_page); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_to_row", editable), + signal_setup_move_to_row); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_to_column", editable), + signal_setup_move_to_column); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("kill_char", editable), + signal_setup_kill_char); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("kill_word", editable), + signal_setup_kill_word); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("kill_line", editable), + signal_setup_kill_line); /* child initialization */ Init_gtk_entry(); diff -u --new-file --recursive gtk/src/rbgtkentry.c gtk-new/src/rbgtkentry.c --- gtk/src/rbgtkentry.c Thu Mar 30 16:17:45 2000 +++ gtk-new/src/rbgtkentry.c Mon May 15 21:52:06 2000 @@ -81,8 +81,19 @@ return self; } +static void +signal_args_setup_insert_position(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[0]))); + return; +} + void Init_gtk_entry() { + GtkType entry; + gEntry = rb_define_class_under(mGtk, "Entry", gEditable); rb_define_method(gEntry, "initialize", entry_initialize, 0); @@ -93,6 +104,12 @@ rb_define_method(gEntry, "get_text", entry_get_text, 0); rb_define_method(gEntry, "set_visibility", entry_set_visibility, 1); rb_define_method(gEntry, "set_max_length", entry_set_max_length, 1); + + /* argument handler for singnals */ + entry = gtk_entry_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("insert_position", entry), + signal_args_setup_insert_position); /* child initialize */ Init_gtk_spin_button(); diff -u --new-file --recursive gtk/src/rbgtknotebook.c gtk-new/src/rbgtknotebook.c --- gtk/src/rbgtknotebook.c Thu Mar 30 16:17:45 2000 +++ gtk-new/src/rbgtknotebook.c Mon May 15 22:10:18 2000 @@ -472,9 +472,20 @@ return get_value_from_gobject(GTK_OBJECT(label)); } +static void +signal_args_setup_switch_page(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, make_notepage((GtkNotebookPage*) GTK_VALUE_OBJECT(params[0]))); + rb_ary_push(args, INT2FIX(GTK_VALUE_INT(params[1]))); + return; +} void Init_gtk_notebook() { + GtkType notebook; + gNotebook = rb_define_class_under(mGtk, "Notebook", gContainer); rb_define_const(gNotebook, "SIGNAL_SWITCH_PAGE", rb_str_new2("switch_page")); @@ -525,4 +536,10 @@ rb_define_method(gNotePage, "child", notepage_child, 0); rb_define_method(gNotePage, "tab_label", notepage_tab_label, 0); rb_define_method(gNotePage, "menu_label", notepage_menu_label, 0); + + /* argument handler for singnals */ + notebook = gtk_notebook_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("switch_page", notebook), + signal_args_setup_switch_page); } diff -u --new-file --recursive gtk/src/rbgtkobject.c gtk-new/src/rbgtkobject.c --- gtk/src/rbgtkobject.c Thu Mar 30 15:52:48 2000 +++ gtk-new/src/rbgtkobject.c Mon May 15 22:10:02 2000 @@ -136,114 +136,20 @@ GtkArg *params1; int i; char *signame = rb_id2name(sig); + guint sig_id; + void (*setup_func)(VALUE, GtkArg*); - if (rb_obj_is_kind_of(obj, gWidget)) { - if (signal_comp(signame, "draw", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_gdkrectangle(GTK_VALUE_POINTER(params[0]))); - return; - } - if (signal_comp(signame, "size_request", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_grequisition(GTK_VALUE_POINTER(params[0]))); - return; - } - if (signal_comp(signame, "size_allocate", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_gallocation(GTK_VALUE_POINTER(params[0]))); - return; - } - } - if (rb_obj_is_kind_of(obj, gWindow)) { - if (signal_comp(signame, "move_resize", GTK_TYPE_WINDOW)) { - rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[0]))); - rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[1]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[3]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[4]))); - return; - } - if (signal_comp(signame, "set_focus", GTK_TYPE_WINDOW)) { - rb_ary_push(args, get_value_from_gobject(GTK_VALUE_POINTER(params[0]))); - return; - } - } - if (rb_obj_is_kind_of(obj, gEditable)) { - if (signal_comp(signame, "insert_text", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, rb_str_new(GTK_VALUE_STRING(params[0]), GTK_VALUE_INT(params[1]))); - rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[2]))); - return; - } - if (signal_comp(signame, "delete_text", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "set_editable", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, GTK_VALUE_BOOL(params[0])? Qtrue: Qfalse); - return; - } - if (signal_comp(signame, "move_cursor", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "move_word", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); - return; - } - if (signal_comp(signame, "move_page", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "move_to_row", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "move_to_column", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "kill_char", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "kill_word", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - if (signal_comp(signame, "kill_line", GTK_TYPE_EDITABLE)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - return; - } - } - if (rb_obj_is_kind_of(obj, gEntry)) { - if (signal_comp(signame, "insert_position", GTK_TYPE_ENTRY)) { - rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[0]))); - return; - } - } - if (rb_obj_is_kind_of(obj, gCList)) { - if (signal_comp(signame, "select_row", GTK_TYPE_CLIST) || - signal_comp(signame, "unselect_row", GTK_TYPE_CLIST)) { - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[0]))); - rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[1]))); - if (GTK_VALUE_POINTER(params[2])) - rb_ary_push(args, make_gdkevent(GTK_VALUE_POINTER(params[2]))); - else - rb_ary_push(args, Qnil); - return; - } - } - if (rb_obj_is_kind_of(obj, gNotebook)) { - if (signal_comp(signame, "switch_page", GTK_TYPE_NOTEBOOK)) { - rb_ary_push(args, make_notepage((GtkNotebookPage*) GTK_VALUE_OBJECT(params[0]))); - rb_ary_push(args, INT2FIX(GTK_VALUE_INT(params[1]))); - return; + sig_id = gtk_signal_lookup(signame, GTK_OBJECT_TYPE(get_gobject(obj))); + + setup_func = g_hash_table_lookup(arg_setup_func_table, (gpointer)sig_id); + if (setup_func) { + (*setup_func)(args, params); + } else { + params1 = params; + for (i=0; i<argc; i++) { + rb_ary_push(args, arg_to_value(params1)); + params1++; } - } - - params1 = params; - for (i=0; i<argc; i++) { - rb_ary_push(args, arg_to_value(params1)); - params1++; } } diff -u --new-file --recursive gtk/src/rbgtkwidget.c gtk-new/src/rbgtkwidget.c --- gtk/src/rbgtkwidget.c Thu Mar 30 16:17:47 2000 +++ gtk-new/src/rbgtkwidget.c Mon May 15 21:58:17 2000 @@ -843,33 +843,14 @@ return val; } -/* yashi -static VALUE -signal_setup_args(self, sig, argc, params, args) - VALUE obj; - ID sig; - int argc; - GtkArg *params; +static void +signal_setup_draw(args, params) VALUE args; + GtkArg *params; { - char *signame = rb_id2name(sig); - ID id_supre = rb_intern("super"); - - if (signal_comp(signame, "draw", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_gdkrectangle(GTK_VALUE_POINTER(params[0]))); - return; - } - if (signal_comp(signame, "size_request", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_grequisition(GTK_VALUE_POINTER(params[0]))); - return; - } - if (signal_comp(signame, "size_allocate", GTK_TYPE_WIDGET)) { - rb_ary_push(args, make_gallocation(GTK_VALUE_POINTER(params[0]))); - return; - } - rb_func_call(self, id_super, sig, argc, params, args); + rb_ary_push(args, make_gdkrectangle(GTK_VALUE_POINTER(params[0]))); + return; } -*/ #define DEFINE_EVENT_FUNC(EVENT,TYPE) \ static VALUE \ @@ -906,8 +887,37 @@ DEFINE_EVENT_FUNC(client_event, client) DEFINE_EVENT_FUNC(no_expose_event, any) +static void +signal_args_setup_draw(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, make_gdkrectangle(GTK_VALUE_POINTER(params[0]))); + return; +} + +static void +signal_args_setup_size_request(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, make_grequisition(GTK_VALUE_POINTER(params[0]))); + return; +} + +static void +signal_args_setup_size_allocate(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, make_gallocation(GTK_VALUE_POINTER(params[0]))); + return; +} + void Init_gtk_widget() { + GtkType widget; + gWidget = rb_define_class_under(mGtk, "Widget", gObject); /* @@ -1159,10 +1169,19 @@ rb_define_singleton_method(gWidget, "push_composite_child", widget_push_composite_child, 0); - /* private method */ - /* need rb_call_super, which hopefully implemented in Ruby 1.5 - yashi - rb_define_private_method(gWidget, "signal_setup_args", 4); - */ + /* argument handler for singnals */ + widget = gtk_widget_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("draw", widget), + signal_args_setup_draw); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("size_allocate", widget), + signal_args_setup_size_allocate); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("size_request", widget), + signal_args_setup_size_request); + + /* child initialization */ Init_gtk_calendar(); diff -u --new-file --recursive gtk/src/rbgtkwindow.c gtk-new/src/rbgtkwindow.c --- gtk/src/rbgtkwindow.c Thu Mar 30 17:39:36 2000 +++ gtk-new/src/rbgtkwindow.c Mon May 15 22:03:02 2000 @@ -165,8 +165,31 @@ return self; } +static void +signal_args_setup_move_resize(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[0]))); + rb_ary_push(args, INT2NUM(*GTK_RETLOC_INT(params[1]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[3]))); + rb_ary_push(args, INT2NUM(GTK_VALUE_INT(params[4]))); + return; +} + +static void +signal_args_setup_set_forcus(args, params) + VALUE args; + GtkArg *params; +{ + rb_ary_push(args, get_value_from_gobject(GTK_VALUE_POINTER(params[0]))); + return; +} + void Init_gtk_window() { + GtkType window; + gWindow = rb_define_class_under(mGtk, "Window", gBin); rb_define_const(gWindow, "SIGNAL_MOVE_RESIZE", rb_str_new2("move_resize")); @@ -191,6 +214,16 @@ rb_define_method(gWindow, "grab_remove", gwin_grab_remove, 0); rb_define_method(gWindow, "set_modal", gwin_set_modal, 1); rb_define_method(gWindow, "set_transient_for", gwin_set_transient_for, 1); + + /* argument handler for singnals */ + window = gtk_window_get_type(); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("move_resize", window), + signal_args_setup_move_resize); + g_hash_table_insert(arg_setup_func_table, + (gpointer)gtk_signal_lookup("set_forcus", window), + signal_args_setup_set_forcus); + /* child init */ Init_gtk_color_selection_dialog();