diff options
63 files changed, 7922 insertions, 1715 deletions
@@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 64f295c8e4..28e6e2617b 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,115 @@ +Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org> + + * gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment. + + * gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from, + this should eventually be done by gentypeinfo.el somewhen. + * gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays. + + * gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the + enum values of an enum type. + + * gtk/gtk.defs: + * gtk/gtkcurve.h: + * gtk/gtkobject.h: + * gtk/gtkprivate.h: + * gtk/gtkwidget.h: + * gtk/gtkenums.h: + brought enum/flags definitions in sync, added a few more enum + definitions for bindings and pattern matching. + + * some more macro and GtkType fixups in various places. + + * gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used + as a key-release modifier for the binding system. + +Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it + was a stale list pointer that is already present in GtkMenuShell. + + * gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal + GtkMenuShell::selection_done which is emitted after the menu shell + poped down again and all possible menu items have been activated. + +Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue + before activation of the menuitem, so the menu is actually taken off the + screen prior to any menu item activation. + + * gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation + for NULL nodes. + + * gtk/gtkwidget.h: + * gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop + the emission of the "add-accelerator" signal on a widget. this is + usefull to prevent accelerator installation on certain widgets. + + * gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu + labels left justified, by setting their alignment. stop accelerator + installation for the menu items, since we use dynamic menus. + +Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkmenufactory.c: adaptions to use the new accel groups. people + should *really* use GtkItemFactory. this is only for preserving source + compatibility where possible, use of GtkMenuFactory is deprecated as of + now. + + * gtk/gtkobject.h (gtk_object_class_add_user_signal): new function + to create user signals of type GTK_RUN_NO_RECURSE. don't know why i + missed this possibility when i added gtk_object_class_add_user_signal + in late january. + + * gtk/gtkmain.c (gtk_init): ignore subsequent function calls. + +Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkaccelgroup.h: + * gtk/gtkaccelgroup.c: new implementation of the accelerator concept. + + * gtk/gtkaccellabel.h: + * gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features + display of the accelerators associated with a certain widget. + + * gtk/gtkitemfactory.h: + * gtk/gtkitemfactory.c: new widget, item factory with automatic rc + parsing and accelerator handling. + + * gtk/gtkmenu.c (gtk_menu_reposition): new function to care for + positioning a menu. + (gtk_menu_map): removed the allocation code. + (gtk_menu_size_allocate): care for redrawing of children and resize + our widget->window correctly. + (gtk_menu_key_press): feature the new accelerator groups. + + * gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the + submenu if neccessary. + + * gtk/gtkmenuitem.c: + * gtk/gtkcheckmenuitem.c: + * gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label() + function variants. + + * gdk/gdk.c: + (gdk_keyval_from_name): + (gdk_keyval_name): new functions for keyval<->key-name associations. + (gdk_keyval_to_upper): + (gdk_keyval_to_lower): + (gdk_keyval_is_upper): + (gdk_keyval_is_lower): new functions to check/translate keyvalues with + regards to their cases. + +Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org> + + * gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a + widget's class path. + (gtk_widget_path): new function to calculate a widget's name path. + + * gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up + pattern matching, features reversed pattern matches. + Thu Jun 4 12:12:11 BST 1998 Tony Gale <gale@gtk.org> * examples/extract.sh, examples/extract.awk: @@ -3,8 +3,13 @@ For 1.1.0 release: gtkobject.c Bugs: - * Scrolled windows (GtkList?) get cought in an endless reallocation loop - under certain (rare) circumstances. + * gtk_ctree_set_selection_mode should be a mere alias of + gtk_clist_set_selection_mode, and clist should implement a new member + function `set_selection_mode' (doesn't need to have a gtk_signal_new + declaration) that can be overridden by ctree, this + is needed for proper widget argument support on GtkCList basis. + this applies similarly to `gtk_ctree_clear', one should be able to + get the same effect by invoking gtk_clist_clear (GTK_CLIST (ctree)); * Widget redrawing when the window resizes sometimes messes up. GtkLabels sometimes redraw without clearing up the underlying background on @@ -4247,7 +4247,7 @@ gdk_drop_get_real_window (GdkWindow *w, GList *children; gint16 myx = *x, myy = *y; - g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL); + g_return_val_if_fail (w != NULL && x != NULL && y != NULL, NULL); myx = *x; myy = *y; @@ -4278,7 +4278,7 @@ descend: /* Sends a ClientMessage to all toplevel client windows */ void -gdk_event_send_clientmessage_toall(GdkEvent *event) +gdk_event_send_clientmessage_toall (GdkEvent *event) { XEvent sev; Window *ret_children, ret_root, ret_parent, curwin; @@ -4333,3 +4333,73 @@ gdk_send_xevent (Window window, gboolean propagate, glong event_mask, return result && (gdk_error_code != -1); } + +gchar* +gdk_keyval_name (guint keyval) +{ + return XKeysymToString (keyval); +} + +guint +gdk_keyval_from_name (const gchar *keyval_name) +{ + g_return_val_if_fail (keyval_name != NULL, 0); + + return XStringToKeysym (keyval_name); +} + +guint +gdk_keyval_to_upper (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return upper_val; + } + return 0; +} + +guint +gdk_keyval_to_lower (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return lower_val; + } + return 0; +} + +gboolean +gdk_keyval_is_upper (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return upper_val == keyval; + } + return TRUE; +} + +gboolean +gdk_keyval_is_lower (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return lower_val == keyval; + } + return TRUE; +} @@ -25,6 +25,7 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ @@ -710,9 +711,6 @@ void gdk_ic_set_attr (GdkIC ic, const char *target, ...); void gdk_ic_get_attr (GdkIC ic, const char *target, ...); GdkEventMask gdk_ic_get_events (GdkIC ic); -/* Miscellaneous */ -void gdk_event_send_clientmessage_toall(GdkEvent *event); - /* Color Context */ GdkColorContext *gdk_color_context_new (GdkVisual *visual, @@ -807,6 +805,9 @@ GdkRegion* gdk_regions_subtract (GdkRegion *source1, GdkRegion* gdk_regions_xor (GdkRegion *source1, GdkRegion *source2); +/* Threads + */ + gboolean gdk_threads_init (void); void gdk_threads_enter (void); void gdk_threads_leave (void); @@ -816,6 +817,20 @@ void gdk_threads_leave (void); */ void gdk_threads_wake (void); +/* Miscellaneous */ +void gdk_event_send_clientmessage_toall (GdkEvent *event); + +/* Key values + */ +gchar* gdk_keyval_name (guint keyval); +guint gdk_keyval_from_name (const gchar *keyval_name); +guint gdk_keyval_to_upper (guint keyval); +guint gdk_keyval_to_lower (guint keyval); +gboolean gdk_keyval_is_upper (guint keyval); +gboolean gdk_keyval_is_lower (guint keyval); + + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 2be67de5d6..f1b9a40681 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -440,7 +440,9 @@ typedef enum GDK_BUTTON2_MASK = 1 << 9, GDK_BUTTON3_MASK = 1 << 10, GDK_BUTTON4_MASK = 1 << 11, - GDK_BUTTON5_MASK = 1 << 12 + GDK_BUTTON5_MASK = 1 << 12, + GDK_AFTER_MASK = 1 << 13, + GDK_MODIFIER_MASK = 0x3fff } GdkModifierType; typedef enum diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 2303b293fd..6b5f4021f5 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -4247,7 +4247,7 @@ gdk_drop_get_real_window (GdkWindow *w, GList *children; gint16 myx = *x, myy = *y; - g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL); + g_return_val_if_fail (w != NULL && x != NULL && y != NULL, NULL); myx = *x; myy = *y; @@ -4278,7 +4278,7 @@ descend: /* Sends a ClientMessage to all toplevel client windows */ void -gdk_event_send_clientmessage_toall(GdkEvent *event) +gdk_event_send_clientmessage_toall (GdkEvent *event) { XEvent sev; Window *ret_children, ret_root, ret_parent, curwin; @@ -4333,3 +4333,73 @@ gdk_send_xevent (Window window, gboolean propagate, glong event_mask, return result && (gdk_error_code != -1); } + +gchar* +gdk_keyval_name (guint keyval) +{ + return XKeysymToString (keyval); +} + +guint +gdk_keyval_from_name (const gchar *keyval_name) +{ + g_return_val_if_fail (keyval_name != NULL, 0); + + return XStringToKeysym (keyval_name); +} + +guint +gdk_keyval_to_upper (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return upper_val; + } + return 0; +} + +guint +gdk_keyval_to_lower (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return lower_val; + } + return 0; +} + +gboolean +gdk_keyval_is_upper (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return upper_val == keyval; + } + return TRUE; +} + +gboolean +gdk_keyval_is_lower (guint keyval) +{ + if (keyval) + { + KeySym lower_val = 0; + KeySym upper_val = 0; + + XConvertCase (keyval, &lower_val, &upper_val); + return lower_val == keyval; + } + return TRUE; +} diff --git a/glib/ChangeLog b/glib/ChangeLog index 48a162ede3..69584b0afc 100644 --- a/glib/ChangeLog +++ b/glib/ChangeLog @@ -3,6 +3,11 @@ Sat Jun 6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org> * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird problems +Wed Jun 3 06:19:42 1998 Tim Janik <timj@gtk.org> + + * glib.h (g_chunk_new0): convenience macro, for allocating small chunks + like g_chunk_new() with additional 0 initialization. + Mon Jun 1 04:43:27 1998 Tim Janik <timj@gtk.org> * ghash.c (g_hash_table_insert): wrote a comment describing why diff --git a/glib/glib.h b/glib/glib.h index 78688c5fbe..c57aece366 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -210,6 +210,9 @@ #define g_chunk_new(type, chunk) ( \ (type *) g_mem_chunk_alloc (chunk) \ ) +#define g_chunk_new0(type, chunk) ( \ + (type *) memset (g_mem_chunk_alloc (chunk), 0, sizeof (type)) \ +) #define g_chunk_free(mem, mem_chunk) G_STMT_START { \ g_mem_chunk_free ((mem_chunk), (mem)); \ } G_STMT_END diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 71cb2f79bd..31a1a5d89f 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -1,16 +1,18 @@ -## Process this file with automake to produce Makefile.in +### Process this file with automake to produce Makefile.in gtkincludedir = $(includedir)/gtk lib_LTLIBRARIES = libgtk-1.1.la libgtk_1_1_la_SOURCES = \ - gtkaccelerator.c \ + gtkaccelgroup.c \ + gtkaccellabel.c \ gtkadjustment.c \ gtkaspectframe.c \ gtkalignment.c \ gtkarrow.c \ gtkbin.c \ + gtkbindings.c \ gtkbbox.c \ gtkbox.c \ gtkbutton.c \ @@ -44,6 +46,7 @@ libgtk_1_1_la_SOURCES = \ gtkimage.c \ gtkinputdialog.c \ gtkitem.c \ + gtkitemfactory.c \ gtklabel.c \ gtklist.c \ gtklistitem.c \ @@ -99,12 +102,14 @@ libgtk_1_1_la_SOURCES = \ gtkinclude_HEADERS = \ gtk.h \ - gtkaccelerator.h \ + gtkaccelgroup.h \ + gtkaccellabel.h \ gtkadjustment.h \ gtkaspectframe.h \ gtkalignment.h \ gtkarrow.h \ gtkbin.h \ + gtkbindings.h \ gtkbbox.h \ gtkbox.h \ gtkbutton.h \ @@ -141,6 +146,7 @@ gtkinclude_HEADERS = \ gtkimage.h \ gtkinputdialog.h \ gtkitem.h \ + gtkitemfactory.h \ gtklabel.h \ gtklist.h \ gtklistitem.h \ @@ -200,6 +206,14 @@ $(srcdir)/gtktypebuiltins.h: @MAINT@ $(srcdir)/gtk.defs $(srcdir)/gentypeinfo.el $(srcdir)/gtktypebuiltins.c: @MAINT@ $(srcdir)/gtk.defs $(srcdir)/gentypeinfo.el $(SHELL) $(srcdir)/runelisp $(srcdir)/gentypeinfo.el id $< $@ +$(srcdir)/gtkenumvalues.c: @MAINT@ $(srcdir)/gtk.defs $(srcdir)/makeenums.awk + awk -f makeenums.awk $(srcdir)/gtk.defs > $@ + +# special remake rules +$(srcdir)/gtktypeutils.h: @MAINT@ $(srcdir)/gtktypebuiltins.h +$(srcdir)/gtktypeutils.c: @MAINT@ $(srcdir)/gtktypebuiltins.c +$(srcdir)/gtktypeutils.c: @MAINT@ $(srcdir)/gtkenumvalues.c + libgtk_1_1_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) EXTRA_DIST = \ @@ -211,7 +225,9 @@ EXTRA_DIST = \ gtkfeatures.h.in \ runelisp \ gentypeinfo.el \ + makeenums.awk \ gtktypebuiltins.c \ + gtkenumvalues.c \ test.xpm \ marble.xpm \ 3DRings.xpm \ @@ -223,7 +239,7 @@ EXTRA_DIST = \ tree_minus.xbm \ circles.xbm -INCLUDES = -I$(top_srcdir) -I../glib -I$(top_srcdir)/glib @x_cflags@ +INCLUDES = -I$(top_srcdir) -I../glib -I$(top_srcdir)/glib @x_cflags@ noinst_PROGRAMS = testgtk testinput testselection testthreads simple diff --git a/gtk/gentypeinfo.el b/gtk/gentypeinfo.el index 2de6a92d2b..380ac2a865 100644 --- a/gtk/gentypeinfo.el +++ b/gtk/gentypeinfo.el @@ -107,12 +107,20 @@ (defun emit-ids (defs) (map-interesting #'(lambda (form) - (printf " { %S, %s },\n" + (printf " { %S, %s, %s%s },\n" (symbol-name (cadr form)) (case (car form) - ((define-enum) "GTK_TYPE_ENUM") - ((define-flags) "GTK_TYPE_FLAGS") - ((define-boxed) "GTK_TYPE_BOXED")))) + ((define-enum) "GTK_TYPE_ENUM") + ((define-flags) "GTK_TYPE_FLAGS") + ((define-boxed) "GTK_TYPE_BOXED")) + (case (car form) + ((define-enum) "enum_values_") + ((define-flags) "enum_values_") + ((define-boxed) "NULL")) + (case (car form) + ((define-enum) (symbol-name (cadr form))) + ((define-flags) (symbol-name (cadr form))) + ((define-boxed) "")))) defs)) diff --git a/gtk/gtk.defs b/gtk/gtk.defs index cf6d7e3d04..7e635269d6 100644 --- a/gtk/gtk.defs +++ b/gtk/gtk.defs @@ -1,18 +1,30 @@ ;; -*- scheme -*- -;;; Gtk enums +;;; Gtk enums from gtkenums.h -(define-enum GtkWindowType - (toplevel GTK_WINDOW_TOPLEVEL) - (dialog GTK_WINDOW_DIALOG) - (popup GTK_WINDOW_POPUP)) +(define-flags GtkAccelFlags + (visible GTK_ACCEL_VISIBLE) + (signal-visible GTK_ACCEL_SIGNAL_VISIBLE) + (locked GTK_ACCEL_LOCKED) + (mask GTK_ACCEL_MASK)) -(define-enum GtkStateType - (normal GTK_STATE_NORMAL) - (active GTK_STATE_ACTIVE) - (prelight GTK_STATE_PRELIGHT) - (selected GTK_STATE_SELECTED) - (insensitive GTK_STATE_INSENSITIVE)) +(define-enum GtkArrowType + (up GTK_ARROW_UP) + (down GTK_ARROW_DOWN) + (left GTK_ARROW_LEFT) + (right GTK_ARROW_RIGHT)) + +(define-flags GtkAttachOptions + (expand GTK_EXPAND) + (shrink GTK_SHRINK) + (fill GTK_FILL)) + +(define-enum GtkButtonBoxStyle + (default GTK_BUTTONBOX_DEFAULT_STYLE) + (spread GTK_BUTTONBOX_SPREAD) + (edge GTK_BUTTONBOX_EDGE) + (start GTK_BUTTONBOX_START) + (end GTK_BUTTONBOX_END)) (define-enum GtkDirectionType (tab-forward GTK_DIR_TAB_FORWARD) @@ -22,36 +34,89 @@ (left GTK_DIR_LEFT) (right GTK_DIR_RIGHT)) -(define-enum GtkShadowType - (none GTK_SHADOW_NONE) - (in GTK_SHADOW_IN) - (out GTK_SHADOW_OUT) - (etched-in GTK_SHADOW_ETCHED_IN) - (etched-out GTK_SHADOW_ETCHED_OUT)) +(define-enum GtkJustification + (left GTK_JUSTIFY_LEFT) + (right GTK_JUSTIFY_RIGHT) + (center GTK_JUSTIFY_CENTER) + (fill GTK_JUSTIFY_FILL)) -(define-enum GtkArrowType - (up GTK_ARROW_UP) - (down GTK_ARROW_DOWN) - (left GTK_ARROW_LEFT) - (right GTK_ARROW_RIGHT)) +(define-enum GtkMatchType + (all GTK_MATCH_ALL) + (all-tail GTK_MATCH_ALL_TAIL) + (head GTK_MATCH_HEAD) + (tail GTK_MATCH_TAIL) + (exact GTK_MATCH_EXACT) + (last GTK_MATCH_LAST)) + +(define-enum GtkMenuFactoryType + (menu GTK_MENU_FACTORY_MENU) + (menu-bar GTK_MENU_FACTORY_MENU_BAR) + (option-menu GTK_MENU_FACTORY_OPTION_MENU)) + +(define-enum GtkMetricType + (pixels GTK_PIXELS) + (inches GTK_INCHES) + (centimeters GTK_CENTIMETERS)) + +(define-enum GtkOrientation + (horizontal GTK_ORIENTATION_HORIZONTAL) + (vertical GTK_ORIENTATION_VERTICAL)) (define-enum GtkPackType (start GTK_PACK_START) (end GTK_PACK_END)) +(define-enum GtkPathPriorityType + (lowest GTK_PATH_PRIO_LOWEST) + (gtk GTK_PATH_PRIO_GTK) + (application GTK_PATH_PRIO_APPLICATION) + (rc GTK_PATH_PRIO_RC) + (highest GTK_PATH_PRIO_HIGHEST) + (mask GTK_PATH_PRIO_MASK)) + +(define-enum GtkPathType + (widget GTK_PATH_WIDGET) + (widget-class GTK_PATH_WIDGET_CLASS) + (class GTK_PATH_CLASS)) + (define-enum GtkPolicyType (always GTK_POLICY_ALWAYS) (automatic GTK_POLICY_AUTOMATIC)) -(define-enum GtkUpdateType - (continuous GTK_UPDATE_CONTINUOUS) - (discontinuous GTK_UPDATE_DISCONTINUOUS) - (delayed GTK_UPDATE_DELAYED)) +(define-enum GtkPositionType + (left GTK_POS_LEFT) + (right GTK_POS_RIGHT) + (top GTK_POS_TOP) + (bottom GTK_POS_BOTTOM)) -(define-flags GtkAttachOptions - (expand GTK_EXPAND) - (shrink GTK_SHRINK) - (fill GTK_FILL)) +(define-enum GtkPreviewType + (color GTK_PREVIEW_COLOR) + (grayscale GTK_PREVIEW_GRAYSCALE)) + +(define-enum GtkReliefStyle + (normal GTK_RELIEF_NORMAL) + (none GTK_RELIEF_NONE)) + +(define-enum GtkScrollType + (none GTK_SCROLL_NONE) + (step-backward GTK_SCROLL_STEP_BACKWARD) + (step-forward GTK_SCROLL_STEP_FORWARD) + (page-backward GTK_SCROLL_PAGE_BACKWARD) + (page-forward GTK_SCROLL_PAGE_FORWARD) + (jump GTK_SCROLL_JUMP)) + +(define-enum GtkSelectionMode + (single GTK_SELECTION_SINGLE) + (browse GTK_SELECTION_BROWSE) + (multiple GTK_SELECTION_MULTIPLE) + (extended GTK_SELECTION_EXTENDED)) + +(define-enum GtkShadowType + (none GTK_SHADOW_NONE) + (in GTK_SHADOW_IN) + (out GTK_SHADOW_OUT) + (etched-in GTK_SHADOW_ETCHED_IN) + (etched-out GTK_SHADOW_ETCHED_OUT)) (define-flags GtkSignalRunType (first GTK_RUN_FIRST) @@ -60,10 +125,12 @@ (mask GTK_RUN_MASK) (no-recurse GTK_RUN_NO_RECURSE)) -(define-enum GtkWindowPosition - (none GTK_WIN_POS_NONE) - (center GTK_WIN_POS_CENTER) - (mouse GTK_WIN_POS_MOUSE)) +(define-enum GtkStateType + (normal GTK_STATE_NORMAL) + (active GTK_STATE_ACTIVE) + (prelight GTK_STATE_PRELIGHT) + (selected GTK_STATE_SELECTED) + (insensitive GTK_STATE_INSENSITIVE)) (define-enum GtkSubmenuDirection (left GTK_DIRECTION_LEFT) @@ -73,60 +140,80 @@ (top-bottom GTK_TOP_BOTTOM) (left-right GTK_LEFT_RIGHT)) -(define-enum GtkMenuFactoryType - (menu GTK_MENU_FACTORY_MENU) - (menu-bar GTK_MENU_FACTORY_MENU_BAR) - (option-menu GTK_MENU_FACTORY_OPTION_MENU)) - -(define-enum GtkMetricType - (pixels GTK_PIXELS) - (inches GTK_INCHES) - (centimeters GTK_CENTIMETERS)) - -(define-enum GtkScrollType - (none GTK_SCROLL_NONE) - (step-backward GTK_SCROLL_STEP_BACKWARD) - (step-forward GTK_SCROLL_STEP_FORWARD) - (page-backward GTK_SCROLL_PAGE_BACKWARD) - (page-forward GTK_SCROLL_PAGE_FORWARD)) +(define-enum GtkToolbarStyle + (icons GTK_TOOLBAR_ICONS) + (text GTK_TOOLBAR_TEXT) + (both GTK_TOOLBAR_BOTH)) (define-enum GtkTroughType (none GTK_TROUGH_NONE) (start GTK_TROUGH_START) - (end GTK_TROUGH_END)) + (end GTK_TROUGH_END) + (jump GTK_TROUGH_JUMP)) -(define-enum GtkPositionType - (left GTK_POS_LEFT) - (right GTK_POS_RIGHT) - (top GTK_POS_TOP) - (bottom GTK_POS_BOTTOM)) +(define-enum GtkUpdateType + (continuous GTK_UPDATE_CONTINUOUS) + (discontinuous GTK_UPDATE_DISCONTINUOUS) + (delayed GTK_UPDATE_DELAYED)) -(define-enum GtkPreviewType - (color GTK_PREVIEW_COLOR) - (grayscale GTK_PREVIEW_GRAYSCALE)) +(define-enum GtkVisibility + (none GTK_VISIBILITY_NONE) + (discontinuous GTK_UPDATE_DISCONTINUOUS) + (delayed GTK_UPDATE_DELAYED)) + +(define-enum GtkWindowPosition + (none GTK_WIN_POS_NONE) + (center GTK_WIN_POS_CENTER) + (mouse GTK_WIN_POS_MOUSE)) + +(define-enum GtkWindowType + (toplevel GTK_WINDOW_TOPLEVEL) + (dialog GTK_WINDOW_DIALOG) + (popup GTK_WINDOW_POPUP)) + +;;; Gtk enums from gtkobject.h + +(define-flags GtkObjectFlags + (destroyed GTK_DESTROYED) + (floating GTK_FLOATING) + (connected GTK_CONNECTED) + (object-flag-last GTK_OBJECT_FLAG_LAST)) + +(define-flags GtkArgFlags + (readable GTK_ARG_READABLE) + (writable GTK_ARG_WRITABLE) + (construct GTK_ARG_CONSTRUCT) + (mask GTK_ARG_MASK) + (readwrite GTK_ARG_READWRITE)) + +;;; Gtk enums from gtkwidget.h (define-flags GtkWidgetFlags - (visible GTK_VISIBLE) - (mapped GTK_MAPPED) - (unmapped GTK_UNMAPPED) + (toplevel GTK_TOPLEVEL) + (no-window GTK_NO_WINDOW) (realized GTK_REALIZED) + (mapped GTK_MAPPED) + (visible GTK_VISIBLE) (sensitive GTK_SENSITIVE) (parent-sensitive GTK_PARENT_SENSITIVE) - (no-window GTK_NO_WINDOW) - (has-focus GTK_HAS_FOCUS) (can-focus GTK_CAN_FOCUS) - (has-default GTK_HAS_DEFAULT) + (has-focus GTK_HAS_FOCUS) (can-default GTK_CAN_DEFAULT) - (propagate-state GTK_PROPAGATE_STATE) - (anchored GTK_ANCHORED) - (basic GTK_BASIC) - (user-style GTK_USER_STYLE)) + (has-default GTK_HAS_DEFAULT) + (has-grab GTK_HAS_GRAB) + (rc-style GTK_RC_STYLE) + (basic GTK_BASIC)) -(define-enum GtkSelectionMode - (single GTK_SELECTION_SINGLE) - (browse GTK_SELECTION_BROWSE) - (multiple GTK_SELECTION_MULTIPLE) - (extended GTK_SELECTION_EXTENDED)) +;;; Gtk enums from gtkprivate.h + +(define-flags GtkPrivateFlags + (user-style PRIVATE_GTK_USER_STYLE) + (redraw-pending PRIVATE_GTK_REDRAW_PENDING) + (resize-pending PRIVATE_GTK_RESIZE_PENDING) + (resize-needed PRIVATE_GTK_RESIZE_NEEDED) + (leave-pending PRIVATE_GTK_LEAVE_PENDING) + (has-shape-mask PRIVATE_GTK_HAS_SHAPE_MASK) + (in-reparent PRIVATE_GTK_IN_REPARENT)) (define-enum GtkCurveType (linear GTK_CURVE_TYPE_LINEAR) @@ -143,6 +230,7 @@ (long GTK_TYPE_LONG) (ulong GTK_TYPE_ULONG) (float GTK_TYPE_FLOAT) + (double GTK_TYPE_DOUBLE) (string GTK_TYPE_STRING) (enum GTK_TYPE_ENUM) (flags GTK_TYPE_FLAGS) @@ -155,23 +243,6 @@ (c-callback GTK_TYPE_C_CALLBACK) (object GTK_TYPE_OBJECT)) -(define-enum GtkJustification - (left GTK_JUSTIFY_LEFT) - (right GTK_JUSTIFY_RIGHT) - (center GTK_JUSTIFY_CENTER) - (fill GTK_JUSTIFY_FILL)) - -(define-enum GtkButtonBoxStyle - (default GTK_BUTTONBOX_DEFAULT_STYLE) - (spread GTK_BUTTONBOX_SPREAD) - (edge GTK_BUTTONBOX_EDGE) - (start GTK_BUTTONBOX_START) - (end GTK_BUTTONBOX_END)) - -(define-enum GtkOrientation - (horizontal GTK_ORIENTATION_HORIZONTAL) - (vertical GTK_ORIENTATION_VERTICAL)) - ;;; Gdk enums (define-enum GdkWindowType @@ -264,6 +335,16 @@ (selection-clear GDK_SELECTION_CLEAR) (selection-request GDK_SELECTION_REQUEST) (selection-notify GDK_SELECTION_NOTIFY) + (proximity-in GDK_PROXIMITY_IN) + (proximity-out GDK_PROXIMITY_OUT) + (drag-begin GDK_DRAG_BEGIN) + (drag-request GDK_DRAG_REQUEST) + (drop-enter GDK_DROP_ENTER) + (drop-leave GDK_DROP_LEAVE) + (drop-data-avail GDK_DROP_DATA_AVAIL) + (client-event GDK_CLIENT_EVENT) + (visibility-notify GDK_VISIBILITY_NOTIFY) + (no-expose GDK_NO_EXPOSE) (other-event GDK_OTHER_EVENT)) (define-flags GdkEventMask @@ -282,6 +363,11 @@ (leave-notify-mask GDK_LEAVE_NOTIFY_MASK) (focus-change-mask GDK_FOCUS_CHANGE_MASK) (structure-mask GDK_STRUCTURE_MASK) + (property-change-mask GDK_PROPERTY_CHANGE_MASK) + (visibility-notify-mask GDK_VISIBILITY_NOTIFY_MASK) + (proximity-in-mask GDK_PROXIMITY_IN_MASK) + (proximity-out-mask GDK_PROXIMITY_OUT_MASK) + (substructure-mask GDK_SUBSTRUCTURE_MASK) (all-events-mask GDK_ALL_EVENTS_MASK)) (define-enum GdkNotifyType @@ -292,6 +378,11 @@ (nonlinear-virtual GDK_NOTIFY_NONLINEAR_VIRTUAL) (unknown GDK_NOTIFY_UNKNOWN)) +(define-flags GdkCrossingMode + (crossing-normal GDK_CROSSING_NORMAL) + (crossing-grab GDK_CROSSING_GRAB) + (crossing-ungrab GDK_CROSSING_UNGRAB)) + (define-flags GdkModifierType (shift-mask GDK_SHIFT_MASK) (lock-mask GDK_LOCK_MASK) @@ -305,7 +396,9 @@ (button2-mask GDK_BUTTON2_MASK) (button3-mask GDK_BUTTON3_MASK) (button4-mask GDK_BUTTON4_MASK) - (button5-mask GDK_BUTTON5_MASK)) + (button5-mask GDK_BUTTON5_MASK) + (after-mask GDK_AFTER_MASK) + (modifier-mask GDK_MODIFIER_MASK)) (define-enum GdkSubwindowMode (clip-by-children GDK_CLIP_BY_CHILDREN) @@ -362,9 +455,9 @@ ;;; Gtk boxed types -(define-boxed GtkAcceleratorTable - gtk_accelerator_table_ref - gtk_accelerator_table_unref) +(define-boxed GtkAccelGroup + gtk_accel_group_ref + gtk_accel_group_unref) (define-boxed GtkStyle gtk_style_ref @@ -546,19 +639,21 @@ none ((GtkWidget widget))) - ;(define-func gtk_widget_install_accelerator - ; none - ; ((GtkWidget widget) - ; (GtkAcceleratorTable table) - ; (string signal_name) - ; (char key) - ; (...))) +(define-func gtk_widget_add_accelerator + none + ((GtkWidget widget) + (string accel_signal) + (GtkAccelGroup accel_group) + (guint accel_key) + (guint accel_mods) + (GtkAccelFlags accel_flags))) (define-func gtk_widget_remove_accelerator none ((GtkWidget widget) - (GtkAcceleratorTable table) - (string signal_name))) + (GtkAccelGroup accel_group) + (guint accel_key) + (guint accel_mods))) (define-func gtk_widget_event bool @@ -797,15 +892,15 @@ (bool allow_grow) (bool auto_shrink))) -(define-func gtk_window_add_accelerator_table +(define-func gtk_window_add_accel_group none ((GtkWindow window) - (GtkAcceleratorTable table))) + (GtkAccelGroup accel_group))) -(define-func gtk_window_remove_accelerator_table +(define-func gtk_window_remove_accel_group none ((GtkWindow window) - (GtkAcceleratorTable table))) + (GtkAccelGroup accel_group))) (define-func gtk_window_position none @@ -1233,10 +1328,10 @@ ((GtkMenu menu) (int index))) -(define-func gtk_menu_set_accelerator_table +(define-func gtk_menu_set_accel_group none ((GtkMenu menu) - (GtkAcceleratorTable table))) + (GtkAccelGroup accel_group))) ;; Item @@ -1277,10 +1372,6 @@ ((GtkMenuItem menu_item) (GtkSubmenuPlacement placement))) -(define-func gtk_menu_item_accelerator_size - none - ((GtkMenuItem menu_item))) - (define-func gtk_menu_item_configure none ((GtkMenuItem menu_item) @@ -21,12 +21,14 @@ #include <gdk/gdk.h> -#include <gtk/gtkaccelerator.h> +#include <gtk/gtkaccelgroup.h> +#include <gtk/gtkaccellabel.h> #include <gtk/gtkadjustment.h> #include <gtk/gtkalignment.h> #include <gtk/gtkaspectframe.h> #include <gtk/gtkarrow.h> #include <gtk/gtkbin.h> +#include <gtk/gtkbindings.h> #include <gtk/gtkbox.h> #include <gtk/gtkbbox.h> #include <gtk/gtkbutton.h> @@ -62,6 +64,7 @@ #include <gtk/gtkimage.h> #include <gtk/gtkinputdialog.h> #include <gtk/gtkitem.h> +#include <gtk/gtkitemfactory.h> #include <gtk/gtklabel.h> #include <gtk/gtklist.h> #include <gtk/gtklistitem.h> diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c new file mode 100644 index 0000000000..bfba69c6e6 --- /dev/null +++ b/gtk/gtkaccelgroup.c @@ -0,0 +1,1062 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkAccelGroup: Accelerator manager for GtkObjects. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include <ctype.h> +#include <strings.h> +#include "gtkaccelgroup.h" +#include "gdk/gdkkeysyms.h" +#include "gtksignal.h" +#include "gtkwidget.h" + + +/* --- signals --- */ +typedef void (*GtkSignalAddAccelerator) (GtkObject *object, + guint accel_signal_id, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags, + gpointer func_data); +typedef void (*GtkSignalRemoveAccelerator) (GtkObject *object, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + gpointer func_data); + +/* --- variables --- */ +static GtkAccelGroup *default_accel_group = NULL; +static guint default_accel_mod_mask = (GDK_SHIFT_MASK | + GDK_CONTROL_MASK | + GDK_MOD1_MASK); +static const gchar *accel_groups_key = "gtk-accel-groups"; +static guint accel_groups_key_id = 0; +static const gchar *accel_entries_key = "gtk-accel-entries"; +static guint accel_entries_key_id = 0; +static GHashTable *accel_entry_hash_table = NULL; +static GMemChunk *accel_tables_mem_chunk = NULL; +static GMemChunk *accel_entries_mem_chunk = NULL; + + +/* --- functions --- */ +static gint +gtk_accel_entries_equal (gpointer a, + gpointer b) +{ + GtkAccelEntry *e1; + GtkAccelEntry *e2; + + e1 = a; + e2 = b; + + return ((e1->accel_group == e2->accel_group) && + (e1->accelerator_key == e2->accelerator_key) && + (e1->accelerator_mods == e2->accelerator_mods)); +} + +static guint +gtk_accel_entries_hash (gpointer a) +{ + GtkAccelEntry *e; + guint h; + + e = a; + + h = (gulong) e->accel_group; + h ^= e->accelerator_key << 16; + h ^= e->accelerator_key >> 16; + h ^= e->accelerator_mods; + + return h; +} + +GtkAccelGroup* +gtk_accel_group_new (void) +{ + GtkAccelGroup *accel_group; + + if (!accel_groups_key_id) + { + accel_groups_key_id = gtk_object_data_force_id (accel_groups_key); + accel_entries_key_id = gtk_object_data_force_id (accel_entries_key); + + accel_entry_hash_table = g_hash_table_new (gtk_accel_entries_hash, + gtk_accel_entries_equal); + + accel_tables_mem_chunk = g_mem_chunk_create (GtkAccelGroup, 8, G_ALLOC_AND_FREE); + accel_entries_mem_chunk = g_mem_chunk_create (GtkAccelEntry, 64, G_ALLOC_AND_FREE); + } + + accel_group = g_chunk_new (GtkAccelGroup, accel_tables_mem_chunk); + + accel_group->ref_count = 1; + accel_group->lock_count = 0; + accel_group->modifier_mask = gtk_accelerator_get_default_mod_mask (); + accel_group->attach_objects = NULL; + + return accel_group; +} + +GtkAccelGroup* +gtk_accel_group_get_default (void) +{ + if (!default_accel_group) + default_accel_group = gtk_accel_group_new (); + + return default_accel_group; +} + +GtkAccelGroup* +gtk_accel_group_ref (GtkAccelGroup *accel_group) +{ + g_return_val_if_fail (accel_group != NULL, NULL); + + accel_group->ref_count += 1; + + return accel_group; +} + +void +gtk_accel_group_unref (GtkAccelGroup *accel_group) +{ + g_return_if_fail (accel_group != NULL); + g_return_if_fail (accel_group->ref_count > 0); + + accel_group->ref_count -= 1; + if (accel_group->ref_count == 0) + { + g_return_if_fail (accel_group != default_accel_group); + g_return_if_fail (accel_group->attach_objects == NULL); + + g_chunk_free (accel_group, accel_tables_mem_chunk); + } +} + +static void +gtk_accel_group_object_destroy (GtkObject *object) +{ + GSList *free_list, *slist; + + free_list = gtk_object_get_data_by_id (object, accel_groups_key_id); + gtk_object_set_data_by_id (object, accel_groups_key_id, NULL); + + for (slist = free_list; slist; slist = slist->next) + { + GtkAccelGroup *accel_group; + + accel_group = slist->data; + accel_group->attach_objects = g_slist_remove (accel_group->attach_objects, object); + gtk_accel_group_unref (accel_group); + } + g_slist_free (free_list); +} + +void +gtk_accel_group_attach (GtkAccelGroup *accel_group, + GtkObject *object) +{ + GSList *slist; + + g_return_if_fail (accel_group != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (g_slist_find (accel_group->attach_objects, object) == NULL); + + accel_group->attach_objects = g_slist_prepend (accel_group->attach_objects, object); + gtk_accel_group_ref (accel_group); + slist = gtk_object_get_data_by_id (object, accel_groups_key_id); + if (!slist) + gtk_signal_connect (object, + "destroy", + GTK_SIGNAL_FUNC (gtk_accel_group_object_destroy), + NULL); + slist = g_slist_prepend (slist, accel_group); + gtk_object_set_data_by_id (object, accel_groups_key_id, slist); +} + +void +gtk_accel_group_detach (GtkAccelGroup *accel_group, + GtkObject *object) +{ + GSList *slist; + + g_return_if_fail (accel_group != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (g_slist_find (accel_group->attach_objects, object) != NULL); + + accel_group->attach_objects = g_slist_remove (accel_group->attach_objects, object); + gtk_accel_group_unref (accel_group); + slist = gtk_object_get_data_by_id (object, accel_groups_key_id); + slist = g_slist_remove (slist, accel_group); + if (!slist) + gtk_signal_disconnect_by_func (object, + GTK_SIGNAL_FUNC (gtk_accel_group_object_destroy), + NULL); + gtk_object_set_data_by_id (object, accel_groups_key_id, slist); +} + +void +gtk_accel_group_lock (GtkAccelGroup *accel_group) +{ + g_return_if_fail (accel_group != NULL); + + accel_group->lock_count += 1; +} + +void +gtk_accel_group_unlock (GtkAccelGroup *accel_group) +{ + g_return_if_fail (accel_group != NULL); + + if (accel_group->lock_count) + accel_group->lock_count -= 1; +} + +static GtkAccelEntry* +gtk_accel_group_lookup (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry key_entry = { 0 }; + + key_entry.accel_group = accel_group; + key_entry.accelerator_key = gdk_keyval_to_lower (accel_key); + key_entry.accelerator_mods = accel_mods & accel_group->modifier_mask; + + return g_hash_table_lookup (accel_entry_hash_table, &key_entry); +} + +gboolean +gtk_accel_group_activate (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry *entry; + + g_return_val_if_fail (accel_group != NULL, FALSE); + + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry && entry->signal_id) + { + gtk_signal_emit (entry->object, entry->signal_id); + return TRUE; + } + return FALSE; +} + +gboolean +gtk_accel_groups_activate (GtkObject *object, + guint accel_key, + guint accel_mods) +{ + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE); + + if (gtk_accelerator_valid (accel_key, accel_mods)) + { + GSList *slist; + + for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next) + if (gtk_accel_group_activate (slist->data, accel_key, accel_mods)) + return TRUE; + return gtk_accel_group_activate (gtk_accel_group_get_default (), accel_key, accel_mods); + } + + return FALSE; +} + +void +gtk_accel_group_lock_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry *entry; + + g_return_if_fail (accel_group != NULL); + + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry) + entry->accel_flags |= GTK_ACCEL_LOCKED; +} + +void +gtk_accel_group_unlock_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry *entry; + + g_return_if_fail (accel_group != NULL); + + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry) + entry->accel_flags &= ~GTK_ACCEL_LOCKED; +} + +GtkAccelEntry* +gtk_accel_group_get_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + g_return_val_if_fail (accel_group != NULL, 0); + + return gtk_accel_group_lookup (accel_group, accel_key, accel_mods); +} + +void +gtk_accel_group_add (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags, + GtkObject *object, + const gchar *accel_signal) +{ + guint accel_signal_id = 0; + guint add_accelerator_signal_id = 0; + guint remove_accelerator_signal_id = 0; + gchar *signal; + GtkSignalQuery *query; + GSList *slist; + GSList *groups; + GSList *attach_objects; + GtkAccelEntry *entry; + + g_return_if_fail (accel_group != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (accel_signal != NULL); + + /* check for required signals in the objects branch + */ + signal = (gchar*) accel_signal; + accel_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object)); + if (accel_signal_id) + { + signal = "add-accelerator"; + add_accelerator_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object)); + } + if (add_accelerator_signal_id) + { + signal = "remove-accelerator"; + remove_accelerator_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object)); + } + if (!accel_signal_id || + !add_accelerator_signal_id || + !remove_accelerator_signal_id) + { + g_warning ("gtk_accel_group_add(): could not find signal \"%s\"" + "in the `%s' class ancestry", + signal, + gtk_type_name (GTK_OBJECT_TYPE (object))); + return; + } + query = gtk_signal_query (accel_signal_id); + if (!query || + query->nparams > 0) + { + g_warning ("gtk_accel_group_add(): signal \"%s\" in the `%s' class ancestry" + "cannot be used as accelerator signal", + accel_signal, + gtk_type_name (GTK_OBJECT_TYPE (object))); + return; + } + + /* prematurely abort if the group/entry is already locked + */ + if (accel_group->lock_count > 0) + return; + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry && entry->accel_flags & GTK_ACCEL_LOCKED) + return; + + /* make sure our structures stay alive + */ + gtk_accel_group_ref (accel_group); + gtk_object_ref (object); + + /* remove an existing entry + */ + if (entry) + gtk_signal_emit (entry->object, remove_accelerator_signal_id, + accel_group, + gdk_keyval_to_lower (accel_key), + accel_mods & accel_group->modifier_mask); + + /* abort if the entry still exists + */ + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry) + { + gtk_accel_group_unref (accel_group); + gtk_object_unref (object); + + return; + } + + /* collect accel groups and remove existing entries + */ + attach_objects = accel_group->attach_objects; + groups = NULL; + for (attach_objects = accel_group->attach_objects; attach_objects; attach_objects = attach_objects->next) + { + GSList *tmp_groups; + + tmp_groups = gtk_object_get_data_by_id (attach_objects->data, accel_groups_key_id); + while (tmp_groups) + { + groups = g_slist_prepend (groups, tmp_groups->data); + gtk_accel_group_ref (tmp_groups->data); + tmp_groups = tmp_groups->next; + } + } + for (slist = groups; slist; slist = slist->next) + { + GtkAccelGroup *tmp_group; + + tmp_group = slist->data; + + /* we only remove the accelerator if neccessary + */ + if (tmp_group->lock_count == 0) + { + entry = gtk_accel_group_lookup (tmp_group, accel_key, accel_mods); + if (entry && !(entry->accel_flags & GTK_ACCEL_LOCKED)) + gtk_signal_emit (entry->object, remove_accelerator_signal_id, + tmp_group, + gdk_keyval_to_lower (accel_key), + accel_mods & tmp_group->modifier_mask); + } + gtk_accel_group_unref (tmp_group); + } + g_slist_free (groups); + + /* now install the new accelerator + */ + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (!entry) + gtk_signal_emit (object, add_accelerator_signal_id, + accel_signal_id, + accel_group, + gdk_keyval_to_lower (accel_key), + accel_mods & accel_group->modifier_mask, + accel_flags & GTK_ACCEL_MASK); + + /* and release the structures again + */ + gtk_accel_group_unref (accel_group); + gtk_object_unref (object); +} + +static void +gtk_accel_group_delete_entries (GtkObject *object) +{ + GSList *free_slist, *slist; + + gtk_signal_disconnect_by_func (object, + GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries), + NULL); + + /* we remove all entries of this object the hard + * way (i.e. without signal emission). + */ + free_slist = gtk_object_get_data_by_id (object, accel_entries_key_id); + gtk_object_set_data_by_id (object, accel_entries_key_id, NULL); + for (slist = free_slist; slist; slist = slist->next) + { + GtkAccelEntry *entry; + + entry = slist->data; + + g_hash_table_remove (accel_entry_hash_table, entry); + gtk_accel_group_unref (entry->accel_group); + g_chunk_free (entry, accel_entries_mem_chunk); + } + g_slist_free (free_slist); +} + +void +gtk_accel_group_handle_add (GtkObject *object, + guint accel_signal_id, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags) +{ + GtkAccelEntry *entry; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (accel_group != NULL); + g_return_if_fail (accel_signal_id > 0); + + if (!gtk_accelerator_valid (accel_key, accel_mods)) + return; + + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (!entry) + { + GSList *slist; + + gtk_accel_group_ref (accel_group); + + entry = g_chunk_new (GtkAccelEntry, accel_entries_mem_chunk); + entry->accel_group = accel_group; + entry->accelerator_key = gdk_keyval_to_lower (accel_key); + entry->accelerator_mods = accel_mods & accel_group->modifier_mask; + entry->accel_flags = accel_flags & GTK_ACCEL_MASK; + entry->object = object; + entry->signal_id = accel_signal_id; + + g_hash_table_insert (accel_entry_hash_table, entry, entry); + + slist = gtk_object_get_data_by_id (object, accel_entries_key_id); + if (!slist) + gtk_signal_connect (object, + "destroy", + GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries), + NULL); + slist = g_slist_prepend (slist, entry); + gtk_object_set_data_by_id (object, accel_entries_key_id, slist); + } +} + +void +gtk_accel_group_remove (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkObject *object) +{ + GtkAccelEntry *entry; + guint remove_accelerator_signal_id = 0; + + g_return_if_fail (accel_group != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + /* check for required signals in the objects branch + */ + remove_accelerator_signal_id = gtk_signal_lookup ("remove-accelerator", GTK_OBJECT_TYPE (object)); + if (!remove_accelerator_signal_id) + { + g_warning ("gtk_accel_group_remove(): could not find signal \"%s\"" + "in the `%s' class ancestry", + "remove-accelerator", + gtk_type_name (GTK_OBJECT_TYPE (object))); + return; + } + + /* prematurely abort if the entry is locked + */ + if (accel_group->lock_count > 0) + return; + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (!entry || + entry->accel_flags & GTK_ACCEL_LOCKED) + return; + if (entry->object != object) + { + g_warning ("gtk_accel_group_remove(): invalid object reference for accel-group entry"); + return; + } + + /* make sure our structures stay alive + */ + gtk_accel_group_ref (accel_group); + gtk_object_ref (object); + + /* remove the entry + */ + gtk_signal_emit (entry->object, remove_accelerator_signal_id, + accel_group, + gdk_keyval_to_lower (accel_key), + accel_mods & accel_group->modifier_mask); + + /* and release the structures again + */ + gtk_accel_group_unref (accel_group); + gtk_object_unref (object); +} + +void +gtk_accel_group_handle_remove (GtkObject *object, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry *entry; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (accel_group != NULL); + + entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods); + if (entry) + { + if (entry->object == object) + { + GSList *slist; + + g_hash_table_remove (accel_entry_hash_table, entry); + + slist = gtk_object_get_data_by_id (object, accel_entries_key_id); + if (slist) + { + slist = g_slist_remove (slist, entry); + if (!slist) + gtk_signal_disconnect_by_func (object, + GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries), + NULL); + gtk_object_set_data_by_id (object, accel_entries_key_id, slist); + + gtk_accel_group_unref (accel_group); + + g_chunk_free (entry, accel_entries_mem_chunk); + } + } + else + g_warning ("gtk_accel_group_handle_remove(): invalid object reference for accel-group entry"); + } + else + g_warning ("gtk_accel_group_handle_remove(): attempt to remove unexisting accel-group entry"); +} + +guint +gtk_accel_group_create_add (GtkType class_type, + GtkSignalRunType run_type, + guint handler_offset) +{ + g_return_val_if_fail (gtk_type_is_a (class_type, GTK_TYPE_OBJECT), 0); + + return gtk_signal_new ("add-accelerator", + run_type, + class_type, + handler_offset, + gtk_accel_group_marshal_add, + GTK_TYPE_NONE, 5, + GTK_TYPE_UINT, + GTK_TYPE_BOXED, + GTK_TYPE_UINT, + GTK_TYPE_UINT, + GTK_TYPE_ENUM); +} + +guint +gtk_accel_group_create_remove (GtkType class_type, + GtkSignalRunType run_type, + guint handler_offset) +{ + g_return_val_if_fail (gtk_type_is_a (class_type, GTK_TYPE_OBJECT), 0); + + return gtk_signal_new ("remove-accelerator", + run_type, + class_type, + handler_offset, + gtk_accel_group_marshal_remove, + GTK_TYPE_NONE, 3, + GTK_TYPE_BOXED, + GTK_TYPE_UINT, + GTK_TYPE_UINT); +} + +void +gtk_accel_group_marshal_add (GtkObject *object, + GtkSignalFunc func, + gpointer func_data, + GtkArg *args) +{ + GtkSignalAddAccelerator signal_func; + + signal_func = (GtkSignalAddAccelerator) func; + + signal_func (object, + GTK_VALUE_UINT (args[0]), + GTK_VALUE_BOXED (args[1]), + GTK_VALUE_UINT (args[2]), + GTK_VALUE_UINT (args[3]), + GTK_VALUE_ENUM (args[4]), + func_data); +} + +void +gtk_accel_group_marshal_remove (GtkObject *object, + GtkSignalFunc func, + gpointer func_data, + GtkArg *args) +{ + GtkSignalRemoveAccelerator signal_func; + + signal_func = (GtkSignalRemoveAccelerator) func; + + signal_func (object, + GTK_VALUE_BOXED (args[0]), + GTK_VALUE_UINT (args[1]), + GTK_VALUE_UINT (args[2]), + func_data); +} + +GSList* +gtk_accel_groups_from_object (GtkObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (GTK_IS_OBJECT (object), NULL); + + return gtk_object_get_data_by_id (object, accel_groups_key_id); +} + +GSList* +gtk_accel_group_entries_from_object (GtkObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (GTK_IS_OBJECT (object), NULL); + + return gtk_object_get_data_by_id (object, accel_entries_key_id); +} + +gboolean +gtk_accelerator_valid (guint keyval, + guint modifiers) +{ + guint invalid_accelerator_vals[] = { + GDK_BackSpace, GDK_Delete, GDK_KP_Delete, + GDK_Shift_L, GDK_Shift_R, GDK_Shift_Lock, GDK_Caps_Lock, GDK_ISO_Lock, + GDK_Control_L, GDK_Control_R, GDK_Meta_L, GDK_Meta_R, + GDK_Super_L, GDK_Super_R, GDK_Hyper_L, GDK_Hyper_R, + GDK_Mode_switch, GDK_Num_Lock, GDK_Multi_key, + GDK_Scroll_Lock, GDK_Sys_Req, + GDK_Up, GDK_Down, GDK_Left, GDK_Right, GDK_Tab, GDK_ISO_Left_Tab, + GDK_KP_Up, GDK_KP_Down, GDK_KP_Left, GDK_KP_Right, GDK_KP_Tab, + GDK_First_Virtual_Screen, GDK_Prev_Virtual_Screen, + GDK_Next_Virtual_Screen, GDK_Last_Virtual_Screen, + GDK_Terminate_Server, GDK_AudibleBell_Enable, + 0 + }; + guint *ac_val; + + modifiers &= GDK_MODIFIER_MASK; + + if (keyval <= 0xFF) + return keyval >= 0x20; + + ac_val = invalid_accelerator_vals; + while (*ac_val) + { + if (keyval == *ac_val++) + return FALSE; + } + + return TRUE; +} + +static inline gboolean +is_alt (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'a' || string[1] == 'A') && + (string[2] == 'l' || string[2] == 'L') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == '>')); +} + +static inline gboolean +is_ctl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == '>')); +} + +static inline gboolean +is_modx (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'd' || string[3] == 'D') && + (string[4] >= '1' && string[4] <= '5') && + (string[5] == '>')); +} + +static inline gboolean +is_ctrl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'r' || string[3] == 'R') && + (string[4] == 'l' || string[4] == 'L') && + (string[5] == '>')); +} + +static inline gboolean +is_shft (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'f' || string[3] == 'F') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == '>')); +} + +static inline gboolean +is_shift (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'f' || string[4] == 'F') && + (string[5] == 't' || string[5] == 'T') && + (string[6] == '>')); +} + +static inline gboolean +is_after (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'a' || string[1] == 'A') && + (string[2] == 'f' || string[2] == 'F') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_control (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'n' || string[3] == 'N') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == 'o' || string[6] == 'O') && + (string[7] == 'l' || string[7] == 'L') && + (string[8] == '>')); +} + +void +gtk_accelerator_parse (const gchar *accelerator, + guint *accelerator_key, + guint *accelerator_mods) +{ + guint keyval; + guint mods; + gint len; + + if (accelerator_key) + *accelerator_key = 0; + if (accelerator_mods) + *accelerator_mods = 0; + g_return_if_fail (accelerator != NULL); + + keyval = 0; + mods = 0; + len = strlen (accelerator); + while (len) + { + if (*accelerator == '<') + { + if (len >= 9 && is_control (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 7 && is_shift (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_SHIFT_MASK; + } + else if (len >= 7 && is_after (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_AFTER_MASK; + } + else if (len >= 6 && is_shft (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_SHIFT_MASK; + } + else if (len >= 6 && is_ctrl (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 6 && is_modx (accelerator)) + { + guint mod_vals[] = { + GDK_MOD1_MASK, GDK_MOD2_MASK, GDK_MOD3_MASK, + GDK_MOD4_MASK, GDK_MOD5_MASK + }; + + len -= 6; + accelerator += 4; + mods |= mod_vals[*accelerator - '1']; + accelerator += 2; + } + else if (len >= 5 && is_ctl (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= GDK_CONTROL_MASK; + } + else if (len >= 5 && is_alt (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= GDK_MOD1_MASK; + } + else + { + gchar last_ch; + + last_ch = *accelerator; + while (last_ch && last_ch != '>') + { + last_ch = *accelerator; + accelerator += 1; + len -= 1; + } + } + } + else + { + keyval = gdk_keyval_from_name (accelerator); + accelerator += len; + len -= len; + } + } + + if (accelerator_key) + *accelerator_key = gdk_keyval_to_lower (keyval); + if (accelerator_mods) + *accelerator_mods = mods; +} + +gchar* +gtk_accelerator_name (guint accelerator_key, + guint accelerator_mods) +{ + static const gchar text_shift[] = "<Shift>"; + static const gchar text_control[] = "<Control>"; + static const gchar text_mod1[] = "<Alt>"; + static const gchar text_mod2[] = "<Mod2>"; + static const gchar text_mod3[] = "<Mod3>"; + static const gchar text_mod4[] = "<Mod4>"; + static const gchar text_mod5[] = "<Mod5>"; + static const gchar text_after[] = "<After>"; + guint l; + gchar *keyval_name; + gchar *accelerator; + + accelerator_mods &= GDK_MODIFIER_MASK; + + keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); + if (!keyval_name) + keyval_name = ""; + + l = 0; + if (accelerator_mods & GDK_SHIFT_MASK) + l += sizeof (text_shift) - 1; + if (accelerator_mods & GDK_CONTROL_MASK) + l += sizeof (text_control) - 1; + if (accelerator_mods & GDK_MOD1_MASK) + l += sizeof (text_mod1) - 1; + if (accelerator_mods & GDK_MOD2_MASK) + l += sizeof (text_mod2) - 1; + if (accelerator_mods & GDK_MOD3_MASK) + l += sizeof (text_mod3) - 1; + if (accelerator_mods & GDK_MOD4_MASK) + l += sizeof (text_mod4) - 1; + if (accelerator_mods & GDK_MOD5_MASK) + l += sizeof (text_mod5) - 1; + if (accelerator_mods & GDK_AFTER_MASK) + l += sizeof (text_after) - 1; + l += strlen (keyval_name); + + accelerator = g_new (gchar, l + 1); + + l = 0; + accelerator[l] = 0; + if (accelerator_mods & GDK_SHIFT_MASK) + { + strcpy (accelerator + l, text_shift); + l += sizeof (text_shift) - 1; + } + if (accelerator_mods & GDK_CONTROL_MASK) + { + strcpy (accelerator + l, text_control); + l += sizeof (text_control) - 1; + } + if (accelerator_mods & GDK_MOD1_MASK) + { + strcpy (accelerator + l, text_mod1); + l += sizeof (text_mod1) - 1; + } + if (accelerator_mods & GDK_MOD2_MASK) + { + strcpy (accelerator + l, text_mod2); + l += sizeof (text_mod2) - 1; + } + if (accelerator_mods & GDK_MOD3_MASK) + { + strcpy (accelerator + l, text_mod3); + l += sizeof (text_mod3) - 1; + } + if (accelerator_mods & GDK_MOD4_MASK) + { + strcpy (accelerator + l, text_mod4); + l += sizeof (text_mod4) - 1; + } + if (accelerator_mods & GDK_MOD5_MASK) + { + strcpy (accelerator + l, text_mod5); + l += sizeof (text_mod5) - 1; + } + if (accelerator_mods & GDK_AFTER_MASK) + { + strcpy (accelerator + l, text_after); + l += sizeof (text_after) - 1; + } + strcpy (accelerator + l, keyval_name); + + return accelerator; +} + +void +gtk_accelerator_set_default_mod_mask (guint default_mod_mask) +{ + default_accel_mod_mask = default_mod_mask & GDK_MODIFIER_MASK; +} + +guint +gtk_accelerator_get_default_mod_mask (void) +{ + return default_accel_mod_mask; +} diff --git a/gtk/gtkaccelgroup.h b/gtk/gtkaccelgroup.h new file mode 100644 index 0000000000..7b72860fd1 --- /dev/null +++ b/gtk/gtkaccelgroup.h @@ -0,0 +1,164 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkAccelGroup: Accelerator manager for GtkObjects. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __GTK_ACCEL_GROUP_H__ +#define __GTK_ACCEL_GROUP_H__ + + +#include <gdk/gdk.h> +#include <gtk/gtkobject.h> +#include <gtk/gtkenums.h> + + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + +typedef struct _GtkAccelGroup GtkAccelGroup; +typedef struct _GtkAccelEntry GtkAccelEntry; + +/* enum GtkAccelFlags: + * + * GTK_ACCEL_VISIBLE - should the accelerator appear in + * the widget's display? + * GTK_ACCEL_SIGNAL_VISIBLE - should the signal associated + * with this accelerator be also visible? + * GTK_ACCEL_LOCKED - may the accelerator be removed again? + */ + +struct _GtkAccelGroup +{ + guint ref_count; + guint lock_count; + guint modifier_mask; + GSList *attach_objects; +}; + +struct _GtkAccelEntry +{ + /* key portion + */ + GtkAccelGroup *accel_group; + guint accelerator_key; + guint accelerator_mods; + + GtkAccelFlags accel_flags; + GtkObject *object; + guint signal_id; +}; + + +/* Accelerator Groups + */ +GtkAccelGroup* gtk_accel_group_new (void); +GtkAccelGroup* gtk_accel_group_get_default (void); +GtkAccelGroup* gtk_accel_group_ref (GtkAccelGroup *accel_group); +void gtk_accel_group_unref (GtkAccelGroup *accel_group); +gboolean gtk_accel_group_activate (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +gboolean gtk_accel_groups_activate (GtkObject *object, + guint accel_key, + guint accel_mods); +void gtk_accel_group_attach (GtkAccelGroup *accel_group, + GtkObject *object); +void gtk_accel_group_detach (GtkAccelGroup *accel_group, + GtkObject *object); +void gtk_accel_group_lock (GtkAccelGroup *accel_group); +void gtk_accel_group_unlock (GtkAccelGroup *accel_group); + +/* Accelerator Group Entries + */ +GtkAccelEntry* gtk_accel_group_get_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +void gtk_accel_group_lock_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +void gtk_accel_group_unlock_entry (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +void gtk_accel_group_add (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags, + GtkObject *object, + const gchar *accel_signal); +void gtk_accel_group_remove (GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkObject *object); + +/* Accelerator Signals + */ +void gtk_accel_group_handle_add (GtkObject *object, + guint accel_signal_id, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags); +void gtk_accel_group_handle_remove (GtkObject *object, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +guint gtk_accel_group_create_add (GtkType class_type, + GtkSignalRunType run_type, + guint handler_offset); +guint gtk_accel_group_create_remove (GtkType class_type, + GtkSignalRunType run_type, + guint handler_offset); +void gtk_accel_group_marshal_add (GtkObject *object, + GtkSignalFunc func, + gpointer func_data, + GtkArg *args); +void gtk_accel_group_marshal_remove (GtkObject *object, + GtkSignalFunc func, + gpointer func_data, + GtkArg *args); + +/* Miscellaneous + */ +GSList* gtk_accel_groups_from_object (GtkObject *object); +GSList* gtk_accel_group_entries_from_object (GtkObject *object); + + +/* Accelerators + */ +gboolean gtk_accelerator_valid (guint keyval, + guint modifiers); +void gtk_accelerator_parse (const gchar *accelerator, + guint *accelerator_key, + guint *accelerator_mods); +gchar* gtk_accelerator_name (guint accelerator_key, + guint accelerator_mods); +void gtk_accelerator_set_default_mod_mask (guint default_mod_mask); +guint gtk_accelerator_get_default_mod_mask (void); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_ACCEL_GROUP_H__ */ diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c new file mode 100644 index 0000000000..2a10e8f8f7 --- /dev/null +++ b/gtk/gtkaccellabel.c @@ -0,0 +1,442 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkAccelLabel: GtkLabel with accelerator monitoring facilities. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include <string.h> +#include <ctype.h> +#include "gtkmain.h" +#include "gtksignal.h" +#include "gtkaccellabel.h" + + +enum { + ARG_0, + ARG_ACCEL_WIDGET, +}; + +static void gtk_accel_label_class_init (GtkAccelLabelClass *klass); +static void gtk_accel_label_init (GtkAccelLabel *accel_label); +static void gtk_accel_label_set_arg (GtkAccelLabel *accel_label, + GtkArg *arg, + guint arg_id); +static void gtk_accel_label_get_arg (GtkAccelLabel *accel_label, + GtkArg *arg, + guint arg_id); +static void gtk_accel_label_destroy (GtkObject *object); +static void gtk_accel_label_finalize (GtkObject *object); +static void gtk_accel_label_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static gint gtk_accel_label_expose_event (GtkWidget *widget, + GdkEventExpose *event); + +static GtkAccelLabelClass *accel_label_class = NULL; +static GtkLabelClass *parent_class = NULL; + + +GtkType +gtk_accel_label_get_type (void) +{ + static GtkType accel_label_type = 0; + + if (!accel_label_type) + { + GtkTypeInfo accel_label_info = + { + "GtkAccelLabel", + sizeof (GtkAccelLabel), + sizeof (GtkAccelLabelClass), + (GtkClassInitFunc) gtk_accel_label_class_init, + (GtkObjectInitFunc) gtk_accel_label_init, + (GtkArgSetFunc) gtk_accel_label_set_arg, + (GtkArgGetFunc) gtk_accel_label_get_arg, + }; + + accel_label_type = gtk_type_unique (gtk_label_get_type (), &accel_label_info); + } + + return accel_label_type; +} + +static void +gtk_accel_label_class_init (GtkAccelLabelClass *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkMiscClass *misc_class; + GtkLabelClass *label_class; + + accel_label_class = class; + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + misc_class = (GtkMiscClass*) class; + label_class = (GtkLabelClass*) class; + + parent_class = gtk_type_class (gtk_label_get_type ()); + + gtk_object_add_arg_type ("GtkAccelLabel::accel_widget", GTK_TYPE_WIDGET, GTK_ARG_READWRITE, ARG_ACCEL_WIDGET); + + object_class->destroy = gtk_accel_label_destroy; + object_class->finalize = gtk_accel_label_finalize; + + widget_class->size_request = gtk_accel_label_size_request; + widget_class->expose_event = gtk_accel_label_expose_event; + + class->signal_quote1 = g_strdup ("<:"); + class->signal_quote2 = g_strdup (":>"); + class->mod_name_shift = g_strdup ("Shft"); + class->mod_name_control = g_strdup ("Ctl"); + class->mod_name_alt = g_strdup ("Alt"); + class->mod_separator = g_strdup ("+"); + class->accel_seperator = g_strdup (" / "); + class->latin1_to_char = TRUE; +} + +static void +gtk_accel_label_set_arg (GtkAccelLabel *accel_label, + GtkArg *arg, + guint arg_id) +{ + switch (arg_id) + { + case ARG_ACCEL_WIDGET: + gtk_accel_label_set_accel_widget (accel_label, (GtkWidget*) GTK_VALUE_OBJECT (*arg)); + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static void +gtk_accel_label_get_arg (GtkAccelLabel *accel_label, + GtkArg *arg, + guint arg_id) +{ + switch (arg_id) + { + case ARG_ACCEL_WIDGET: + GTK_VALUE_OBJECT (*arg) = (GtkObject*) accel_label->accel_widget; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static void +gtk_accel_label_init (GtkAccelLabel *accel_label) +{ + accel_label->queue_id = 0; + accel_label->accel_padding = 3; + accel_label->accel_widget = NULL; + accel_label->accel_string = NULL; + + gtk_accel_label_refetch (accel_label); +} + +GtkWidget* +gtk_accel_label_new (const gchar *string) +{ + GtkAccelLabel *accel_label; + + g_return_val_if_fail (string != NULL, NULL); + + accel_label = gtk_type_new (GTK_TYPE_ACCEL_LABEL); + + gtk_label_set (GTK_LABEL (accel_label), string); + + return GTK_WIDGET (accel_label); +} + +static void +gtk_accel_label_destroy (GtkObject *object) +{ + GtkAccelLabel *accel_label; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_ACCEL_LABEL (object)); + + accel_label = GTK_ACCEL_LABEL (object); + + gtk_accel_label_set_accel_widget (accel_label, NULL); + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +static void +gtk_accel_label_finalize (GtkObject *object) +{ + GtkAccelLabel *accel_label; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_ACCEL_LABEL (object)); + + accel_label = GTK_ACCEL_LABEL (object); + + g_free (accel_label->accel_string); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gtk_accel_label_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkAccelLabel *accel_label; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_ACCEL_LABEL (widget)); + g_return_if_fail (requisition != NULL); + + accel_label = GTK_ACCEL_LABEL (widget); + + if (GTK_WIDGET_CLASS (parent_class)->size_request) + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); + + accel_label->accel_string_width = gdk_string_width (GTK_WIDGET (accel_label)->style->font, + accel_label->accel_string); + requisition->width += accel_label->accel_padding + accel_label->accel_string_width; +} + +static gint +gtk_accel_label_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + GtkMisc *misc; + GtkAccelLabel *accel_label; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_ACCEL_LABEL (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + accel_label = GTK_ACCEL_LABEL (widget); + misc = GTK_MISC (accel_label); + + if (GTK_WIDGET_DRAWABLE (accel_label)) + { + guint ac_width; + + ac_width = accel_label->accel_padding + accel_label->accel_string_width; + + if (widget->allocation.width > ac_width + misc->xpad * 2) + { + guint x; + guint y; + + widget->allocation.width -= ac_width; + if (GTK_WIDGET_CLASS (parent_class)->expose_event) + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + widget->allocation.width += ac_width; + + x = widget->allocation.x + widget->allocation.width - misc->xpad - ac_width; + + y = (widget->allocation.y * (1.0 - misc->yalign) + + (widget->allocation.y + widget->allocation.height - + (widget->requisition.height - misc->ypad * 2)) * + misc->yalign + widget->style->font->ascent) + 1.5; + + if (GTK_WIDGET_STATE (accel_label) == GTK_STATE_INSENSITIVE) + gdk_draw_string (widget->window, + widget->style->font, + widget->style->white_gc, + x + 1, + y + 1, + accel_label->accel_string); + + gdk_draw_string (widget->window, + widget->style->font, + widget->style->fg_gc[GTK_WIDGET_STATE (accel_label)], + x, + y, + accel_label->accel_string); + } + else + { + if (GTK_WIDGET_CLASS (parent_class)->expose_event) + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + } + } + + return TRUE; +} + +static void +gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label) +{ + g_return_if_fail (accel_label != NULL); + g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label)); + + if (accel_label->queue_id == 0) + accel_label->queue_id = gtk_idle_add_priority (GTK_PRIORITY_HIGH - 2, + (GtkFunction) gtk_accel_label_refetch, + accel_label); +} + +void +gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label, + GtkWidget *accel_widget) +{ + g_return_if_fail (accel_label != NULL); + g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label)); + if (accel_widget != NULL) + g_return_if_fail (GTK_IS_WIDGET (accel_widget)); + + if (accel_widget != accel_label->accel_widget) + { + if (accel_label->accel_widget) + { + gtk_signal_disconnect_by_func (GTK_OBJECT (accel_label->accel_widget), + GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch), + accel_label); + gtk_widget_unref (accel_label->accel_widget); + } + if (accel_label->queue_id) + { + gtk_idle_remove (accel_label->queue_id); + accel_label->queue_id = 0; + } + accel_label->accel_widget = accel_widget; + if (accel_label->accel_widget) + { + gtk_widget_ref (accel_label->accel_widget); + gtk_signal_connect_object_after (GTK_OBJECT (accel_label->accel_widget), + "add-accelerator", + GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch), + GTK_OBJECT (accel_label)); + gtk_signal_connect_object_after (GTK_OBJECT (accel_label->accel_widget), + "remove-accelerator", + GTK_SIGNAL_FUNC (gtk_accel_label_queue_refetch), + GTK_OBJECT (accel_label)); + } + } +} + +gboolean +gtk_accel_label_refetch (GtkAccelLabel *accel_label) +{ + GtkAccelLabelClass *class; + + g_return_val_if_fail (accel_label != NULL, FALSE); + g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE); + + class = GTK_ACCEL_LABEL_CLASS (GTK_OBJECT (accel_label)->klass); + + g_free (accel_label->accel_string); + accel_label->accel_string = NULL; + + if (accel_label->accel_widget) + { + GtkAccelEntry *entry = NULL; + GSList *slist; + + slist = gtk_accel_group_entries_from_object (GTK_OBJECT (accel_label->accel_widget)); + for (; slist; slist = slist->next) + { + entry = slist->data; + if (entry->accel_flags & GTK_ACCEL_VISIBLE) + { + GString *gstring; + gboolean had_mod; + + gstring = g_string_new (accel_label->accel_string); + if (gstring->len) + g_string_append (gstring, class->accel_seperator); + else + g_string_append (gstring, " "); + + if (entry->accel_flags & GTK_ACCEL_SIGNAL_VISIBLE) + { + g_string_append (gstring, class->signal_quote1); + g_string_append (gstring, gtk_signal_name (entry->signal_id)); + g_string_append (gstring, class->signal_quote2); + } + + had_mod = FALSE; + if (entry->accelerator_mods & GDK_SHIFT_MASK) + { + g_string_append (gstring, class->mod_name_shift); + had_mod = TRUE; + } + if (entry->accelerator_mods & GDK_CONTROL_MASK) + { + if (had_mod) + g_string_append (gstring, class->mod_separator); + g_string_append (gstring, class->mod_name_control); + had_mod = TRUE; + } + if (entry->accelerator_mods & GDK_MOD1_MASK) + { + if (had_mod) + g_string_append (gstring, class->mod_separator); + g_string_append (gstring, class->mod_name_alt); + had_mod = TRUE; + } + + if (had_mod) + g_string_append (gstring, class->mod_separator); + if (entry->accelerator_key < 0x80 || + (entry->accelerator_key > 0x80 && + entry->accelerator_key <= 0xff && + class->latin1_to_char)) + { + switch (entry->accelerator_key) + { + case ' ': + g_string_append (gstring, "Space"); + break; + case '\\': + g_string_append (gstring, "Backslash"); + break; + default: + g_string_append_c (gstring, toupper (entry->accelerator_key)); + break; + } + } + else + { + gchar *tmp; + + tmp = gtk_accelerator_name (entry->accelerator_key, 0); + if (tmp[0] != 0 && tmp[1] == 0) + tmp[0] = toupper (tmp[0]); + g_string_append (gstring, tmp); + g_free (tmp); + } + + g_free (accel_label->accel_string); + accel_label->accel_string = gstring->str; + g_string_free (gstring, FALSE); + } + } + } + + if (!accel_label->accel_string) + accel_label->accel_string = g_strdup (""); + + if (accel_label->queue_id) + { + gtk_idle_remove (accel_label->queue_id); + accel_label->queue_id = 0; + } + + gtk_widget_queue_resize (GTK_WIDGET (accel_label)); + + return FALSE; +} diff --git a/gtk/gtkaccellabel.h b/gtk/gtkaccellabel.h new file mode 100644 index 0000000000..9762e79c18 --- /dev/null +++ b/gtk/gtkaccellabel.h @@ -0,0 +1,83 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkAccelLabel: GtkLabel with accelerator monitoring facilities. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __GTK_ACCEL_LABEL_H__ +#define __GTK_ACCEL_LABEL_H__ + + +#include <gtk/gtklabel.h> + + +#ifdef __cplusplus +extern "C" { +#prgma } +#endif /* __cplusplus */ + + +#define GTK_TYPE_ACCEL_LABEL (gtk_accel_label_get_type ()) +#define GTK_ACCEL_LABEL(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_ACCEL_LABEL, GtkAccelLabel)) +#define GTK_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_ACCEL_LABEL, GtkAccelLabelClass)) +#define GTK_IS_ACCEL_LABEL(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_ACCEL_LABEL)) +#define GTK_IS_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ACCEL_LABEL)) + + +typedef struct _GtkAccelLabel GtkAccelLabel; +typedef struct _GtkAccelLabelClass GtkAccelLabelClass; + +struct _GtkAccelLabel +{ + GtkLabel label; + + guint queue_id; + guint accel_padding; + GtkWidget *accel_widget; + gchar *accel_string; + guint accel_string_width : 16; +}; + +struct _GtkAccelLabelClass +{ + GtkLabelClass parent_class; + + gchar *signal_quote1; + gchar *signal_quote2; + gchar *mod_name_shift; + gchar *mod_name_control; + gchar *mod_name_alt; + gchar *mod_separator; + gchar *accel_seperator; + guint latin1_to_char : 1; +}; + + +GtkType gtk_accel_label_get_type (void); +GtkWidget* gtk_accel_label_new (const gchar *string); +void gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label, + GtkWidget *accel_widget); +gboolean gtk_accel_label_refetch (GtkAccelLabel *accel_label); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_ACCEL_LABEL_H__ */ diff --git a/gtk/gtkbbox.c b/gtk/gtkbbox.c index 14b6177129..5ad1267c0d 100644 --- a/gtk/gtkbbox.c +++ b/gtk/gtkbbox.c @@ -29,10 +29,10 @@ static gint default_child_ipad_x = 7; static gint default_child_ipad_y = 0; -guint +GtkType gtk_button_box_get_type (void) { - static guint button_box_type = 0; + static GtkType button_box_type = 0; if (!button_box_type) { diff --git a/gtk/gtkbbox.h b/gtk/gtkbbox.h index 6ec7585926..703a7e795d 100644 --- a/gtk/gtkbbox.h +++ b/gtk/gtkbbox.h @@ -24,24 +24,19 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -#define GTK_BUTTON_BOX(obj) GTK_CHECK_CAST (obj, gtk_button_box_get_type (), GtkButtonBox) -#define GTK_BUTTON_BOX_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_button_box_get_type (), GtkButtonBoxClass) -#define GTK_IS_BUTTON_BOX(obj) GTK_CHECK_TYPE (obj, gtk_button_box_get_type ()) +#define GTK_TYPE_BUTTON_BOX (gtk_button_box_get_type ()) +#define GTK_BUTTON_BOX(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_BUTTON_BOX, GtkButtonBox)) +#define GTK_BUTTON_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_BUTTON_BOX, GtkButtonBoxClass)) +#define GTK_IS_BUTTON_BOX(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_BUTTON_BOX)) +#define GTK_IS_BUTTON_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_BUTTON_BOX)) #define GTK_BUTTONBOX_DEFAULT -1 -typedef enum { - GTK_BUTTONBOX_DEFAULT_STYLE, - GTK_BUTTONBOX_SPREAD, - GTK_BUTTONBOX_EDGE, - GTK_BUTTONBOX_START, - GTK_BUTTONBOX_END -} GtkButtonBoxStyle; - typedef struct _GtkButtonBox GtkButtonBox; typedef struct _GtkButtonBoxClass GtkButtonBoxClass; @@ -62,7 +57,7 @@ struct _GtkButtonBoxClass }; -guint gtk_button_box_get_type (void); +GtkType gtk_button_box_get_type (void); void gtk_button_box_get_child_size_default (gint *min_width, gint *min_height); void gtk_button_box_get_child_ipadding_default (gint *ipad_x, gint *ipad_y); diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c new file mode 100644 index 0000000000..c9e55181ed --- /dev/null +++ b/gtk/gtkbindings.c @@ -0,0 +1,1136 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkBindingSet: Keybinding manager for GtkObjects. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include <ctype.h> +#include <strings.h> +#include <stdarg.h> +#include "gtkbindings.h" +#include "gtksignal.h" +#include "gtkwidget.h" + + +/* --- defines --- */ +#define BINDING_MOD_MASK() (gtk_accelerator_get_default_mod_mask () | GDK_AFTER_MASK) + + +/* --- variables --- */ +static GHashTable *binding_entry_hash_table = NULL; +static GSList *binding_set_list = NULL; +static const gchar *key_class_binding_set = "gtk-class-binding-set"; +static guint key_id_class_binding_set = 0; + + +/* --- functions --- */ +static GtkBindingSignal* +binding_signal_new (const gchar *signal_name, + guint n_args) +{ + GtkBindingSignal *signal; + + signal = g_new (GtkBindingSignal, 1); + signal->next = NULL; + signal->signal_name = g_strdup (signal_name); + signal->n_args = n_args; + signal->args = g_new0 (GtkBindingArg, n_args); + + return signal; +} + +static void +binding_signal_free (GtkBindingSignal *sig) +{ + guint i; + + for (i = 0; i < sig->n_args; i++) + { + if (sig->args[i].arg_type == GTK_BINDING_ARG_STRING) + g_free (sig->args[i].d.string_data); + } + g_free (sig->args); + g_free (sig->signal_name); + g_free (sig); +} + +static guint +binding_entry_hash (gpointer key) +{ + register GtkBindingEntry *e = key; + register guint h; + + h = e->keyval; + h ^= e->modifiers; + + return h; +} + +static gint +binding_entries_compare (gpointer a, + gpointer b) +{ + register GtkBindingEntry *ea = a; + register GtkBindingEntry *eb = b; + + return (ea->keyval == eb->keyval && ea->modifiers == eb->modifiers); +} + +static GtkBindingEntry* +binding_entry_new (GtkBindingSet *binding_set, + guint keyval, + guint modifiers) +{ + GtkBindingEntry *entry; + + if (!binding_entry_hash_table) + binding_entry_hash_table = g_hash_table_new (binding_entry_hash, binding_entries_compare); + + entry = g_new (GtkBindingEntry, 1); + entry->keyval = keyval; + entry->modifiers = modifiers; + entry->binding_set = binding_set, + entry->destroyed = FALSE; + entry->in_emission = FALSE; + entry->signals = NULL; + + entry->set_next = binding_set->entries; + binding_set->entries = entry; + + entry->hash_next = g_hash_table_lookup (binding_entry_hash_table, entry); + g_hash_table_freeze (binding_entry_hash_table); + if (entry->hash_next) + g_hash_table_remove (binding_entry_hash_table, entry->hash_next); + g_hash_table_insert (binding_entry_hash_table, entry, entry); + g_hash_table_thaw (binding_entry_hash_table); + + return entry; +} + +static void +binding_entry_free (GtkBindingEntry *entry) +{ + GtkBindingSignal *sig; + + g_assert (entry->set_next == NULL && + entry->hash_next == NULL && + entry->in_emission == FALSE && + entry->destroyed == TRUE); + + entry->destroyed = FALSE; + + sig = entry->signals; + while (sig) + { + GtkBindingSignal *prev; + + prev = sig; + sig = prev->next; + binding_signal_free (prev); + } + g_free (entry); +} + +static void +binding_entry_destroy (GtkBindingEntry *entry) +{ + GtkBindingEntry *o_entry; + register GtkBindingEntry *tmp; + GtkBindingEntry *begin; + register GtkBindingEntry *last; + + /* unlink from binding set + */ + last = NULL; + tmp = entry->binding_set->entries; + while (tmp) + { + if (tmp == entry) + { + if (last) + last->set_next = entry->set_next; + else + entry->binding_set->entries = entry->set_next; + break; + } + last = tmp; + tmp = last->set_next; + } + entry->set_next = NULL; + + o_entry = g_hash_table_lookup (binding_entry_hash_table, entry); + begin = o_entry; + last = NULL; + tmp = begin; + while (tmp) + { + if (tmp == entry) + { + if (last) + last->hash_next = entry->hash_next; + else + begin = entry->hash_next; + break; + } + last = tmp; + tmp = last->hash_next; + } + entry->hash_next = NULL; + + if (!begin) + g_hash_table_remove (binding_entry_hash_table, entry); + else if (begin != o_entry) + { + g_hash_table_freeze (binding_entry_hash_table); + g_hash_table_remove (binding_entry_hash_table, entry); + g_hash_table_insert (binding_entry_hash_table, begin, begin); + g_hash_table_thaw (binding_entry_hash_table); + } + + entry->destroyed = TRUE; + + if (!entry->in_emission) + binding_entry_free (entry); +} + +static GtkBindingEntry* +binding_ht_lookup_list (guint keyval, + guint modifiers) +{ + GtkBindingEntry lookup_entry = { 0 }; + + if (!binding_entry_hash_table) + return NULL; + + lookup_entry.keyval = keyval; + lookup_entry.modifiers = modifiers; + + return g_hash_table_lookup (binding_entry_hash_table, &lookup_entry); +} + +static GtkBindingEntry* +binding_ht_lookup_entry (GtkBindingSet *set, + guint keyval, + guint modifiers) +{ + GtkBindingEntry lookup_entry = { 0 }; + GtkBindingEntry *entry; + + if (!binding_entry_hash_table) + return NULL; + + lookup_entry.keyval = keyval; + lookup_entry.modifiers = modifiers; + + entry = g_hash_table_lookup (binding_entry_hash_table, &lookup_entry); + for (; entry; entry = entry->hash_next) + if (entry->binding_set == set) + return entry; + + return NULL; +} + +static gboolean +binding_compose_params (GtkBindingArg *args, + GtkSignalQuery *query, + GtkArg **params_p) +{ + GtkArg *params; + const GtkType *types; + guint i; + gboolean valid; + + params = g_new0 (GtkArg, query->nparams); + *params_p = params; + + types = query->params; + valid = TRUE; + for (i = 0; i < query->nparams && valid; i++) + { + params->type = *types; + params->name = NULL; + switch (args->arg_type) + { + case GTK_BINDING_ARG_STRING: + if (params->type == GTK_TYPE_STRING) + GTK_VALUE_STRING (*params) = args->d.string_data; + else + valid = FALSE; + break; + case GTK_BINDING_ARG_DOUBLE: + if (params->type == GTK_TYPE_FLOAT) + GTK_VALUE_FLOAT (*params) = args->d.double_data; + else if (params->type == GTK_TYPE_DOUBLE) + GTK_VALUE_DOUBLE (*params) = args->d.double_data; + else + valid = FALSE; + break; + case GTK_BINDING_ARG_LONG: + if (params->type == GTK_TYPE_BOOL && + (args->d.long_data == 0 || + args->d.long_data == 1)) + GTK_VALUE_BOOL (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_INT) + GTK_VALUE_INT (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_UINT && + args->d.long_data >= 0) + GTK_VALUE_UINT (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_LONG) + GTK_VALUE_LONG (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_ULONG && + args->d.long_data >= 0) + GTK_VALUE_ULONG (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_FLOAT) + GTK_VALUE_FLOAT (*params) = args->d.long_data; + else if (params->type == GTK_TYPE_DOUBLE) + GTK_VALUE_DOUBLE (*params) = args->d.long_data; + else + valid = FALSE; + break; + default: + valid = FALSE; + break; + } + types++; + params++; + args++; + } + + if (!valid) + { + g_free (*params_p); + *params_p = NULL; + } + + return valid; +} + +static void +gtk_binding_entry_activate (GtkBindingEntry *entry, + GtkObject *object) +{ + GtkBindingSignal *sig; + gboolean old_emission; + + old_emission = entry->in_emission; + entry->in_emission = TRUE; + + gtk_object_ref (object); + + for (sig = entry->signals; sig; sig = sig->next) + { + GtkSignalQuery *query; + guint signal_id; + GtkArg *params = NULL; + + signal_id = gtk_signal_lookup (sig->signal_name, GTK_OBJECT_TYPE (object)); + if (!signal_id) + { + gchar *accelerator; + + accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers); + g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": " + "could not find signal \"%s\" in the `%s' class ancestry", + entry->binding_set->set_name, + accelerator, + sig->signal_name, + gtk_type_name (GTK_OBJECT_TYPE (object))); + g_free (accelerator); + continue; + } + + query = gtk_signal_query (signal_id); + if (query->nparams != sig->n_args || + query->return_val != GTK_TYPE_NONE || + !binding_compose_params (sig->args, query, ¶ms)) + { + gchar *accelerator; + + accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers); + g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": " + "signature mismatch for signal \"%s\" in the `%s' class ancestry", + entry->binding_set->set_name, + accelerator, + sig->signal_name, + gtk_type_name (GTK_OBJECT_TYPE (object))); + g_free (accelerator); + g_free (query); + continue; + } + g_free (query); + + gtk_signal_emitv (object, signal_id, params); + g_free (params); + + if (GTK_OBJECT_DESTROYED (object) || entry->destroyed) + break; + } + + gtk_object_unref (object); + + entry->in_emission = old_emission; + if (entry->destroyed && !entry->in_emission) + binding_entry_free (entry); +} + +GtkBindingSet* +gtk_binding_set_new (const gchar *set_name) +{ + GtkBindingSet *binding_set; + + g_return_val_if_fail (set_name != NULL, NULL); + + binding_set = g_new (GtkBindingSet, 1); + binding_set->set_name = g_strdup (set_name); + binding_set->widget_path_pspecs = NULL; + binding_set->widget_class_pspecs = NULL; + binding_set->class_branch_pspecs = NULL; + binding_set->entries = NULL; + binding_set->current = NULL; + + binding_set_list = g_slist_prepend (NULL, binding_set); + + return binding_set; +} + +GtkBindingSet* +gtk_binding_set_by_class (gpointer object_class) +{ + GtkObjectClass *class = object_class; + GtkBindingSet* binding_set; + + g_return_val_if_fail (GTK_IS_OBJECT_CLASS (class), NULL); + + if (!key_id_class_binding_set) + key_id_class_binding_set = g_dataset_force_id (key_class_binding_set); + + binding_set = g_dataset_id_get_data (class, key_id_class_binding_set); + + if (binding_set) + return binding_set; + + binding_set = gtk_binding_set_new (gtk_type_name (class->type)); + gtk_binding_set_add_path (binding_set, + GTK_PATH_CLASS, + gtk_type_name (class->type), + GTK_PATH_PRIO_GTK); + g_dataset_id_set_data (class, key_id_class_binding_set, binding_set); + + return binding_set; +} + +GtkBindingSet* +gtk_binding_set_find (const gchar *set_name) +{ + GSList *slist; + + g_return_val_if_fail (set_name != NULL, NULL); + + for (slist = binding_set_list; slist; slist = slist->next) + { + GtkBindingSet *binding_set; + + binding_set = slist->data; + if (g_str_equal (binding_set->set_name, (gpointer) set_name)) + return binding_set; + } + return NULL; +} + +gboolean +gtk_binding_set_activate (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + GtkObject *object) +{ + GtkBindingEntry *entry; + + g_return_val_if_fail (binding_set != NULL, FALSE); + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + if (!GTK_OBJECT_DESTROYED (object)) + { + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + if (entry) + { + gtk_binding_entry_activate (entry, object); + + return TRUE; + } + } + + return FALSE; +} + +void +gtk_binding_entry_clear (GtkBindingSet *binding_set, + guint keyval, + guint modifiers) +{ + GtkBindingEntry *entry; + + g_return_if_fail (binding_set != NULL); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + if (entry) + binding_entry_destroy (entry); + + entry = binding_entry_new (binding_set, keyval, modifiers); +} + +void +gtk_binding_entry_remove (GtkBindingSet *binding_set, + guint keyval, + guint modifiers) +{ + GtkBindingEntry *entry; + + g_return_if_fail (binding_set != NULL); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + if (entry) + binding_entry_destroy (entry); +} + +void +gtk_binding_entry_add_signall (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + const gchar *signal_name, + GSList *binding_args) +{ + GtkBindingEntry *entry; + GtkBindingSignal *signal, **signal_p; + GSList *slist; + guint n = 0; + GtkBindingArg *arg; + + g_return_if_fail (binding_set != NULL); + g_return_if_fail (signal_name != NULL); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + signal = binding_signal_new (signal_name, g_slist_length (binding_args)); + + arg = signal->args; + for (slist = binding_args; slist; slist = slist->next) + { + GtkBindingArg *tmp_arg; + + tmp_arg = slist->data; + if (!tmp_arg) + { + g_warning ("gtk_binding_entry_add_signall(): arg[%u] is `NULL'", n); + binding_signal_free (signal); + return; + } + arg->arg_type = tmp_arg->arg_type; + switch (tmp_arg->arg_type) + { + case GTK_BINDING_ARG_INT: + case GTK_BINDING_ARG_LONG: + arg->d.long_data = tmp_arg->d.long_data; + break; + case GTK_BINDING_ARG_FLOAT: + case GTK_BINDING_ARG_DOUBLE: + arg->d.double_data = tmp_arg->d.double_data; + break; + case GTK_BINDING_ARG_STRING: + if (!tmp_arg->d.string_data) + { + g_warning ("gtk_binding_entry_add_signall(): value of `string' arg[%u] is `NULL'", n); + arg->d.string_data = NULL; + binding_signal_free (signal); + return; + } + arg->d.string_data = g_strdup (tmp_arg->d.string_data); + break; + default: + g_warning ("gtk_binding_entry_add_signall(): unsupported type `%s' for arg[%u]", + gtk_type_name (arg->arg_type), n); + binding_signal_free (signal); + return; + } + arg++; + n++; + } + + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + if (!entry) + { + gtk_binding_entry_add (binding_set, keyval, modifiers); + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + } + signal_p = &entry->signals; + while (*signal_p) + signal_p = &(*signal_p)->next; + *signal_p = signal; +} + +void +gtk_binding_entry_add_signal (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + const gchar *signal_name, + guint n_args, + ...) +{ + GSList *slist, *free_slist; + va_list args; + guint i; + + g_return_if_fail (binding_set != NULL); + g_return_if_fail (signal_name != NULL); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + va_start (args, n_args); + slist = NULL; + for (i = 0; i < n_args; i++) + { + GtkBindingArg *arg; + + arg = g_new0 (GtkBindingArg, 1); + slist = g_slist_prepend (slist, arg); + + arg->arg_type = va_arg (args, GtkType); + switch (arg->arg_type) + { + case GTK_BINDING_ARG_INT: + arg->d.long_data = va_arg (args, gint); + break; + case GTK_BINDING_ARG_LONG: + arg->d.long_data = va_arg (args, glong); + break; + case GTK_BINDING_ARG_FLOAT: + arg->d.double_data = va_arg (args, gfloat); + break; + case GTK_BINDING_ARG_DOUBLE: + arg->d.double_data = va_arg (args, gdouble); + break; + case GTK_BINDING_ARG_STRING: + arg->d.string_data = va_arg (args, gchar*); + if (!arg->d.string_data) + { + g_warning ("gtk_binding_entry_add_signal(): value of `string' arg[%u] is `NULL'", i); + i = n_args + 2; + } + break; + default: + g_warning ("gtk_binding_entry_add_signal(): unsupported type `%s' for arg[%u]", + gtk_type_name (arg->arg_type), i); + i = n_args + 2; + break; + } + } + va_end (args); + + if (i == n_args + 1 || i == 0) + { + slist = g_slist_reverse (slist); + gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist); + } + + free_slist = slist; + while (slist) + { + g_free (slist->data); + slist = slist->next; + } + g_slist_free (free_slist); +} + +void +gtk_binding_set_add_path (GtkBindingSet *binding_set, + GtkPathType path_type, + const gchar *path_pattern, + GtkPathPriorityType priority) +{ + GtkPatternSpec *pspec; + GSList **slist_p, *slist; + static guint seq_id = 0; + + g_return_if_fail (binding_set != NULL); + g_return_if_fail (path_pattern != NULL); + + priority &= GTK_PATH_PRIO_MASK; + + switch (path_type) + { + case GTK_PATH_WIDGET: + slist_p = &binding_set->widget_path_pspecs; + break; + case GTK_PATH_WIDGET_CLASS: + slist_p = &binding_set->widget_class_pspecs; + break; + case GTK_PATH_CLASS: + slist_p = &binding_set->class_branch_pspecs; + break; + default: + g_assert_not_reached (); + slist_p = NULL; + break; + } + + pspec = g_new (GtkPatternSpec, 1); + gtk_pattern_spec_init (pspec, path_pattern); + pspec->seq_id = seq_id++ & 0x0fffffff; + pspec->seq_id |= priority << 28; + pspec->user_data = binding_set; + + slist = *slist_p; + while (slist) + { + GtkPatternSpec *tmp_pspec; + + tmp_pspec = slist->data; + slist = slist->next; + + if (tmp_pspec->pattern_length == pspec->pattern_length && + g_str_equal (tmp_pspec->pattern_reversed, pspec->pattern_reversed)) + { + gtk_pattern_spec_free_segs (pspec); + g_free (pspec); + pspec = NULL; + } + } + if (pspec) + *slist_p = g_slist_prepend (*slist_p, pspec); +} + +static inline gboolean +binding_match_activate (GSList *pspec_list, + GtkObject *object, + guint path_length, + gchar *path, + gchar *path_reversed) +{ + GSList *slist; + + for (slist = pspec_list; slist; slist = slist->next) + { + GtkPatternSpec *pspec; + + pspec = slist->data; + if (gtk_pattern_match (pspec, path_length, path, path_reversed)) + { + GtkBindingSet *binding_set; + + binding_set = pspec->user_data; + + gtk_binding_entry_activate (binding_set->current, object); + + return TRUE; + } + } + + return FALSE; +} + +static gint +gtk_binding_pattern_compare (gpointer a, + gpointer b) +{ + register GtkPatternSpec *pa = a; + register GtkPatternSpec *pb = b; + + return pa->seq_id < pb->seq_id ? -1 : 1; +} + +static inline GSList* +gtk_binding_entries_sort_patterns (GtkBindingEntry *entries, + GtkPathType path_id) +{ + GSList *patterns; + + patterns = NULL; + while (entries) + { + register GtkBindingSet *binding_set; + GSList *slist = NULL; + + binding_set = entries->binding_set; + binding_set->current = entries; + + switch (path_id) + { + case GTK_PATH_WIDGET: + slist = binding_set->widget_path_pspecs; + break; + case GTK_PATH_WIDGET_CLASS: + slist = binding_set->widget_class_pspecs; + break; + case GTK_PATH_CLASS: + slist = binding_set->class_branch_pspecs; + break; + } + + for (; slist; slist = slist->next) + { + GtkPatternSpec *pspec; + + pspec = slist->data; + patterns = g_slist_insert_sorted (patterns, pspec, gtk_binding_pattern_compare); + } + + entries = entries->hash_next; + } + + return patterns; +} + + +gboolean +gtk_bindings_activate (GtkObject *object, + guint keyval, + guint modifiers) +{ + GtkBindingEntry *entries; + GtkWidget *widget; + gboolean handled = FALSE; + + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE); + + if (!GTK_IS_WIDGET (object) || GTK_OBJECT_DESTROYED (object)) + return FALSE; + + widget = GTK_WIDGET (object); + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + entries = binding_ht_lookup_list (keyval, modifiers); + + if (!entries) + return FALSE; + + if (!handled) + { + guint path_length; + gchar *path, *path_reversed; + GSList *patterns; + + gtk_widget_path (widget, &path_length, &path, &path_reversed); + patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET); + handled = binding_match_activate (patterns, object, path_length, path, path_reversed); + g_slist_free (patterns); + g_free (path); + g_free (path_reversed); + } + + if (!handled) + { + guint path_length; + gchar *path, *path_reversed; + GSList *patterns; + + gtk_widget_class_path (widget, &path_length, &path, &path_reversed); + patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET_CLASS); + handled = binding_match_activate (patterns, object, path_length, path, path_reversed); + g_slist_free (patterns); + g_free (path); + g_free (path_reversed); + } + + if (!handled) + { + GSList *patterns; + GtkType class_type; + + patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_CLASS); + class_type = GTK_OBJECT_TYPE (object); + while (class_type && !handled) + { + guint path_length; + gchar *path, *path_reversed; + + path = gtk_type_name (class_type); + path_reversed = g_strdup (path); + g_strreverse (path_reversed); + path_length = strlen (path); + handled = binding_match_activate (patterns, object, path_length, path, path_reversed); + g_free (path_reversed); + + class_type = gtk_type_parent (class_type); + } + g_slist_free (patterns); + } + + return handled; +} + + + + + + + + + + +/* Patterns + */ + +static inline gboolean +gtk_pattern_ph_match (const gchar *match_pattern, + const gchar *match_string) +{ + register const gchar *pattern, *string; + register gchar ch; + + pattern = match_pattern; + string = match_string; + + ch = *pattern; + pattern++; + while (ch) + { + switch (ch) + { + case '?': + if (!*string) + return FALSE; + string++; + break; + + case '*': + do + { + ch = *pattern; + pattern++; + if (ch == '?') + { + if (!*string) + return FALSE; + string++; + } + } + while (ch == '*' || ch == '?'); + if (!ch) + return TRUE; + do + { + while (ch != *string) + { + if (!*string) + return FALSE; + string++; + } + string++; + if (gtk_pattern_ph_match (pattern, string)) + return TRUE; + } + while (*string); + break; + + default: + if (ch == *string) + string++; + else + return FALSE; + break; + } + + ch = *pattern; + pattern++; + } + + return *string == 0; +} + +gboolean +gtk_pattern_match (GtkPatternSpec *pspec, + guint string_length, + const gchar *string, + const gchar *string_reversed) +{ + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (string_reversed != NULL, FALSE); + + switch (pspec->match_type) + { + case GTK_MATCH_ALL: + return gtk_pattern_ph_match (pspec->pattern, string); + + case GTK_MATCH_ALL_TAIL: + return gtk_pattern_ph_match (pspec->pattern_reversed, string_reversed); + + case GTK_MATCH_HEAD: + if (pspec->pattern_length > string_length) + return FALSE; + else if (pspec->pattern_length == string_length) + return strcmp (pspec->pattern, string) == 0; + else if (pspec->pattern_length) + return strncmp (pspec->pattern, string, pspec->pattern_length) == 0; + else + return TRUE; + + case GTK_MATCH_TAIL: + if (pspec->pattern_length > string_length) + return FALSE; + else if (pspec->pattern_length == string_length) + return strcmp (pspec->pattern_reversed, string_reversed) == 0; + else if (pspec->pattern_length) + return strncmp (pspec->pattern_reversed, + string_reversed, + pspec->pattern_length) == 0; + else + return TRUE; + + case GTK_MATCH_EXACT: + if (pspec->pattern_length != string_length) + return FALSE; + else + return strcmp (pspec->pattern_reversed, string_reversed) == 0; + + default: + g_return_val_if_fail (pspec->match_type < GTK_MATCH_LAST, FALSE); + return FALSE; + } +} + +void +gtk_pattern_spec_init (GtkPatternSpec *pspec, + const gchar *pattern) +{ + gchar *p; + + g_return_if_fail (pspec != NULL); + + pspec->match_type = GTK_MATCH_ALL; + pspec->seq_id = 0; + pspec->user_data = NULL; + + if (!pattern) + pattern = ""; + + pspec->pattern = g_strdup (pattern); + pspec->pattern_length = strlen (pspec->pattern); + pspec->pattern_reversed = g_strdup (pspec->pattern); + g_strreverse (pspec->pattern_reversed); + if (pspec->pattern_reversed[0] != '*') + pspec->match_type = GTK_MATCH_ALL_TAIL; + + if (strchr (pspec->pattern, '?')) + return; + + if (!strchr (pspec->pattern, '*')) + { + pspec->match_type = GTK_MATCH_EXACT; + return; + } + + p = pspec->pattern; + while (*p == '*') + p++; + if (p > pspec->pattern && + !strchr (p, '*')) + { + gchar *t; + + pspec->match_type = GTK_MATCH_TAIL; + t = pspec->pattern; + pspec->pattern = g_strdup (p); + g_free (t); + g_free (pspec->pattern_reversed); + pspec->pattern_reversed = g_strdup (pspec->pattern); + g_strreverse (pspec->pattern_reversed); + pspec->pattern_length = strlen (pspec->pattern); + return; + } + + p = pspec->pattern_reversed; + while (*p == '*') + p++; + if (p > pspec->pattern_reversed && + !strchr (p, '*')) + { + gchar *t; + + pspec->match_type = GTK_MATCH_HEAD; + t = pspec->pattern_reversed; + pspec->pattern_reversed = g_strdup (p); + g_free (t); + pspec->pattern = g_strdup (pspec->pattern_reversed); + g_strreverse (pspec->pattern); + pspec->pattern_length = strlen (pspec->pattern); + } +} + +gboolean +gtk_pattern_match_string (GtkPatternSpec *pspec, + const gchar *string) +{ + gchar *string_reversed; + guint length; + gboolean ergo; + + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + length = strlen (string); + string_reversed = g_strdup (string); + g_strreverse (string_reversed); + + ergo = gtk_pattern_match (pspec, length, string, string_reversed); + g_free (string_reversed); + + return ergo; +} + +gboolean +gtk_pattern_match_simple (const gchar *pattern, + const gchar *string) +{ + GtkPatternSpec pspec; + gboolean ergo; + + g_return_val_if_fail (pattern != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + gtk_pattern_spec_init (&pspec, pattern); + ergo = gtk_pattern_match_string (&pspec, string); + gtk_pattern_spec_free_segs (&pspec); + + return ergo; +} + +void +gtk_pattern_spec_free_segs (GtkPatternSpec *pspec) +{ + g_return_if_fail (pspec != NULL); + + g_free (pspec->pattern); + pspec->pattern = NULL; + g_free (pspec->pattern_reversed); + pspec->pattern_reversed = NULL; +} diff --git a/gtk/gtkbindings.h b/gtk/gtkbindings.h new file mode 100644 index 0000000000..d9ed4033d8 --- /dev/null +++ b/gtk/gtkbindings.h @@ -0,0 +1,166 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkBindingSet: Keybinding manager for GtkObjects. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __GTK_BINDINGS_H__ +#define __GTK_BINDINGS_H__ + + +#include <gdk/gdk.h> +#include <gtk/gtkobject.h> +#include <gtk/gtkenums.h> + + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + +/* Pattern matching + */ +typedef struct _GtkPatternSpec GtkPatternSpec; + +struct _GtkPatternSpec +{ + GtkMatchType match_type; + guint pattern_length; + gchar *pattern; + gchar *pattern_reversed; + gpointer user_data; + guint seq_id; +}; + +void gtk_pattern_spec_init (GtkPatternSpec *pspec, + const gchar *pattern); +void gtk_pattern_spec_free_segs (GtkPatternSpec *pspec); +gboolean gtk_pattern_match (GtkPatternSpec *pspec, + guint string_length, + const gchar *string, + const gchar *string_reversed); +gboolean gtk_pattern_match_string (GtkPatternSpec *pspec, + const gchar *string); +gboolean gtk_pattern_match_simple (const gchar *pattern, + const gchar *string); + + +/* Binding sets + */ + +#define GTK_BINDING_ARG_INT (GTK_TYPE_INT) +#define GTK_BINDING_ARG_LONG (GTK_TYPE_LONG) +#define GTK_BINDING_ARG_FLOAT (GTK_TYPE_FLOAT) +#define GTK_BINDING_ARG_DOUBLE (GTK_TYPE_DOUBLE) +#define GTK_BINDING_ARG_STRING (GTK_TYPE_STRING) + +typedef struct _GtkBindingSet GtkBindingSet; +typedef struct _GtkBindingEntry GtkBindingEntry; +typedef struct _GtkBindingSignal GtkBindingSignal; +typedef struct _GtkBindingArg GtkBindingArg; + +struct _GtkBindingSet +{ + gchar *set_name; + gint priority; + GSList *widget_path_pspecs; + GSList *widget_class_pspecs; + GSList *class_branch_pspecs; + GtkBindingEntry *entries; + GtkBindingEntry *current; +}; + +struct _GtkBindingEntry +{ + /* key portion + */ + guint keyval; + guint modifiers; + + GtkBindingSet *binding_set; + guint destroyed : 1; + guint in_emission : 1; + GtkBindingEntry *set_next; + GtkBindingEntry *hash_next; + GtkBindingSignal *signals; +}; + +struct _GtkBindingSignal +{ + GtkBindingSignal *next; + gchar *signal_name; + guint n_args; + GtkBindingArg *args; +}; + +struct _GtkBindingArg +{ + GtkType arg_type; + union { + glong long_data; + gdouble double_data; + gchar *string_data; + } d; +}; + +/* Binding sets + */ +GtkBindingSet* gtk_binding_set_new (const gchar *set_name); +GtkBindingSet* gtk_binding_set_by_class(gpointer object_class); +GtkBindingSet* gtk_binding_set_find (const gchar *set_name); +gboolean gtk_bindings_activate (GtkObject *object, + guint keyval, + guint modifiers); +gboolean gtk_binding_set_activate (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + GtkObject *object); +#define gtk_binding_entry_add gtk_binding_entry_clear +void gtk_binding_entry_clear (GtkBindingSet *binding_set, + guint keyval, + guint modifiers); +void gtk_binding_entry_remove (GtkBindingSet *binding_set, + guint keyval, + guint modifiers); +void gtk_binding_entry_add_signal (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + const gchar *signal_name, + guint n_args, + ...); +void gtk_binding_entry_add_signall (GtkBindingSet *binding_set, + guint keyval, + guint modifiers, + const gchar *signal_name, + GSList *binding_args); +void gtk_binding_set_add_path (GtkBindingSet *binding_set, + GtkPathType path_type, + const gchar *path_pattern, + GtkPathPriorityType priority); + + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_BINDINGS_H__ */ diff --git a/gtk/gtkcheckmenuitem.c b/gtk/gtkcheckmenuitem.c index 40e9deb1ac..91489b098f 100644 --- a/gtk/gtkcheckmenuitem.c +++ b/gtk/gtkcheckmenuitem.c @@ -17,7 +17,7 @@ * Boston, MA 02111-1307, USA. */ #include "gtkcheckmenuitem.h" -#include "gtklabel.h" +#include "gtkaccellabel.h" #include "gtksignal.h" @@ -81,14 +81,15 @@ GtkWidget* gtk_check_menu_item_new_with_label (const gchar *label) { GtkWidget *check_menu_item; - GtkWidget *label_widget; + GtkWidget *accel_label; check_menu_item = gtk_check_menu_item_new (); - label_widget = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); + accel_label = gtk_accel_label_new (label); + gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5); - gtk_container_add (GTK_CONTAINER (check_menu_item), label_widget); - gtk_widget_show (label_widget); + gtk_container_add (GTK_CONTAINER (check_menu_item), accel_label); + gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), check_menu_item); + gtk_widget_show (accel_label); return check_menu_item; } diff --git a/gtk/gtkctree.c b/gtk/gtkctree.c index 971a492ba2..06fa147ab1 100644 --- a/gtk/gtkctree.c +++ b/gtk/gtkctree.c @@ -3557,9 +3557,8 @@ gtk_ctree_get_row_data (GtkCTree *ctree, { g_return_val_if_fail (ctree != NULL, NULL); g_return_val_if_fail (GTK_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - return GTK_CTREE_ROW (node)->row.data; + return node ? GTK_CTREE_ROW (node)->row.data : NULL; } void diff --git a/gtk/gtkcurve.c b/gtk/gtkcurve.c index 169c885bbf..d275e44ec7 100644 --- a/gtk/gtkcurve.c +++ b/gtk/gtkcurve.c @@ -51,10 +51,10 @@ static gint gtk_curve_graph_events (GtkWidget *widget, GtkCurve *c); static void gtk_curve_size_graph (GtkCurve *curve); -guint +GtkType gtk_curve_get_type (void) { - static guint curve_type = 0; + static GtkType curve_type = 0; if (!curve_type) { diff --git a/gtk/gtkcurve.h b/gtk/gtkcurve.h index eec009ca74..20755692eb 100644 --- a/gtk/gtkcurve.h +++ b/gtk/gtkcurve.h @@ -25,23 +25,20 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -#define GTK_CURVE(obj) (GTK_CHECK_CAST ((obj), gtk_curve_get_type (), GtkCurve)) -#define GTK_CURVE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), gtk_curve_get_type (), GtkCurveClass)) -#define GTK_IS_CURVE(obj) (GTK_CHECK_TYPE ((obj), gtk_curve_get_type ())) +#define GTK_TYPE_CURVE (gtk_curve_get_type ()) +#define GTK_CURVE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_CURVE, GtkCurve)) +#define GTK_CURVE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_CURVE, GtkCurveClass)) +#define GTK_IS_CURVE(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_CURVE)) +#define GTK_IS_CURVE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CURVE)) typedef struct _GtkCurve GtkCurve; typedef struct _GtkCurveClass GtkCurveClass; -typedef enum -{ - GTK_CURVE_TYPE_LINEAR, /* linear interpolation */ - GTK_CURVE_TYPE_SPLINE, /* spline interpolation */ - GTK_CURVE_TYPE_FREE /* free form curve */ -} GtkCurveType; struct _GtkCurve { @@ -75,7 +72,7 @@ struct _GtkCurveClass }; -guint gtk_curve_get_type (void); +GtkType gtk_curve_get_type (void); GtkWidget* gtk_curve_new (void); void gtk_curve_reset (GtkCurve *curve); void gtk_curve_set_gamma (GtkCurve *curve, gfloat gamma); diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 130ed1091c..26d3b7a593 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -21,47 +21,28 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -/* Widget states */ -typedef enum -{ - GTK_STATE_NORMAL, - GTK_STATE_ACTIVE, - GTK_STATE_PRELIGHT, - GTK_STATE_SELECTED, - GTK_STATE_INSENSITIVE -} GtkStateType; - -/* Window types */ -typedef enum -{ - GTK_WINDOW_TOPLEVEL, - GTK_WINDOW_DIALOG, - GTK_WINDOW_POPUP -} GtkWindowType; - -/* Focus movement types */ -typedef enum -{ - GTK_DIR_TAB_FORWARD, - GTK_DIR_TAB_BACKWARD, - GTK_DIR_UP, - GTK_DIR_DOWN, - GTK_DIR_LEFT, - GTK_DIR_RIGHT -} GtkDirectionType; +/* the enum definitions in this file are ordered alphabetically. + * this file *must* be kept in sync with gtk.defs + */ -/* Shadow types */ +/* Accelerator flags */ typedef enum { - GTK_SHADOW_NONE, - GTK_SHADOW_IN, - GTK_SHADOW_OUT, - GTK_SHADOW_ETCHED_IN, - GTK_SHADOW_ETCHED_OUT -} GtkShadowType; + GTK_ACCEL_VISIBLE = 1 << 0 /* should the accelerator appear in + * the widget's display? + */, + GTK_ACCEL_SIGNAL_VISIBLE = 1 << 1 /* should the signal associated with + * this accelerator be also visible? + */, + GTK_ACCEL_LOCKED = 1 << 2 /* may the accelerator be removed + * again? + */, + GTK_ACCEL_MASK = 0x07 +} GtkAccelFlags; /* Arrow types */ typedef enum @@ -72,28 +53,6 @@ typedef enum GTK_ARROW_RIGHT } GtkArrowType; -/* Packing types (for boxes) */ -typedef enum -{ - GTK_PACK_START, - GTK_PACK_END -} GtkPackType; - -/* Scrollbar policy types (for scrolled windows) */ -typedef enum -{ - GTK_POLICY_ALWAYS, - GTK_POLICY_AUTOMATIC -} GtkPolicyType; - -/* Data update types (for ranges) */ -typedef enum -{ - GTK_UPDATE_CONTINUOUS, - GTK_UPDATE_DISCONTINUOUS, - GTK_UPDATE_DELAYED -} GtkUpdateType; - /* Attach options (for tables) */ typedef enum { @@ -102,34 +61,56 @@ typedef enum GTK_FILL = 1 << 2 } GtkAttachOptions; +/* button box styles */ typedef enum { - GTK_RUN_FIRST = 0x1, - GTK_RUN_LAST = 0x2, - GTK_RUN_BOTH = 0x3, - GTK_RUN_MASK = 0xF, - GTK_RUN_NO_RECURSE = 0x10 -} GtkSignalRunType; + GTK_BUTTONBOX_DEFAULT_STYLE, + GTK_BUTTONBOX_SPREAD, + GTK_BUTTONBOX_EDGE, + GTK_BUTTONBOX_START, + GTK_BUTTONBOX_END +} GtkButtonBoxStyle; +/* curve types */ typedef enum { - GTK_WIN_POS_NONE, - GTK_WIN_POS_CENTER, - GTK_WIN_POS_MOUSE -} GtkWindowPosition; + GTK_CURVE_TYPE_LINEAR, /* linear interpolation */ + GTK_CURVE_TYPE_SPLINE, /* spline interpolation */ + GTK_CURVE_TYPE_FREE /* free form curve */ +} GtkCurveType; +/* Focus movement types */ typedef enum { - GTK_DIRECTION_LEFT, - GTK_DIRECTION_RIGHT -} GtkSubmenuDirection; + GTK_DIR_TAB_FORWARD, + GTK_DIR_TAB_BACKWARD, + GTK_DIR_UP, + GTK_DIR_DOWN, + GTK_DIR_LEFT, + GTK_DIR_RIGHT +} GtkDirectionType; +/* justification for label and maybe other widgets (text?) */ typedef enum { - GTK_TOP_BOTTOM, - GTK_LEFT_RIGHT -} GtkSubmenuPlacement; + GTK_JUSTIFY_LEFT, + GTK_JUSTIFY_RIGHT, + GTK_JUSTIFY_CENTER, + GTK_JUSTIFY_FILL +} GtkJustification; + +/* GtkPatternSpec match types */ +typedef enum +{ + GTK_MATCH_ALL /* "*A?A*" */, + GTK_MATCH_ALL_TAIL /* "*A?AA" */, + GTK_MATCH_HEAD /* "AAAA*" */, + GTK_MATCH_TAIL /* "*AAAA" */, + GTK_MATCH_EXACT /* "AAAAA" */, + GTK_MATCH_LAST +} GtkMatchType; +/* menu factory types (outdated) */ typedef enum { GTK_MENU_FACTORY_MENU, @@ -137,6 +118,7 @@ typedef enum GTK_MENU_FACTORY_OPTION_MENU } GtkMenuFactoryType; +/* gtk metrics */ typedef enum { GTK_PIXELS, @@ -144,24 +126,47 @@ typedef enum GTK_CENTIMETERS } GtkMetricType; +/* Orientation for toolbars, etc. */ typedef enum { - GTK_SCROLL_NONE, - GTK_SCROLL_STEP_BACKWARD, - GTK_SCROLL_STEP_FORWARD, - GTK_SCROLL_PAGE_BACKWARD, - GTK_SCROLL_PAGE_FORWARD, - GTK_SCROLL_JUMP -} GtkScrollType; + GTK_ORIENTATION_HORIZONTAL, + GTK_ORIENTATION_VERTICAL +} GtkOrientation; +/* Packing types (for boxes) */ typedef enum { - GTK_TROUGH_NONE, - GTK_TROUGH_START, - GTK_TROUGH_END, - GTK_TROUGH_JUMP -} GtkTroughType; + GTK_PACK_START, + GTK_PACK_END +} GtkPackType; + +/* priorities for path lookups */ +typedef enum +{ + GTK_PATH_PRIO_LOWEST = 0, + GTK_PATH_PRIO_GTK = 4, + GTK_PATH_PRIO_APPLICATION = 8, + GTK_PATH_PRIO_RC = 12, + GTK_PATH_PRIO_HIGHEST = 15, + GTK_PATH_PRIO_MASK = 0x0f +} GtkPathPriorityType; + +/* widget path types */ +typedef enum +{ + GTK_PATH_WIDGET, + GTK_PATH_WIDGET_CLASS, + GTK_PATH_CLASS +} GtkPathType; + +/* Scrollbar policy types (for scrolled windows) */ +typedef enum +{ + GTK_POLICY_ALWAYS, + GTK_POLICY_AUTOMATIC +} GtkPolicyType; +/* gtk position */ typedef enum { GTK_POS_LEFT, @@ -170,20 +175,30 @@ typedef enum GTK_POS_BOTTOM } GtkPositionType; +/* GtkPreview types */ typedef enum { GTK_PREVIEW_COLOR, GTK_PREVIEW_GRAYSCALE } GtkPreviewType; -/* justification for label and maybe other widgets (text?) */ +/* Style for buttons */ typedef enum { - GTK_JUSTIFY_LEFT, - GTK_JUSTIFY_RIGHT, - GTK_JUSTIFY_CENTER, - GTK_JUSTIFY_FILL -} GtkJustification; + GTK_RELIEF_NORMAL, + GTK_RELIEF_NONE +} GtkReliefStyle; + +/* scrolling types */ +typedef enum +{ + GTK_SCROLL_NONE, + GTK_SCROLL_STEP_BACKWARD, + GTK_SCROLL_STEP_FORWARD, + GTK_SCROLL_PAGE_BACKWARD, + GTK_SCROLL_PAGE_FORWARD, + GTK_SCROLL_JUMP +} GtkScrollType; /* list selection modes */ typedef enum @@ -194,12 +209,49 @@ typedef enum GTK_SELECTION_EXTENDED } GtkSelectionMode; -/* Orientation for toolbars, etc. */ +/* Shadow types */ typedef enum { - GTK_ORIENTATION_HORIZONTAL, - GTK_ORIENTATION_VERTICAL -} GtkOrientation; + GTK_SHADOW_NONE, + GTK_SHADOW_IN, + GTK_SHADOW_OUT, + GTK_SHADOW_ETCHED_IN, + GTK_SHADOW_ETCHED_OUT +} GtkShadowType; + +/* signal run types */ +typedef enum +{ + GTK_RUN_FIRST = 0x1, + GTK_RUN_LAST = 0x2, + GTK_RUN_BOTH = 0x3, + GTK_RUN_MASK = 0xF, + GTK_RUN_NO_RECURSE = 0x10 +} GtkSignalRunType; + +/* Widget states */ +typedef enum +{ + GTK_STATE_NORMAL, + GTK_STATE_ACTIVE, + GTK_STATE_PRELIGHT, + GTK_STATE_SELECTED, + GTK_STATE_INSENSITIVE +} GtkStateType; + +/* directions for submenus */ +typedef enum +{ + GTK_DIRECTION_LEFT, + GTK_DIRECTION_RIGHT +} GtkSubmenuDirection; + +/* placement of submenus */ +typedef enum +{ + GTK_TOP_BOTTOM, + GTK_LEFT_RIGHT +} GtkSubmenuPlacement; /* Style for toolbars */ typedef enum @@ -209,12 +261,22 @@ typedef enum GTK_TOOLBAR_BOTH } GtkToolbarStyle; -/* Style for buttons */ +/* trough types for GtkRange */ typedef enum { - GTK_RELIEF_NORMAL, - GTK_RELIEF_NONE -} GtkReliefStyle; + GTK_TROUGH_NONE, + GTK_TROUGH_START, + GTK_TROUGH_END, + GTK_TROUGH_JUMP +} GtkTroughType; + +/* Data update types (for ranges) */ +typedef enum +{ + GTK_UPDATE_CONTINUOUS, + GTK_UPDATE_DISCONTINUOUS, + GTK_UPDATE_DELAYED +} GtkUpdateType; /* Generic visibility flags */ typedef enum @@ -224,6 +286,24 @@ typedef enum GTK_VISIBILITY_FULL } GtkVisibility; +/* window position types */ +typedef enum +{ + GTK_WIN_POS_NONE, + GTK_WIN_POS_CENTER, + GTK_WIN_POS_MOUSE +} GtkWindowPosition; + +/* Window types */ +typedef enum +{ + GTK_WINDOW_TOPLEVEL, + GTK_WINDOW_DIALOG, + GTK_WINDOW_POPUP +} GtkWindowType; + + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtkenumvalues.c b/gtk/gtkenumvalues.c new file mode 100644 index 0000000000..bfe015c2b3 --- /dev/null +++ b/gtk/gtkenumvalues.c @@ -0,0 +1,506 @@ +/* generated by makeenums.awk from "./gtk.defs" */ + +static GtkEnumValue enum_values_GtkAccelFlags[] = { + { GTK_ACCEL_VISIBLE, "GTK_ACCEL_VISIBLE", "visible" }, + { GTK_ACCEL_SIGNAL_VISIBLE, "GTK_ACCEL_SIGNAL_VISIBLE", "signal-visible" }, + { GTK_ACCEL_LOCKED, "GTK_ACCEL_LOCKED", "locked" }, + { GTK_ACCEL_MASK, "GTK_ACCEL_MASK", "mask" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkArrowType[] = { + { GTK_ARROW_UP, "GTK_ARROW_UP", "up" }, + { GTK_ARROW_DOWN, "GTK_ARROW_DOWN", "down" }, + { GTK_ARROW_LEFT, "GTK_ARROW_LEFT", "left" }, + { GTK_ARROW_RIGHT, "GTK_ARROW_RIGHT", "right" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkAttachOptions[] = { + { GTK_EXPAND, "GTK_EXPAND", "expand" }, + { GTK_SHRINK, "GTK_SHRINK", "shrink" }, + { GTK_FILL, "GTK_FILL", "fill" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkButtonBoxStyle[] = { + { GTK_BUTTONBOX_DEFAULT_STYLE, "GTK_BUTTONBOX_DEFAULT_STYLE", "default" }, + { GTK_BUTTONBOX_SPREAD, "GTK_BUTTONBOX_SPREAD", "spread" }, + { GTK_BUTTONBOX_EDGE, "GTK_BUTTONBOX_EDGE", "edge" }, + { GTK_BUTTONBOX_START, "GTK_BUTTONBOX_START", "start" }, + { GTK_BUTTONBOX_END, "GTK_BUTTONBOX_END", "end" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkDirectionType[] = { + { GTK_DIR_TAB_FORWARD, "GTK_DIR_TAB_FORWARD", "tab-forward" }, + { GTK_DIR_TAB_BACKWARD, "GTK_DIR_TAB_BACKWARD", "tab-backward" }, + { GTK_DIR_UP, "GTK_DIR_UP", "up" }, + { GTK_DIR_DOWN, "GTK_DIR_DOWN", "down" }, + { GTK_DIR_LEFT, "GTK_DIR_LEFT", "left" }, + { GTK_DIR_RIGHT, "GTK_DIR_RIGHT", "right" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkJustification[] = { + { GTK_JUSTIFY_LEFT, "GTK_JUSTIFY_LEFT", "left" }, + { GTK_JUSTIFY_RIGHT, "GTK_JUSTIFY_RIGHT", "right" }, + { GTK_JUSTIFY_CENTER, "GTK_JUSTIFY_CENTER", "center" }, + { GTK_JUSTIFY_FILL, "GTK_JUSTIFY_FILL", "fill" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkMatchType[] = { + { GTK_MATCH_ALL, "GTK_MATCH_ALL", "all" }, + { GTK_MATCH_ALL_TAIL, "GTK_MATCH_ALL_TAIL", "all-tail" }, + { GTK_MATCH_HEAD, "GTK_MATCH_HEAD", "head" }, + { GTK_MATCH_TAIL, "GTK_MATCH_TAIL", "tail" }, + { GTK_MATCH_EXACT, "GTK_MATCH_EXACT", "exact" }, + { GTK_MATCH_LAST, "GTK_MATCH_LAST", "last" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkMenuFactoryType[] = { + { GTK_MENU_FACTORY_MENU, "GTK_MENU_FACTORY_MENU", "menu" }, + { GTK_MENU_FACTORY_MENU_BAR, "GTK_MENU_FACTORY_MENU_BAR", "menu-bar" }, + { GTK_MENU_FACTORY_OPTION_MENU, "GTK_MENU_FACTORY_OPTION_MENU", "option-menu" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkMetricType[] = { + { GTK_PIXELS, "GTK_PIXELS", "pixels" }, + { GTK_INCHES, "GTK_INCHES", "inches" }, + { GTK_CENTIMETERS, "GTK_CENTIMETERS", "centimeters" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkOrientation[] = { + { GTK_ORIENTATION_HORIZONTAL, "GTK_ORIENTATION_HORIZONTAL", "horizontal" }, + { GTK_ORIENTATION_VERTICAL, "GTK_ORIENTATION_VERTICAL", "vertical" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPackType[] = { + { GTK_PACK_START, "GTK_PACK_START", "start" }, + { GTK_PACK_END, "GTK_PACK_END", "end" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPathPriorityType[] = { + { GTK_PATH_PRIO_LOWEST, "GTK_PATH_PRIO_LOWEST", "lowest" }, + { GTK_PATH_PRIO_GTK, "GTK_PATH_PRIO_GTK", "gtk" }, + { GTK_PATH_PRIO_APPLICATION, "GTK_PATH_PRIO_APPLICATION", "application" }, + { GTK_PATH_PRIO_RC, "GTK_PATH_PRIO_RC", "rc" }, + { GTK_PATH_PRIO_HIGHEST, "GTK_PATH_PRIO_HIGHEST", "highest" }, + { GTK_PATH_PRIO_MASK, "GTK_PATH_PRIO_MASK", "mask" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPathType[] = { + { GTK_PATH_WIDGET, "GTK_PATH_WIDGET", "widget" }, + { GTK_PATH_WIDGET_CLASS, "GTK_PATH_WIDGET_CLASS", "widget-class" }, + { GTK_PATH_CLASS, "GTK_PATH_CLASS", "class" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPolicyType[] = { + { GTK_POLICY_ALWAYS, "GTK_POLICY_ALWAYS", "always" }, + { GTK_POLICY_AUTOMATIC, "GTK_POLICY_AUTOMATIC", "automatic" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPositionType[] = { + { GTK_POS_LEFT, "GTK_POS_LEFT", "left" }, + { GTK_POS_RIGHT, "GTK_POS_RIGHT", "right" }, + { GTK_POS_TOP, "GTK_POS_TOP", "top" }, + { GTK_POS_BOTTOM, "GTK_POS_BOTTOM", "bottom" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPreviewType[] = { + { GTK_PREVIEW_COLOR, "GTK_PREVIEW_COLOR", "color" }, + { GTK_PREVIEW_GRAYSCALE, "GTK_PREVIEW_GRAYSCALE", "grayscale" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkReliefStyle[] = { + { GTK_RELIEF_NORMAL, "GTK_RELIEF_NORMAL", "normal" }, + { GTK_RELIEF_NONE, "GTK_RELIEF_NONE", "none" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkScrollType[] = { + { GTK_SCROLL_NONE, "GTK_SCROLL_NONE", "none" }, + { GTK_SCROLL_STEP_BACKWARD, "GTK_SCROLL_STEP_BACKWARD", "step-backward" }, + { GTK_SCROLL_STEP_FORWARD, "GTK_SCROLL_STEP_FORWARD", "step-forward" }, + { GTK_SCROLL_PAGE_BACKWARD, "GTK_SCROLL_PAGE_BACKWARD", "page-backward" }, + { GTK_SCROLL_PAGE_FORWARD, "GTK_SCROLL_PAGE_FORWARD", "page-forward" }, + { GTK_SCROLL_JUMP, "GTK_SCROLL_JUMP", "jump" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkSelectionMode[] = { + { GTK_SELECTION_SINGLE, "GTK_SELECTION_SINGLE", "single" }, + { GTK_SELECTION_BROWSE, "GTK_SELECTION_BROWSE", "browse" }, + { GTK_SELECTION_MULTIPLE, "GTK_SELECTION_MULTIPLE", "multiple" }, + { GTK_SELECTION_EXTENDED, "GTK_SELECTION_EXTENDED", "extended" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkShadowType[] = { + { GTK_SHADOW_NONE, "GTK_SHADOW_NONE", "none" }, + { GTK_SHADOW_IN, "GTK_SHADOW_IN", "in" }, + { GTK_SHADOW_OUT, "GTK_SHADOW_OUT", "out" }, + { GTK_SHADOW_ETCHED_IN, "GTK_SHADOW_ETCHED_IN", "etched-in" }, + { GTK_SHADOW_ETCHED_OUT, "GTK_SHADOW_ETCHED_OUT", "etched-out" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkSignalRunType[] = { + { GTK_RUN_FIRST, "GTK_RUN_FIRST", "first" }, + { GTK_RUN_LAST, "GTK_RUN_LAST", "last" }, + { GTK_RUN_BOTH, "GTK_RUN_BOTH", "both" }, + { GTK_RUN_MASK, "GTK_RUN_MASK", "mask" }, + { GTK_RUN_NO_RECURSE, "GTK_RUN_NO_RECURSE", "no-recurse" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkStateType[] = { + { GTK_STATE_NORMAL, "GTK_STATE_NORMAL", "normal" }, + { GTK_STATE_ACTIVE, "GTK_STATE_ACTIVE", "active" }, + { GTK_STATE_PRELIGHT, "GTK_STATE_PRELIGHT", "prelight" }, + { GTK_STATE_SELECTED, "GTK_STATE_SELECTED", "selected" }, + { GTK_STATE_INSENSITIVE, "GTK_STATE_INSENSITIVE", "insensitive" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkSubmenuDirection[] = { + { GTK_DIRECTION_LEFT, "GTK_DIRECTION_LEFT", "left" }, + { GTK_DIRECTION_RIGHT, "GTK_DIRECTION_RIGHT", "right" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkSubmenuPlacement[] = { + { GTK_TOP_BOTTOM, "GTK_TOP_BOTTOM", "top-bottom" }, + { GTK_LEFT_RIGHT, "GTK_LEFT_RIGHT", "left-right" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkToolbarStyle[] = { + { GTK_TOOLBAR_ICONS, "GTK_TOOLBAR_ICONS", "icons" }, + { GTK_TOOLBAR_TEXT, "GTK_TOOLBAR_TEXT", "text" }, + { GTK_TOOLBAR_BOTH, "GTK_TOOLBAR_BOTH", "both" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkTroughType[] = { + { GTK_TROUGH_NONE, "GTK_TROUGH_NONE", "none" }, + { GTK_TROUGH_START, "GTK_TROUGH_START", "start" }, + { GTK_TROUGH_END, "GTK_TROUGH_END", "end" }, + { GTK_TROUGH_JUMP, "GTK_TROUGH_JUMP", "jump" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkUpdateType[] = { + { GTK_UPDATE_CONTINUOUS, "GTK_UPDATE_CONTINUOUS", "continuous" }, + { GTK_UPDATE_DISCONTINUOUS, "GTK_UPDATE_DISCONTINUOUS", "discontinuous" }, + { GTK_UPDATE_DELAYED, "GTK_UPDATE_DELAYED", "delayed" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkVisibility[] = { + { GTK_VISIBILITY_NONE, "GTK_VISIBILITY_NONE", "none" }, + { GTK_UPDATE_DISCONTINUOUS, "GTK_UPDATE_DISCONTINUOUS", "discontinuous" }, + { GTK_UPDATE_DELAYED, "GTK_UPDATE_DELAYED", "delayed" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkWindowPosition[] = { + { GTK_WIN_POS_NONE, "GTK_WIN_POS_NONE", "none" }, + { GTK_WIN_POS_CENTER, "GTK_WIN_POS_CENTER", "center" }, + { GTK_WIN_POS_MOUSE, "GTK_WIN_POS_MOUSE", "mouse" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkWindowType[] = { + { GTK_WINDOW_TOPLEVEL, "GTK_WINDOW_TOPLEVEL", "toplevel" }, + { GTK_WINDOW_DIALOG, "GTK_WINDOW_DIALOG", "dialog" }, + { GTK_WINDOW_POPUP, "GTK_WINDOW_POPUP", "popup" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkObjectFlags[] = { + { GTK_DESTROYED, "GTK_DESTROYED", "destroyed" }, + { GTK_FLOATING, "GTK_FLOATING", "floating" }, + { GTK_CONNECTED, "GTK_CONNECTED", "connected" }, + { GTK_OBJECT_FLAG_LAST, "GTK_OBJECT_FLAG_LAST", "object-flag-last" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkArgFlags[] = { + { GTK_ARG_READABLE, "GTK_ARG_READABLE", "readable" }, + { GTK_ARG_WRITABLE, "GTK_ARG_WRITABLE", "writable" }, + { GTK_ARG_CONSTRUCT, "GTK_ARG_CONSTRUCT", "construct" }, + { GTK_ARG_MASK, "GTK_ARG_MASK", "mask" }, + { GTK_ARG_READWRITE, "GTK_ARG_READWRITE", "readwrite" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkWidgetFlags[] = { + { GTK_TOPLEVEL, "GTK_TOPLEVEL", "toplevel" }, + { GTK_NO_WINDOW, "GTK_NO_WINDOW", "no-window" }, + { GTK_REALIZED, "GTK_REALIZED", "realized" }, + { GTK_MAPPED, "GTK_MAPPED", "mapped" }, + { GTK_VISIBLE, "GTK_VISIBLE", "visible" }, + { GTK_SENSITIVE, "GTK_SENSITIVE", "sensitive" }, + { GTK_PARENT_SENSITIVE, "GTK_PARENT_SENSITIVE", "parent-sensitive" }, + { GTK_CAN_FOCUS, "GTK_CAN_FOCUS", "can-focus" }, + { GTK_HAS_FOCUS, "GTK_HAS_FOCUS", "has-focus" }, + { GTK_CAN_DEFAULT, "GTK_CAN_DEFAULT", "can-default" }, + { GTK_HAS_DEFAULT, "GTK_HAS_DEFAULT", "has-default" }, + { GTK_HAS_GRAB, "GTK_HAS_GRAB", "has-grab" }, + { GTK_RC_STYLE, "GTK_RC_STYLE", "rc-style" }, + { GTK_BASIC, "GTK_BASIC", "basic" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkPrivateFlags[] = { + { PRIVATE_GTK_USER_STYLE, "PRIVATE_GTK_USER_STYLE", "user-style" }, + { PRIVATE_GTK_REDRAW_PENDING, "PRIVATE_GTK_REDRAW_PENDING", "redraw-pending" }, + { PRIVATE_GTK_RESIZE_PENDING, "PRIVATE_GTK_RESIZE_PENDING", "resize-pending" }, + { PRIVATE_GTK_RESIZE_NEEDED, "PRIVATE_GTK_RESIZE_NEEDED", "resize-needed" }, + { PRIVATE_GTK_LEAVE_PENDING, "PRIVATE_GTK_LEAVE_PENDING", "leave-pending" }, + { PRIVATE_GTK_HAS_SHAPE_MASK, "PRIVATE_GTK_HAS_SHAPE_MASK", "has-shape-mask" }, + { PRIVATE_GTK_IN_REPARENT, "PRIVATE_GTK_IN_REPARENT", "in-reparent" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkCurveType[] = { + { GTK_CURVE_TYPE_LINEAR, "GTK_CURVE_TYPE_LINEAR", "linear" }, + { GTK_CURVE_TYPE_SPLINE, "GTK_CURVE_TYPE_SPLINE", "spline" }, + { GTK_CURVE_TYPE_FREE, "GTK_CURVE_TYPE_FREE", "free" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GtkFundamentalType[] = { + { GTK_TYPE_INVALID, "GTK_TYPE_INVALID", "invalid" }, + { GTK_TYPE_NONE, "GTK_TYPE_NONE", "none" }, + { GTK_TYPE_CHAR, "GTK_TYPE_CHAR", "char" }, + { GTK_TYPE_BOOL, "GTK_TYPE_BOOL", "bool" }, + { GTK_TYPE_INT, "GTK_TYPE_INT", "int" }, + { GTK_TYPE_UINT, "GTK_TYPE_UINT", "uint" }, + { GTK_TYPE_LONG, "GTK_TYPE_LONG", "long" }, + { GTK_TYPE_ULONG, "GTK_TYPE_ULONG", "ulong" }, + { GTK_TYPE_FLOAT, "GTK_TYPE_FLOAT", "float" }, + { GTK_TYPE_DOUBLE, "GTK_TYPE_DOUBLE", "double" }, + { GTK_TYPE_STRING, "GTK_TYPE_STRING", "string" }, + { GTK_TYPE_ENUM, "GTK_TYPE_ENUM", "enum" }, + { GTK_TYPE_FLAGS, "GTK_TYPE_FLAGS", "flags" }, + { GTK_TYPE_BOXED, "GTK_TYPE_BOXED", "boxed" }, + { GTK_TYPE_FOREIGN, "GTK_TYPE_FOREIGN", "foreign" }, + { GTK_TYPE_CALLBACK, "GTK_TYPE_CALLBACK", "callback" }, + { GTK_TYPE_ARGS, "GTK_TYPE_ARGS", "args" }, + { GTK_TYPE_POINTER, "GTK_TYPE_POINTER", "pointer" }, + { GTK_TYPE_SIGNAL, "GTK_TYPE_SIGNAL", "signal" }, + { GTK_TYPE_C_CALLBACK, "GTK_TYPE_C_CALLBACK", "c-callback" }, + { GTK_TYPE_OBJECT, "GTK_TYPE_OBJECT", "object" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkWindowType[] = { + { GDK_WINDOW_ROOT, "GDK_WINDOW_ROOT", "root" }, + { GDK_WINDOW_TOPLEVEL, "GDK_WINDOW_TOPLEVEL", "toplevel" }, + { GDK_WINDOW_CHILD, "GDK_WINDOW_CHILD", "child" }, + { GDK_WINDOW_DIALOG, "GDK_WINDOW_DIALOG", "dialog" }, + { GDK_WINDOW_TEMP, "GDK_WINDOW_TEMP", "temp" }, + { GDK_WINDOW_PIXMAP, "GDK_WINDOW_PIXMAP", "pixmap" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkWindowClass[] = { + { GDK_INPUT_OUTPUT, "GDK_INPUT_OUTPUT", "input-output" }, + { GDK_INPUT_ONLY, "GDK_INPUT_ONLY", "input-only" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkImageType[] = { + { GDK_IMAGE_NORMAL, "GDK_IMAGE_NORMAL", "normal" }, + { GDK_IMAGE_SHARED, "GDK_IMAGE_SHARED", "shared" }, + { GDK_IMAGE_FASTEST, "GDK_IMAGE_FASTEST", "fastest" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkVisualType[] = { + { GDK_VISUAL_STATIC_GRAY, "GDK_VISUAL_STATIC_GRAY", "static-gray" }, + { GDK_VISUAL_GRAYSCALE, "GDK_VISUAL_GRAYSCALE", "grayscale" }, + { GDK_VISUAL_STATIC_COLOR, "GDK_VISUAL_STATIC_COLOR", "static-color" }, + { GDK_VISUAL_PSEUDO_COLOR, "GDK_VISUAL_PSEUDO_COLOR", "pseudo-color" }, + { GDK_VISUAL_TRUE_COLOR, "GDK_VISUAL_TRUE_COLOR", "true-color" }, + { GDK_VISUAL_DIRECT_COLOR, "GDK_VISUAL_DIRECT_COLOR", "direct-color" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkWindowAttributesType[] = { + { GDK_WA_TITLE, "GDK_WA_TITLE", "title" }, + { GDK_WA_X, "GDK_WA_X", "x" }, + { GDK_WA_Y, "GDK_WA_Y", "y" }, + { GDK_WA_CURSOR, "GDK_WA_CURSOR", "cursor" }, + { GDK_WA_COLORMAP, "GDK_WA_COLORMAP", "colormap" }, + { GDK_WA_VISUAL, "GDK_WA_VISUAL", "visual" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkWindowHints[] = { + { GDK_HINT_POS, "GDK_HINT_POS", "pos" }, + { GDK_HINT_MIN_SIZE, "GDK_HINT_MIN_SIZE", "min-size" }, + { GDK_HINT_MAX_SIZE, "GDK_HINT_MAX_SIZE", "max-size" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkFunction[] = { + { GDK_COPY, "GDK_COPY", "copy" }, + { GDK_INVERT, "GDK_INVERT", "invert" }, + { GDK_XOR, "GDK_XOR", "xor" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkFill[] = { + { GDK_SOLID, "GDK_SOLID", "solid" }, + { GDK_TILED, "GDK_TILED", "tiled" }, + { GDK_STIPPLED, "GDK_STIPPLED", "stippled" }, + { GDK_OPAQUE_STIPPLED, "GDK_OPAQUE_STIPPLED", "opaque-stippled" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkLineStyle[] = { + { GDK_LINE_SOLID, "GDK_LINE_SOLID", "solid" }, + { GDK_LINE_ON_OFF_DASH, "GDK_LINE_ON_OFF_DASH", "on-off-dash" }, + { GDK_LINE_DOUBLE_DASH, "GDK_LINE_DOUBLE_DASH", "double-dash" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkCapStyle[] = { + { GDK_CAP_NOT_LAST, "GDK_CAP_NOT_LAST", "not-last" }, + { GDK_CAP_BUTT, "GDK_CAP_BUTT", "butt" }, + { GDK_CAP_ROUND, "GDK_CAP_ROUND", "round" }, + { GDK_CAP_PROJECTING, "GDK_CAP_PROJECTING", "projecting" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkJoinStyle[] = { + { GDK_JOIN_MITER, "GDK_JOIN_MITER", "miter" }, + { GDK_JOIN_ROUND, "GDK_JOIN_ROUND", "round" }, + { GDK_JOIN_BEVEL, "GDK_JOIN_BEVEL", "bevel" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkCursorType[] = { + { GDK_LAST_CURSOR, "GDK_LAST_CURSOR", "cursor" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkEventType[] = { + { GDK_NOTHING, "GDK_NOTHING", "nothing" }, + { GDK_DELETE, "GDK_DELETE", "delete" }, + { GDK_DESTROY, "GDK_DESTROY", "destroy" }, + { GDK_EXPOSE, "GDK_EXPOSE", "expose" }, + { GDK_MOTION_NOTIFY, "GDK_MOTION_NOTIFY", "motion-notify" }, + { GDK_BUTTON_PRESS, "GDK_BUTTON_PRESS", "button-press" }, + { GDK_2BUTTON_PRESS, "GDK_2BUTTON_PRESS", "2button-press" }, + { GDK_3BUTTON_PRESS, "GDK_3BUTTON_PRESS", "3button-press" }, + { GDK_BUTTON_RELEASE, "GDK_BUTTON_RELEASE", "button-release" }, + { GDK_KEY_PRESS, "GDK_KEY_PRESS", "key-press" }, + { GDK_KEY_RELEASE, "GDK_KEY_RELEASE", "key-release" }, + { GDK_ENTER_NOTIFY, "GDK_ENTER_NOTIFY", "enter-notify" }, + { GDK_LEAVE_NOTIFY, "GDK_LEAVE_NOTIFY", "leave-notify" }, + { GDK_FOCUS_CHANGE, "GDK_FOCUS_CHANGE", "focus-change" }, + { GDK_CONFIGURE, "GDK_CONFIGURE", "configure" }, + { GDK_MAP, "GDK_MAP", "map" }, + { GDK_UNMAP, "GDK_UNMAP", "unmap" }, + { GDK_PROPERTY_NOTIFY, "GDK_PROPERTY_NOTIFY", "property-notify" }, + { GDK_SELECTION_CLEAR, "GDK_SELECTION_CLEAR", "selection-clear" }, + { GDK_SELECTION_REQUEST, "GDK_SELECTION_REQUEST", "selection-request" }, + { GDK_SELECTION_NOTIFY, "GDK_SELECTION_NOTIFY", "selection-notify" }, + { GDK_PROXIMITY_IN, "GDK_PROXIMITY_IN", "proximity-in" }, + { GDK_PROXIMITY_OUT, "GDK_PROXIMITY_OUT", "proximity-out" }, + { GDK_DRAG_BEGIN, "GDK_DRAG_BEGIN", "drag-begin" }, + { GDK_DRAG_REQUEST, "GDK_DRAG_REQUEST", "drag-request" }, + { GDK_DROP_ENTER, "GDK_DROP_ENTER", "drop-enter" }, + { GDK_DROP_LEAVE, "GDK_DROP_LEAVE", "drop-leave" }, + { GDK_DROP_DATA_AVAIL, "GDK_DROP_DATA_AVAIL", "drop-data-avail" }, + { GDK_CLIENT_EVENT, "GDK_CLIENT_EVENT", "client-event" }, + { GDK_VISIBILITY_NOTIFY, "GDK_VISIBILITY_NOTIFY", "visibility-notify" }, + { GDK_NO_EXPOSE, "GDK_NO_EXPOSE", "no-expose" }, + { GDK_OTHER_EVENT, "GDK_OTHER_EVENT", "other-event" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkEventMask[] = { + { GDK_EXPOSURE_MASK, "GDK_EXPOSURE_MASK", "exposure-mask" }, + { GDK_POINTER_MOTION_MASK, "GDK_POINTER_MOTION_MASK", "pointer-motion-mask" }, + { GDK_POINTER_MOTION_HINT_MASK, "GDK_POINTER_MOTION_HINT_MASK", "pointer-motion-hint-mask" }, + { GDK_BUTTON_MOTION_MASK, "GDK_BUTTON_MOTION_MASK", "button-motion-mask" }, + { GDK_BUTTON1_MOTION_MASK, "GDK_BUTTON1_MOTION_MASK", "button1-motion-mask" }, + { GDK_BUTTON2_MOTION_MASK, "GDK_BUTTON2_MOTION_MASK", "button2-motion-mask" }, + { GDK_BUTTON3_MOTION_MASK, "GDK_BUTTON3_MOTION_MASK", "button3-motion-mask" }, + { GDK_BUTTON_PRESS_MASK, "GDK_BUTTON_PRESS_MASK", "button-press-mask" }, + { GDK_BUTTON_RELEASE_MASK, "GDK_BUTTON_RELEASE_MASK", "button-release-mask" }, + { GDK_KEY_PRESS_MASK, "GDK_KEY_PRESS_MASK", "key-press-mask" }, + { GDK_KEY_RELEASE_MASK, "GDK_KEY_RELEASE_MASK", "key-release-mask" }, + { GDK_ENTER_NOTIFY_MASK, "GDK_ENTER_NOTIFY_MASK", "enter-notify-mask" }, + { GDK_LEAVE_NOTIFY_MASK, "GDK_LEAVE_NOTIFY_MASK", "leave-notify-mask" }, + { GDK_FOCUS_CHANGE_MASK, "GDK_FOCUS_CHANGE_MASK", "focus-change-mask" }, + { GDK_STRUCTURE_MASK, "GDK_STRUCTURE_MASK", "structure-mask" }, + { GDK_PROPERTY_CHANGE_MASK, "GDK_PROPERTY_CHANGE_MASK", "property-change-mask" }, + { GDK_VISIBILITY_NOTIFY_MASK, "GDK_VISIBILITY_NOTIFY_MASK", "visibility-notify-mask" }, + { GDK_PROXIMITY_IN_MASK, "GDK_PROXIMITY_IN_MASK", "proximity-in-mask" }, + { GDK_PROXIMITY_OUT_MASK, "GDK_PROXIMITY_OUT_MASK", "proximity-out-mask" }, + { GDK_SUBSTRUCTURE_MASK, "GDK_SUBSTRUCTURE_MASK", "substructure-mask" }, + { GDK_ALL_EVENTS_MASK, "GDK_ALL_EVENTS_MASK", "all-events-mask" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkNotifyType[] = { + { GDK_NOTIFY_ANCESTOR, "GDK_NOTIFY_ANCESTOR", "ancestor" }, + { GDK_NOTIFY_VIRTUAL, "GDK_NOTIFY_VIRTUAL", "virtual" }, + { GDK_NOTIFY_INFERIOR, "GDK_NOTIFY_INFERIOR", "inferior" }, + { GDK_NOTIFY_NONLINEAR, "GDK_NOTIFY_NONLINEAR", "nonlinear" }, + { GDK_NOTIFY_NONLINEAR_VIRTUAL, "GDK_NOTIFY_NONLINEAR_VIRTUAL", "nonlinear-virtual" }, + { GDK_NOTIFY_UNKNOWN, "GDK_NOTIFY_UNKNOWN", "unknown" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkCrossingMode[] = { + { GDK_CROSSING_NORMAL, "GDK_CROSSING_NORMAL", "crossing-normal" }, + { GDK_CROSSING_GRAB, "GDK_CROSSING_GRAB", "crossing-grab" }, + { GDK_CROSSING_UNGRAB, "GDK_CROSSING_UNGRAB", "crossing-ungrab" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkModifierType[] = { + { GDK_SHIFT_MASK, "GDK_SHIFT_MASK", "shift-mask" }, + { GDK_LOCK_MASK, "GDK_LOCK_MASK", "lock-mask" }, + { GDK_CONTROL_MASK, "GDK_CONTROL_MASK", "control-mask" }, + { GDK_MOD1_MASK, "GDK_MOD1_MASK", "mod1-mask" }, + { GDK_MOD2_MASK, "GDK_MOD2_MASK", "mod2-mask" }, + { GDK_MOD3_MASK, "GDK_MOD3_MASK", "mod3-mask" }, + { GDK_MOD4_MASK, "GDK_MOD4_MASK", "mod4-mask" }, + { GDK_MOD5_MASK, "GDK_MOD5_MASK", "mod5-mask" }, + { GDK_BUTTON1_MASK, "GDK_BUTTON1_MASK", "button1-mask" }, + { GDK_BUTTON2_MASK, "GDK_BUTTON2_MASK", "button2-mask" }, + { GDK_BUTTON3_MASK, "GDK_BUTTON3_MASK", "button3-mask" }, + { GDK_BUTTON4_MASK, "GDK_BUTTON4_MASK", "button4-mask" }, + { GDK_BUTTON5_MASK, "GDK_BUTTON5_MASK", "button5-mask" }, + { GDK_AFTER_MASK, "GDK_AFTER_MASK", "after-mask" }, + { GDK_MODIFIER_MASK, "GDK_MODIFIER_MASK", "modifier-mask" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkSubwindowMode[] = { + { GDK_CLIP_BY_CHILDREN, "GDK_CLIP_BY_CHILDREN", "clip-by-children" }, + { GDK_INCLUDE_INFERIORS, "GDK_INCLUDE_INFERIORS", "include-inferiors" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkInputCondition[] = { + { GDK_INPUT_READ, "GDK_INPUT_READ", "read" }, + { GDK_INPUT_WRITE, "GDK_INPUT_WRITE", "write" }, + { GDK_INPUT_EXCEPTION, "GDK_INPUT_EXCEPTION", "exception" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkStatus[] = { + { GDK_OK, "GDK_OK", "ok" }, + { GDK_ERROR, "GDK_ERROR", "error" }, + { GDK_ERROR_PARAM, "GDK_ERROR_PARAM", "error-param" }, + { GDK_ERROR_FILE, "GDK_ERROR_FILE", "error-file" }, + { GDK_ERROR_MEM, "GDK_ERROR_MEM", "error-mem" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkByteOrder[] = { + { GDK_LSB_FIRST, "GDK_LSB_FIRST", "lsb-first" }, + { GDK_MSB_FIRST, "GDK_MSB_FIRST", "msb-first" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkGCValuesMask[] = { + { GDK_GC_FOREGROUND, "GDK_GC_FOREGROUND", "foreground" }, + { GDK_GC_BACKGROUND, "GDK_GC_BACKGROUND", "background" }, + { GDK_GC_FONT, "GDK_GC_FONT", "font" }, + { GDK_GC_FUNCTION, "GDK_GC_FUNCTION", "function" }, + { GDK_GC_FILL, "GDK_GC_FILL", "fill" }, + { GDK_GC_TILE, "GDK_GC_TILE", "tile" }, + { GDK_GC_STIPPLE, "GDK_GC_STIPPLE", "stipple" }, + { GDK_GC_CLIP_MASK, "GDK_GC_CLIP_MASK", "clip-mask" }, + { GDK_GC_SUBWINDOW, "GDK_GC_SUBWINDOW", "subwindow" }, + { GDK_GC_TS_X_ORIGIN, "GDK_GC_TS_X_ORIGIN", "ts-x-origin" }, + { GDK_GC_TS_Y_ORIGIN, "GDK_GC_TS_Y_ORIGIN", "ts-y-origin" }, + { GDK_GC_CLIP_X_ORIGIN, "GDK_GC_CLIP_X_ORIGIN", "clip-x-origin" }, + { GDK_GC_CLIP_Y_ORIGIN, "GDK_GC_CLIP_Y_ORIGIN", "clip-y-origin" }, + { GDK_GC_EXPOSURES, "GDK_GC_EXPOSURES", "exposures" }, + { GDK_GC_LINE_WIDTH, "GDK_GC_LINE_WIDTH", "line-width" }, + { GDK_GC_LINE_STYLE, "GDK_GC_LINE_STYLE", "line-style" }, + { GDK_GC_CAP_STYLE, "GDK_GC_CAP_STYLE", "cap-style" }, + { GDK_GC_JOIN_STYLE, "GDK_GC_JOIN_STYLE", "join-style" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkSelection[] = { + { GDK_SELECTION_PRIMARY, "GDK_SELECTION_PRIMARY", "primary" }, + { GDK_SELECTION_SECONDARY, "GDK_SELECTION_SECONDARY", "secondary" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkPropertyState[] = { + { GDK_PROPERTY_NEW_VALUE, "GDK_PROPERTY_NEW_VALUE", "new-value" }, + { GDK_PROPERTY_DELETE, "GDK_PROPERTY_DELETE", "delete" }, + { 0, NULL, NULL }, +}; +static GtkEnumValue enum_values_GdkPropMode[] = { + { GDK_PROP_MODE_REPLACE, "GDK_PROP_MODE_REPLACE", "replace" }, + { GDK_PROP_MODE_PREPEND, "GDK_PROP_MODE_PREPEND", "prepend" }, + { GDK_PROP_MODE_APPEND, "GDK_PROP_MODE_APPEND", "append" }, + { 0, NULL, NULL }, +}; diff --git a/gtk/gtkitemfactory.c b/gtk/gtkitemfactory.c new file mode 100644 index 0000000000..6910703a97 --- /dev/null +++ b/gtk/gtkitemfactory.c @@ -0,0 +1,1313 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkItemFactory: Flexible item factory with automatic rc handling + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include "gtkitemfactory.h" +#include "gtk/gtksignal.h" +#include "gtk/gtkoptionmenu.h" +#include "gtk/gtkmenubar.h" +#include "gtk/gtkmenu.h" +#include "gtk/gtkmenuitem.h" +#include "gtk/gtkradiomenuitem.h" +#include "gtk/gtkcheckmenuitem.h" +#include "gtk/gtkaccellabel.h" +#include <string.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + + + +/* --- defines --- */ +#define PARENT_DELIMITER ('/') +#define ITEM_FACTORY_STRING ((gchar*) item_factory_string) +#define ITEM_BLOCK_SIZE (128) + + +/* --- structures --- */ +typedef struct _GtkIFCBData GtkIFCBData; +typedef struct _GtkIFActionLink GtkIFActionLink; +struct _GtkIFCBData +{ + GtkItemFactoryCallback func; + gpointer func_data; + guint callback_action; +}; +struct _GtkIFActionLink +{ + GtkWidget *widget; + guint callback_action; +}; + + +/* --- prototypes --- */ +static void gtk_item_factory_class_init (GtkItemFactoryClass *klass); +static void gtk_item_factory_init (GtkItemFactory *ifactory); +static void gtk_item_factory_destroy (GtkObject *object); +static void gtk_item_factory_finalize (GtkObject *object); + + +/* --- static variables --- */ +static GtkItemFactoryClass *gtk_item_factory_class = NULL; +static GtkObjectClass *parent_class = NULL; +static const gchar *item_factory_string = "Gtk-<ItemFactory>"; +static GMemChunk *ifactory_item_chunks = NULL; +static GMemChunk *ifactory_cb_data_chunks = NULL; +static const gchar *key_popup_data = "GtkItemFactory-popup-data"; +static guint key_id_popup_data = 0; +static const gchar *key_if_menu_pos = "GtkItemFactory-menu-position"; +static guint key_id_if_menu_pos = 0; +static const gchar *key_item_factory = "GtkItemFactory"; +static guint key_id_item_factory = 0; +static const gchar *key_item_factory_path = "GtkItemFactory-path"; +static guint key_id_item_factory_path = 0; +static const gchar *key_type_item = "<Item>"; +static guint key_id_type_item = 0; +static const gchar *key_type_title = "<Title>"; +static guint key_id_type_title = 0; +static const gchar *key_type_radio_item = "<RadioItem>"; +static guint key_id_type_radio_item = 0; +static const gchar *key_type_check_item = "<CheckItem>"; +static guint key_id_type_check_item = 0; +static const gchar *key_type_toggle_item = "<ToggleItem>"; +static guint key_id_type_toggle_item = 0; +static const gchar *key_type_separator_item = "<Separator>"; +static guint key_id_type_separator_item = 0; +static const gchar *key_type_branch = "<Branch>"; +static guint key_id_type_branch = 0; +static const gchar *key_type_last_branch = "<LastBranch>"; +static guint key_id_type_last_branch = 0; +static GScannerConfig ifactory_scanner_config = +{ + ( + " \t\n" + ) /* cset_skip_characters */, + ( + G_CSET_a_2_z + "_" + G_CSET_A_2_Z + ) /* cset_identifier_first */, + ( + G_CSET_a_2_z + "-+_0123456789" + G_CSET_A_2_Z + G_CSET_LATINS + G_CSET_LATINC + ) /* cset_identifier_nth */, + ( ";\n" ) /* cpair_comment_single */, + + FALSE /* case_sensitive */, + + TRUE /* skip_comment_multi */, + TRUE /* skip_comment_single */, + FALSE /* scan_comment_multi */, + TRUE /* scan_identifier */, + FALSE /* scan_identifier_1char */, + FALSE /* scan_identifier_NULL */, + TRUE /* scan_symbols */, + TRUE /* scan_binary */, + TRUE /* scan_octal */, + TRUE /* scan_float */, + TRUE /* scan_hex */, + FALSE /* scan_hex_dollar */, + TRUE /* scan_string_sq */, + TRUE /* scan_string_dq */, + TRUE /* numbers_2_int */, + FALSE /* int_2_float */, + FALSE /* identifier_2_string */, + TRUE /* char_2_token */, + FALSE /* symbol_2_token */, +}; + + +/* --- functions --- */ +GtkType +gtk_item_factory_get_type (void) +{ + static GtkType item_factory_type = 0; + + if (!item_factory_type) + { + GtkTypeInfo item_factory_info = + { + "GtkItemFactory", + sizeof (GtkItemFactory), + sizeof (GtkItemFactoryClass), + (GtkClassInitFunc) gtk_item_factory_class_init, + (GtkObjectInitFunc) gtk_item_factory_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL, + }; + + item_factory_type = gtk_type_unique (gtk_object_get_type (), &item_factory_info); + } + + return item_factory_type; +} + +static void +gtk_item_factory_class_init (GtkItemFactoryClass *class) +{ + GtkObjectClass *object_class; + + gtk_item_factory_class = class; + + parent_class = gtk_type_class (gtk_object_get_type ()); + + object_class = (GtkObjectClass*) class; + + object_class->destroy = gtk_item_factory_destroy; + object_class->finalize = gtk_item_factory_finalize; + + class->cpair_comment_single = g_strdup (";\n"); + + class->item_ht = g_hash_table_new (g_str_hash, g_str_equal); + ifactory_item_chunks = + g_mem_chunk_new ("GtkItemFactoryItem", + sizeof (GtkItemFactoryItem), + sizeof (GtkItemFactoryItem) * ITEM_BLOCK_SIZE, + G_ALLOC_ONLY); + ifactory_cb_data_chunks = + g_mem_chunk_new ("GtkIFCBData", + sizeof (GtkIFCBData), + sizeof (GtkIFCBData) * ITEM_BLOCK_SIZE, + G_ALLOC_AND_FREE); + + key_id_popup_data = gtk_object_data_force_id (key_popup_data); + key_id_if_menu_pos = gtk_object_data_force_id (key_if_menu_pos); + key_id_item_factory = gtk_object_data_force_id (key_item_factory); + key_id_item_factory_path = gtk_object_data_force_id (key_item_factory_path); + key_id_type_item = gtk_object_data_force_id (key_type_item); + key_id_type_title = gtk_object_data_force_id (key_type_title); + key_id_type_radio_item = gtk_object_data_force_id (key_type_radio_item); + key_id_type_check_item = gtk_object_data_force_id (key_type_check_item); + key_id_type_toggle_item = gtk_object_data_force_id (key_type_toggle_item); + key_id_type_separator_item = gtk_object_data_force_id (key_type_separator_item); + key_id_type_branch = gtk_object_data_force_id (key_type_branch); + key_id_type_last_branch = gtk_object_data_force_id (key_type_last_branch); +} + +static void +gtk_item_factory_init (GtkItemFactory *ifactory) +{ + GtkObject *object; + + object = GTK_OBJECT (ifactory); + + ifactory->path = NULL; + ifactory->accel_group = NULL; + ifactory->widget = NULL; + ifactory->widgets_by_action = NULL; +} + +GtkItemFactory* +gtk_item_factory_new (GtkType container_type, + const gchar *path, + GtkAccelGroup *accel_group) +{ + GtkItemFactory *ifactory; + + g_return_val_if_fail (path != NULL, NULL); + + ifactory = gtk_type_new (gtk_item_factory_get_type ()); + gtk_item_factory_construct (ifactory, container_type, path, accel_group); + + return ifactory; +} + +static void +gtk_item_factory_callback_marshal (GtkWidget *widget, + gpointer func_data) +{ + GtkIFCBData *data; + + data = func_data; + + data->func (data->func_data, data->callback_action, widget); +} + +static void +gtk_item_factory_propagate_accelerator (GtkItemFactoryItem *item, + GtkWidget *exclude) +{ + GSList *widget_list; + GSList *slist; + + if (item->in_propagation) + return; + + item->in_propagation = TRUE; + + widget_list = NULL; + for (slist = item->widgets; slist; slist = slist->next) + { + GtkWidget *widget; + + widget = slist->data; + + if (widget != exclude) + { + gtk_widget_ref (widget); + widget_list = g_slist_prepend (widget_list, widget); + } + } + + for (slist = widget_list; slist; slist = slist->next) + { + GtkWidget *widget; + GtkItemFactory *ifactory; + + widget = slist->data; + + ifactory = gtk_item_factory_from_widget (widget); + + if (ifactory) + { + guint signal_id; + + signal_id = gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget)); + if (signal_id) + { + if (item->accelerator_key) + gtk_widget_add_accelerator (widget, + "activate", + ifactory->accel_group, + item->accelerator_key, + item->accelerator_mods, + GTK_ACCEL_VISIBLE); + else + { + GSList *slist; + + slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget)); + while (slist) + { + GtkAccelEntry *ac_entry; + + ac_entry = slist->data; + slist = slist->next; + if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE && + ac_entry->accel_group == ifactory->accel_group && + ac_entry->signal_id == signal_id) + gtk_widget_remove_accelerator (GTK_WIDGET (widget), + ac_entry->accel_group, + ac_entry->accelerator_key, + ac_entry->accelerator_mods); + } + } + } + } + gtk_widget_unref (widget); + } + g_slist_free (widget_list); + + item->in_propagation = FALSE; +} + +static gint +gtk_item_factory_item_add_accelerator (GtkWidget *widget, + guint accel_signal_id, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags, + GtkItemFactoryItem *item) +{ + if (!item->in_propagation && + g_slist_find (item->widgets, widget) && + accel_signal_id == gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget))) + { + item->accelerator_key = accel_key; + item->accelerator_mods = accel_mods; + item->modified = TRUE; + + gtk_item_factory_propagate_accelerator (item, widget); + } + + return TRUE; +} + +static void +gtk_item_factory_item_remove_accelerator (GtkWidget *widget, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkItemFactoryItem *item) +{ + if (!item->in_propagation && + g_slist_find (item->widgets, widget) && + item->accelerator_key == accel_key && + item->accelerator_mods == accel_mods) + { + item->accelerator_key = 0; + item->accelerator_mods = 0; + item->modified = TRUE; + + gtk_item_factory_propagate_accelerator (item, widget); + } +} + +static void +gtk_item_factory_item_remove_widget (GtkWidget *widget, + GtkItemFactoryItem *item) +{ + item->widgets = g_slist_remove (item->widgets, widget); + gtk_object_remove_data_by_id (GTK_OBJECT (widget), key_id_item_factory); + gtk_object_remove_data_by_id (GTK_OBJECT (widget), key_id_item_factory_path); +} + +static void +ifactory_cb_data_free (gpointer mem) +{ + g_mem_chunk_free (ifactory_cb_data_chunks, mem); +} + +static void +gtk_item_factory_add_item (GtkItemFactory *ifactory, + const gchar *path, + const gchar *accelerator, + GtkItemFactoryCallback callback, + guint callback_action, + gpointer callback_data, + gchar *item_type, + GtkWidget *widget) +{ + GtkItemFactoryClass *class; + GtkItemFactoryItem *item; + gchar *fpath; + + g_return_if_fail (widget != NULL); + + class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); + + fpath = g_strconcat (ifactory->path, path, NULL); + item = g_hash_table_lookup (class->item_ht, fpath); + + /* link the widget into its item-entry + */ + if (!item) + { + guint keyval; + guint mods; + + if (accelerator) + gtk_accelerator_parse (accelerator, &keyval, &mods); + else + { + keyval = 0; + mods = 0; + } + + item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); + + item->path = fpath; + fpath = NULL; + item->accelerator_key = keyval; + item->accelerator_mods = mods; + item->modified = FALSE; + item->in_propagation = FALSE; + item->item_type = NULL; + item->widgets = NULL; + + g_hash_table_insert (class->item_ht, item->path, item); + } + g_free (fpath); + + if (item->item_type == NULL) + { + g_assert (item->widgets == NULL); + + if (item_type != ITEM_FACTORY_STRING) + item->item_type = g_strdup (item_type); + else + item->item_type = ITEM_FACTORY_STRING; + } + + item->widgets = g_slist_prepend (item->widgets, widget); + gtk_signal_connect (GTK_OBJECT (widget), + "destroy", + GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_widget), + item); + + /* set back pointers for the widget + */ + gtk_object_set_data_by_id (GTK_OBJECT (widget), key_id_item_factory, ifactory); + gtk_object_set_data_by_id (GTK_OBJECT (widget), key_id_item_factory_path, item->path); + gtk_widget_set_name (widget, item->path); + + /* set accelerator group on menu widgets + */ + if (GTK_IS_MENU (widget)) + gtk_menu_set_accel_group ((GtkMenu*) widget, ifactory->accel_group); + + /* install defined accelerators + */ + if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget))) + { + if (item->accelerator_key) + gtk_widget_add_accelerator (widget, + "activate", + ifactory->accel_group, + item->accelerator_key, + item->accelerator_mods, + GTK_ACCEL_VISIBLE); + else + gtk_widget_remove_accelerators (widget, + "activate", + TRUE); + } + + /* keep track of accelerator changes + */ + gtk_signal_connect_after (GTK_OBJECT (widget), + "add-accelerator", + GTK_SIGNAL_FUNC (gtk_item_factory_item_add_accelerator), + item); + gtk_signal_connect_after (GTK_OBJECT (widget), + "remove-accelerator", + GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_accelerator), + item); + + /* keep a per-action list of the widgets on the factory + */ + if (callback_action) + { + GtkIFActionLink *link; + + link = g_new (GtkIFActionLink, 1); + link->widget = widget; + link->callback_action = callback_action; + ifactory->widgets_by_action = g_slist_prepend (ifactory->widgets_by_action, link); + } + + /* connect callback if neccessary + */ + if (callback) + { + GtkIFCBData *data; + + data = g_chunk_new (GtkIFCBData, ifactory_cb_data_chunks); + data->func = callback; + data->func_data = callback_data; + data->callback_action = callback_action; + + gtk_object_weakref (GTK_OBJECT (widget), + ifactory_cb_data_free, + data); + gtk_signal_connect (GTK_OBJECT (widget), + "activate", + GTK_SIGNAL_FUNC (gtk_item_factory_callback_marshal), + data); + } +} + +void +gtk_item_factory_construct (GtkItemFactory *ifactory, + GtkType container_type, + const gchar *path, + GtkAccelGroup *accel_group) +{ + guint len; + + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + g_return_if_fail (ifactory->accel_group == NULL); + g_return_if_fail (path != NULL); + if (!gtk_type_is_a (container_type, gtk_option_menu_get_type ())) + g_return_if_fail (gtk_type_is_a (container_type, gtk_menu_shell_get_type ())); + + len = strlen (path); + + if (path[0] != '<' && path[len - 1] != '>') + { + g_warning ("GtkItemFactory: invalid factory path `%s'", path); + return; + } + + if (accel_group) + { + ifactory->accel_group = accel_group; + gtk_accel_group_ref (ifactory->accel_group); + } + else + ifactory->accel_group = gtk_accel_group_new (); + + ifactory->path = g_strdup (path); + ifactory->widget = + gtk_widget_new (container_type, + "GtkObject::signal::destroy", gtk_widget_destroyed, &ifactory->widget, + NULL); + gtk_object_ref (GTK_OBJECT (ifactory)); + gtk_object_sink (GTK_OBJECT (ifactory)); + gtk_signal_connect_object_while_alive (GTK_OBJECT (ifactory->widget), + "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (ifactory)); + gtk_item_factory_add_item (ifactory, + "", NULL, + NULL, 0, NULL, + ITEM_FACTORY_STRING, + ifactory->widget); +} + +static void +gtk_item_factory_destroy (GtkObject *object) +{ + GtkItemFactory *ifactory; + GSList *slist; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); + + ifactory = (GtkItemFactory*) object; + + if (ifactory->widget) + { + GtkObject *object; + + object = GTK_OBJECT (ifactory->widget); + + gtk_object_ref (object); + gtk_object_sink (object); + gtk_object_destroy (object); + gtk_object_unref (object); + + ifactory->widget = NULL; + } + + for (slist = ifactory->widgets_by_action; slist; slist = slist->next) + g_free (slist->data); + g_slist_free (ifactory->widgets_by_action); + ifactory->widgets_by_action = NULL; + + parent_class->destroy (object); +} + +static void +gtk_item_factory_finalize (GtkObject *object) +{ + GtkItemFactory *ifactory; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); + + ifactory = GTK_ITEM_FACTORY (object); + + gtk_accel_group_unref (ifactory->accel_group); + g_free (ifactory->path); + g_assert (ifactory->widget == NULL); + + parent_class->finalize (object); +} + +GtkItemFactory* +gtk_item_factory_from_widget (GtkWidget *widget) +{ + g_return_val_if_fail (widget != NULL, NULL); + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return gtk_object_get_data_by_id (GTK_OBJECT (widget), key_id_item_factory); +} + +gchar* +gtk_item_factory_path_from_widget (GtkWidget *widget) +{ + g_return_val_if_fail (widget != NULL, NULL); + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return gtk_object_get_data_by_id (GTK_OBJECT (widget), key_id_item_factory_path); +} + +typedef struct +{ + GtkPrintFunc print_func; + gpointer func_data; + guint modified_only : 1; + guint path_length; + const gchar *path; +} DumpLimiterData; + +static void +gtk_item_factory_foreach (gpointer hash_key, + gpointer value, + gpointer user_data) +{ + GtkItemFactoryItem *item; + DumpLimiterData *data; + gchar *string; + gchar *name; + gchar comment_prefix[2] = "\000\000"; + + item = value; + data = user_data; + + if ((data->path && strncmp (item->path, data->path, data->path_length)) || + (data->modified_only && !item->modified)) + return; + + comment_prefix[0] = gtk_item_factory_class->cpair_comment_single[0]; + + name = gtk_accelerator_name (item->accelerator_key, item->accelerator_mods); + string = g_strconcat (item->modified ? "" : comment_prefix, + "(menu-path \"", + hash_key, + "\" \"", + name, + "\")", + NULL); + g_free (name); + + data->print_func (data->func_data, string); + + g_free (string); +} + +void +gtk_item_factory_dump_rc (const gchar *ifactory_path, + gboolean modified_only, + GtkPrintFunc print_func, + gpointer func_data) +{ + DumpLimiterData data; + + g_return_if_fail (print_func != NULL); + + if (!gtk_item_factory_class) + gtk_type_class (GTK_TYPE_ITEM_FACTORY); + + data.print_func = print_func; + data.func_data = func_data; + data.modified_only = (modified_only != FALSE); + data.path_length = ifactory_path ? strlen (ifactory_path) : 0; + data.path = ifactory_path; + + g_hash_table_foreach (gtk_item_factory_class->item_ht, gtk_item_factory_foreach, &data); +} + +void +gtk_item_factory_create_items (GtkItemFactory *ifactory, + guint n_entries, + GtkItemFactoryEntry *entries, + gpointer callback_data) +{ + guint i; + + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + if (n_entries == 0) return; + g_return_if_fail (entries != NULL); + + for (i = 0; i < n_entries; i++) + gtk_item_factory_create_item (ifactory, entries + i, callback_data); +} + +GtkWidget* +gtk_item_factory_get_widget (GtkItemFactory *ifactory, + const gchar *path) +{ + GtkItemFactoryClass *class; + GtkItemFactoryItem *item; + gchar *fpath; + + g_return_val_if_fail (ifactory != NULL, NULL); + g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); + g_return_val_if_fail (path != NULL, NULL); + + class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); + + fpath = g_strconcat (ifactory->path, path, NULL); + item = g_hash_table_lookup (class->item_ht, fpath); + g_free (fpath); + + if (item) + { + GSList *slist; + + for (slist = item->widgets; slist; slist = slist->next) + { + if (gtk_item_factory_from_widget (slist->data) == ifactory) + return slist->data; + } + } + + return NULL; +} + +GtkWidget* +gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory, + guint action) +{ + GSList *slist; + + g_return_val_if_fail (ifactory != NULL, NULL); + g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); + + for (slist = ifactory->widgets_by_action; slist; slist = slist->next) + { + GtkIFActionLink *link; + + link = slist->data; + + if (link->callback_action == action) + return link->widget; + } + + return NULL; +} + +void +gtk_item_factory_create_item (GtkItemFactory *ifactory, + GtkItemFactoryEntry *entry, + gpointer callback_data) +{ + GtkWidget *parent; + GtkWidget *widget; + GSList *radio_group; + gchar *parent_path; + gchar *p; + guint type_id; + GtkType type; + + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + g_return_if_fail (entry != NULL); + g_return_if_fail (entry->path != NULL); + g_return_if_fail (entry->path[0] == PARENT_DELIMITER); + + if (!entry->item_type || + entry->item_type == 0) + type_id = key_id_type_item; + else + type_id = gtk_object_data_try_key (entry->item_type); + + radio_group = NULL; + if (type_id == key_id_type_item) + type = gtk_menu_item_get_type (); + else if (type_id == key_id_type_title) + type = gtk_menu_item_get_type (); + else if (type_id == key_id_type_radio_item) + type = gtk_radio_menu_item_get_type (); + else if (type_id == key_id_type_check_item) + type = gtk_check_menu_item_get_type (); + else if (type_id == key_id_type_toggle_item) + type = gtk_check_menu_item_get_type (); + else if (type_id == key_id_type_separator_item) + type = gtk_menu_item_get_type (); + else if (type_id == key_id_type_branch) + type = gtk_menu_item_get_type (); + else if (type_id == key_id_type_last_branch) + type = gtk_menu_item_get_type (); + else + { + GtkWidget *radio_link; + + radio_link = gtk_item_factory_get_widget (ifactory, entry->item_type); + if (radio_link && GTK_IS_RADIO_MENU_ITEM (radio_link)) + { + type = gtk_radio_menu_item_get_type (); + radio_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (radio_link)); + } + else + { + g_warning ("GtkItemFactory: entry path `%s' has invalid type `%s'", + entry->path, + entry->item_type); + return; + } + } + + parent_path = g_strdup (entry->path); + p = strrchr (parent_path, PARENT_DELIMITER); + if (!p) + { + g_warning ("GtkItemFactory: invalid entry path `%s'", entry->path); + return; + } + *p = 0; + + parent = gtk_item_factory_get_widget (ifactory, parent_path); + if (!parent) + { + GtkItemFactoryEntry pentry; + + pentry.path = parent_path; + pentry.accelerator = NULL; + pentry.callback = NULL; + pentry.callback_action = 0; + pentry.item_type = "<Branch>"; + + gtk_item_factory_create_item (ifactory, &pentry, NULL); + + parent = gtk_item_factory_get_widget (ifactory, parent_path); + } + g_free (parent_path); + + g_return_if_fail (parent != NULL); + + p = strrchr (entry->path, PARENT_DELIMITER); + p++; + + widget = gtk_widget_new (type, + "GtkWidget::visible", TRUE, + "GtkWidget::sensitive", (type_id != key_id_type_separator_item && + type_id != key_id_type_title), + "GtkWidget::parent", parent, + NULL); + + if (type == gtk_radio_menu_item_get_type ()) + gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget), radio_group); + if (GTK_IS_CHECK_MENU_ITEM (widget)) + gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (widget), TRUE); + + if (type_id != key_id_type_separator_item && *p) + { + GtkWidget *label; + + label = + gtk_widget_new (GTK_TYPE_ACCEL_LABEL, + "GtkLabel::label", p, + "GtkWidget::visible", TRUE, + "GtkWidget::parent", widget, + "GtkAccelLabel::accel_widget", widget, + "GtkMisc::xalign", 0.0, + NULL); + } + if (type_id == key_id_type_branch || + type_id == key_id_type_last_branch) + { + if (type_id == key_id_type_last_branch) + gtk_menu_item_right_justify (GTK_MENU_ITEM (widget)); + + parent = widget; + widget = + gtk_widget_new (gtk_menu_get_type (), + NULL); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent), widget); + } + + gtk_item_factory_add_item (ifactory, + entry->path, entry->accelerator, + entry->callback, entry->callback_action, callback_data, + entry->item_type, + widget); +} + +void +gtk_item_factory_path_delete (const gchar *ifactory_path, + const gchar *path) +{ + GtkItemFactoryClass *class; + GtkItemFactoryItem *item; + gchar *fpath; + + g_return_if_fail (ifactory_path != NULL); + g_return_if_fail (path != NULL); + + class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); + + fpath = g_strconcat (ifactory_path, path, NULL); + item = g_hash_table_lookup (class->item_ht, fpath); + g_free (fpath); + + if (item) + { + GSList *widget_list; + GSList *slist; + + widget_list = NULL; + for (slist = item->widgets; slist; slist = slist->next) + { + GtkWidget *widget; + + widget = slist->data; + widget_list = g_slist_prepend (widget_list, widget); + gtk_widget_ref (widget); + } + + for (slist = widget_list; slist; slist = slist->next) + { + GtkWidget *widget; + + widget = slist->data; + gtk_widget_destroy (widget); + gtk_widget_unref (widget); + } + g_slist_free (widget_list); + } +} + +void +gtk_item_factory_delete_item (GtkItemFactory *ifactory, + const gchar *path) +{ + GtkItemFactoryClass *class; + GtkItemFactoryItem *item; + gchar *fpath; + + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + g_return_if_fail (path != NULL); + + class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); + + fpath = g_strconcat (ifactory->path, path, NULL); + item = g_hash_table_lookup (class->item_ht, fpath); + g_free (fpath); + + if (item) + { + GtkWidget *widget = NULL; + GSList *slist; + + for (slist = item->widgets; slist; slist = slist->next) + { + widget = slist->data; + + if (gtk_item_factory_from_widget (widget) == ifactory) + break; + } + + if (slist) + gtk_widget_destroy (widget); + } +} + +void +gtk_item_factory_delete_entry (GtkItemFactory *ifactory, + GtkItemFactoryEntry *entry) +{ + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + g_return_if_fail (entry != NULL); + + gtk_item_factory_delete_item (ifactory, entry->path); +} + +void +gtk_item_factory_delete_entries (GtkItemFactory *ifactory, + guint n_entries, + GtkItemFactoryEntry *entries) +{ + guint i; + + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + if (n_entries > 0) + g_return_if_fail (entries != NULL); + + for (i = 0; i < n_entries; i++) + gtk_item_factory_delete_item (ifactory, (entries + i)->path); +} + +typedef struct +{ + guint x; + guint y; +} MenuPos; + +static void +gtk_item_factory_menu_pos (GtkMenu *menu, + gint *x, + gint *y, + gpointer func_data) +{ + MenuPos *mpos = func_data; + + *x = mpos->x; + *y = mpos->y; +} + +gpointer +gtk_item_factory_popup_data_from_widget (GtkWidget *widget) +{ + GtkItemFactory *ifactory; + + g_return_val_if_fail (widget != NULL, NULL); + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + ifactory = gtk_item_factory_from_widget (widget); + if (ifactory) + return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), key_id_popup_data); + + return NULL; +} + +gpointer +gtk_item_factory_popup_data (GtkItemFactory *ifactory) +{ + g_return_val_if_fail (ifactory != NULL, NULL); + g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); + + return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), key_id_popup_data); +} + +static void +ifactory_delete_popup_data (GtkObject *object, + GtkItemFactory *ifactory) +{ + gtk_signal_disconnect_by_func (object, + GTK_SIGNAL_FUNC (ifactory_delete_popup_data), + ifactory); + gtk_object_remove_data_by_id (GTK_OBJECT (ifactory), key_id_popup_data); +} + +void +gtk_item_factory_popup (GtkItemFactory *ifactory, + guint x, + guint y, + guint mouse_button, + guint32 time) +{ + gtk_item_factory_popup_with_data (ifactory, NULL, NULL, x, y, mouse_button, time); +} + +void +gtk_item_factory_popup_with_data (GtkItemFactory *ifactory, + gpointer popup_data, + GtkDestroyNotify destroy, + guint x, + guint y, + guint mouse_button, + guint32 time) +{ + g_return_if_fail (ifactory != NULL); + g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); + g_return_if_fail (GTK_IS_MENU (ifactory->widget)); + + if (!GTK_WIDGET_VISIBLE (ifactory->widget)) + { + MenuPos *mpos; + + mpos = gtk_object_get_data_by_id (GTK_OBJECT (ifactory->widget), key_id_if_menu_pos); + + if (!mpos) + { + mpos = g_new0 (MenuPos, 1); + gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory->widget), + key_id_if_menu_pos, + mpos, + g_free); + } + + mpos->x = x; + mpos->y = y; + + if (popup_data != NULL) + { + gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory), + key_id_popup_data, + popup_data, + destroy); + gtk_signal_connect (GTK_OBJECT (ifactory->widget), + "selection-done", + GTK_SIGNAL_FUNC (ifactory_delete_popup_data), + ifactory); + } + + gtk_menu_popup (GTK_MENU (ifactory->widget), + NULL, NULL, + gtk_item_factory_menu_pos, mpos, + mouse_button, time); + } +} + +static guint +gtk_item_factory_parse_menu_path (GScanner *scanner, + GtkItemFactoryClass *class) +{ + GtkItemFactoryItem *item; + + g_scanner_get_next_token (scanner); + if (scanner->token != G_TOKEN_STRING) + return G_TOKEN_STRING; + + g_scanner_peek_next_token (scanner); + if (scanner->next_token != G_TOKEN_STRING) + { + g_scanner_get_next_token (scanner); + return G_TOKEN_STRING; + } + + item = g_hash_table_lookup (class->item_ht, scanner->value.v_string); + if (!item) + { + item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); + + item->path = g_strdup (scanner->value.v_string); + item->accelerator_key = 0; + item->accelerator_mods = 0; + item->modified = FALSE; + item->in_propagation = FALSE; + item->item_type = NULL; + item->widgets = NULL; + + g_hash_table_insert (class->item_ht, item->path, item); + } + g_scanner_get_next_token (scanner); + + if (!item->in_propagation) + { + guint old_keyval; + guint old_mods; + + old_keyval = item->accelerator_key; + old_mods = item->accelerator_mods; + gtk_accelerator_parse (scanner->value.v_string, + &item->accelerator_key, + &item->accelerator_mods); + if (old_keyval != item->accelerator_key || + old_mods != item->accelerator_mods) + { + item->modified = TRUE; + gtk_item_factory_propagate_accelerator (item, NULL); + } + } + + g_scanner_get_next_token (scanner); + if (scanner->token != ')') + return ')'; + else + return G_TOKEN_NONE; +} + +static void +gtk_item_factory_parse_statement (GScanner *scanner, + GtkItemFactoryClass *class) +{ + guint expected_token; + + g_scanner_get_next_token (scanner); + + if (scanner->token == G_TOKEN_SYMBOL) + { + guint (*parser_func) (GScanner*, GtkItemFactoryClass*); + + parser_func = scanner->value.v_symbol; + + /* check whether this is a GtkItemFactory symbol... + */ + if (parser_func == gtk_item_factory_parse_menu_path) + expected_token = parser_func (scanner, class); + else + expected_token = G_TOKEN_SYMBOL; + } + else + expected_token = G_TOKEN_SYMBOL; + + /* skip rest of statement on errrors + */ + if (expected_token != G_TOKEN_NONE) + { + register guint level; + + level = 1; + if (scanner->token == ')') + level--; + if (scanner->token == '(') + level++; + + while (!g_scanner_eof (scanner) && level > 0) + { + g_scanner_get_next_token (scanner); + + if (scanner->token == '(') + level++; + else if (scanner->token == ')') + level--; + } + } +} + +void +gtk_item_factory_parse_rc_string (const gchar *rc_string) +{ + GScanner *scanner; + + g_return_if_fail (rc_string != NULL); + + scanner = g_scanner_new (&ifactory_scanner_config); + + g_scanner_input_text (scanner, rc_string, strlen (rc_string)); + + gtk_item_factory_parse_rc_scanner (scanner); + + g_scanner_destroy (scanner); +} + +void +gtk_item_factory_parse_rc_scanner (GScanner *scanner) +{ + gchar *orig_cpair_comment_single; + gpointer saved_symbol; + + g_return_if_fail (scanner != NULL); + + if (!gtk_item_factory_class) + gtk_type_class (GTK_TYPE_ITEM_FACTORY); + + saved_symbol = g_scanner_lookup_symbol (scanner, "menu-path"); + g_scanner_remove_symbol (scanner, "menu-path"); + g_scanner_add_symbol (scanner, "menu-path", gtk_item_factory_parse_menu_path); + + orig_cpair_comment_single = scanner->config->cpair_comment_single; + scanner->config->cpair_comment_single = gtk_item_factory_class->cpair_comment_single; + + g_scanner_peek_next_token (scanner); + + while (scanner->next_token == '(') + { + g_scanner_get_next_token (scanner); + + gtk_item_factory_parse_statement (scanner, gtk_item_factory_class); + + g_scanner_peek_next_token (scanner); + } + + scanner->config->cpair_comment_single = orig_cpair_comment_single; + + g_scanner_remove_symbol (scanner, "menu-path"); + g_scanner_add_symbol (scanner, "menu-path", saved_symbol); +} + +void +gtk_item_factory_parse_rc (const gchar *file_name) +{ + gint fd; + GScanner *scanner; + + g_return_if_fail (file_name != NULL); + + if (!S_ISREG (g_scanner_stat_mode (file_name))) + return; + + fd = open (file_name, O_RDONLY); + if (fd < 0) + return; + + scanner = g_scanner_new (&ifactory_scanner_config); + + g_scanner_input_file (scanner, fd); + + gtk_item_factory_parse_rc_scanner (scanner); + + g_scanner_destroy (scanner); + + close (fd); +} diff --git a/gtk/gtkitemfactory.h b/gtk/gtkitemfactory.h new file mode 100644 index 0000000000..92cd6691fc --- /dev/null +++ b/gtk/gtkitemfactory.h @@ -0,0 +1,182 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GtkItemFactory: Flexible item factory with automatic rc handling + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __GTK_ITEM_FACTORY_H__ +#define __GTK_ITEM_FACTORY_H__ + + +#include <gtk/gtkwidget.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + +typedef void (*GtkPrintFunc) (gpointer func_data, + gchar *str); +typedef void (*GtkItemFactoryCallback) (gpointer callback_data, + guint callback_action, + GtkWidget *widget); + +#define GTK_TYPE_ITEM_FACTORY (gtk_item_factory_get_type ()) +#define GTK_ITEM_FACTORY(object) (GTK_CHECK_CAST (object, GTK_TYPE_ITEM_FACTORY, GtkItemFactory)) +#define GTK_ITEM_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, GTK_TYPE_ITEM_FACTORY, GtkItemFactoryClass)) +#define GTK_IS_ITEM_FACTORY(object) (GTK_CHECK_TYPE (object, GTK_TYPE_ITEM_FACTORY)) +#define GTK_IS_ITEM_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ITEM_FACTORY)) + +typedef struct _GtkItemFactory GtkItemFactory; +typedef struct _GtkItemFactoryClass GtkItemFactoryClass; +typedef struct _GtkItemFactoryEntry GtkItemFactoryEntry; +typedef struct _GtkItemFactoryItem GtkItemFactoryItem; + +struct _GtkItemFactory +{ + GtkObject object; + + gchar *path; + GtkAccelGroup *accel_group; + GtkWidget *widget; + GSList *widgets_by_action; +}; + +struct _GtkItemFactoryClass +{ + GtkObjectClass object_class; + + gchar *cpair_comment_single; + + GHashTable *item_ht; +}; + +struct _GtkItemFactoryEntry +{ + gchar *path; + gchar *accelerator; + + GtkItemFactoryCallback callback; + guint callback_action; + + /* possible values: + * NULL -> "<Item>" + * "" -> "<Item>" + * "<Title>" -> create a title item + * "<Item>" -> create a simple item + * "<CheckItem>" -> create a check item + * "<ToggleItem>" -> create a toggle item + * "<RadioItem>" -> create a radio item + * <path> -> path of a radio item to link against + * "<Separator>" -> create a separator + * "<Branch>" -> create an item to hold sub items + * "<LastBranch>" -> create a right justified item to hold sub items + */ + gchar *item_type; +}; + +struct _GtkItemFactoryItem +{ + gchar *path; + guint accelerator_key; + guint accelerator_mods; + guint modified : 1; + guint in_propagation : 1; + gchar *item_type; + + GSList *widgets; +}; + + +GtkType gtk_item_factory_get_type (void); + +/* `container_type' must be of gtk_menu_bar_get_type (), gtk_menu_get_type (), + * or gtk_option_menu_get_type (). + */ +GtkItemFactory* gtk_item_factory_new (GtkType container_type, + const gchar *path, + GtkAccelGroup *accel_group); +void gtk_item_factory_construct (GtkItemFactory *ifactory, + GtkType container_type, + const gchar *path, + GtkAccelGroup *accel_group); + +/* These functions operate on GtkItemFactoryClass basis. + */ +void gtk_item_factory_parse_rc (const gchar *file_name); +void gtk_item_factory_parse_rc_string (const gchar *rc_string); +void gtk_item_factory_parse_rc_scanner (GScanner *scanner); + +GtkItemFactory* gtk_item_factory_from_widget (GtkWidget *widget); +gchar* gtk_item_factory_path_from_widget (GtkWidget *widget); + +GtkWidget* gtk_item_factory_get_widget (GtkItemFactory *ifactory, + const gchar *path); +GtkWidget* gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory, + guint action); + +/* If `ifactory_path' is passed as `NULL', this function will iterate over + * all hash entries. + */ +void gtk_item_factory_dump_rc (const gchar *ifactory_path, + gboolean modified_only, + GtkPrintFunc print_func, + gpointer func_data); +void gtk_item_factory_create_item (GtkItemFactory *ifactory, + GtkItemFactoryEntry *entry, + gpointer callback_data); +void gtk_item_factory_create_items (GtkItemFactory *ifactory, + guint n_entries, + GtkItemFactoryEntry *entries, + gpointer callback_data); +void gtk_item_factory_path_delete (const gchar *ifactory_path, + const gchar *path); +void gtk_item_factory_delete_item (GtkItemFactory *ifactory, + const gchar *path); +void gtk_item_factory_delete_entry (GtkItemFactory *ifactory, + GtkItemFactoryEntry *entry); +void gtk_item_factory_delete_entries (GtkItemFactory *ifactory, + guint n_entries, + GtkItemFactoryEntry *entries); +void gtk_item_factory_popup (GtkItemFactory *ifactory, + guint x, + guint y, + guint mouse_button, + guint32 time); +void gtk_item_factory_popup_with_data(GtkItemFactory *ifactory, + gpointer popup_data, + GtkDestroyNotify destroy, + guint x, + guint y, + guint mouse_button, + guint32 time); +gpointer gtk_item_factory_popup_data (GtkItemFactory *ifactory); +gpointer gtk_item_factory_popup_data_from_widget (GtkWidget *widget); + + + + + +#ifdef __cplusplus +#pragma { +} +#endif /* __cplusplus */ + + +#endif /* __GTK_ITEM_FACTORY_H__ */ diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index dd31a71d34..a4a955f8d4 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -27,33 +27,33 @@ enum { }; static void gtk_label_class_init (GtkLabelClass *klass); -static void gtk_label_init (GtkLabel *label); -static void gtk_label_set_arg (GtkLabel *label, - GtkArg *arg, - guint arg_id); -static void gtk_label_get_arg (GtkLabel *label, - GtkArg *arg, - guint arg_id); -static void gtk_label_finalize (GtkObject *object); -static void gtk_label_size_request (GtkWidget *widget, +static void gtk_label_init (GtkLabel *label); +static void gtk_label_set_arg (GtkLabel *label, + GtkArg *arg, + guint arg_id); +static void gtk_label_get_arg (GtkLabel *label, + GtkArg *arg, + guint arg_id); +static void gtk_label_finalize (GtkObject *object); +static void gtk_label_size_request (GtkWidget *widget, GtkRequisition *requisition); -static gint gtk_label_expose (GtkWidget *widget, +static gint gtk_label_expose (GtkWidget *widget, GdkEventExpose *event); -static void gtk_label_state_changed (GtkWidget *widget, +static void gtk_label_state_changed (GtkWidget *widget, guint previous_state); -static void gtk_label_style_set (GtkWidget *widget, - GtkStyle *previous_style); +static void gtk_label_style_set (GtkWidget *widget, + GtkStyle *previous_style); static GtkMiscClass *parent_class = NULL; -guint +GtkType gtk_label_get_type (void) { - static guint label_type = 0; - + static GtkType label_type = 0; + if (!label_type) { GtkTypeInfo label_info = @@ -64,13 +64,13 @@ gtk_label_get_type (void) (GtkClassInitFunc) gtk_label_class_init, (GtkObjectInitFunc) gtk_label_init, (GtkArgSetFunc) gtk_label_set_arg, - (GtkArgGetFunc) gtk_label_get_arg, + (GtkArgGetFunc) gtk_label_get_arg, }; - + label_type = gtk_type_unique (gtk_misc_get_type (), &label_info); gtk_type_set_chunk_alloc (label_type, 32); } - + return label_type; } @@ -79,17 +79,17 @@ gtk_label_class_init (GtkLabelClass *class) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - + object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; - + parent_class = gtk_type_class (gtk_misc_get_type ()); - + gtk_object_add_arg_type ("GtkLabel::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL); gtk_object_add_arg_type ("GtkLabel::justify", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_JUSTIFY); - + object_class->finalize = gtk_label_finalize; - + widget_class->size_request = gtk_label_size_request; widget_class->expose_event = gtk_label_expose; widget_class->style_set = gtk_label_style_set; @@ -97,9 +97,9 @@ gtk_label_class_init (GtkLabelClass *class) } static void -gtk_label_set_arg (GtkLabel *label, - GtkArg *arg, - guint arg_id) +gtk_label_set_arg (GtkLabel *label, + GtkArg *arg, + guint arg_id) { switch (arg_id) { @@ -115,9 +115,10 @@ gtk_label_set_arg (GtkLabel *label, } } -static void gtk_label_get_arg (GtkLabel *label, - GtkArg *arg, - guint arg_id) +static void +gtk_label_get_arg (GtkLabel *label, + GtkArg *arg, + guint arg_id) { switch (arg_id) { @@ -137,43 +138,44 @@ static void gtk_label_init (GtkLabel *label) { GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW); - + label->label = NULL; label->row = NULL; + label->max_width = 0; label->jtype = GTK_JUSTIFY_CENTER; - label->needs_clear = 0; - + label->needs_clear = FALSE; + gtk_label_set (label, ""); } GtkWidget* -gtk_label_new (const char *str) +gtk_label_new (const gchar *str) { GtkLabel *label; - + g_return_val_if_fail (str != NULL, NULL); - + label = gtk_type_new (gtk_label_get_type ()); - + gtk_label_set (label, str); - + return GTK_WIDGET (label); } void -gtk_label_set (GtkLabel *label, - const char *str) +gtk_label_set (GtkLabel *label, + const gchar *str) { char* p; - + g_return_if_fail (label != NULL); g_return_if_fail (GTK_IS_LABEL (label)); g_return_if_fail (str != NULL); - + if (label->label) g_free (label->label); label->label = g_strdup (str); - + if (label->row) g_slist_free (label->row); label->row = NULL; @@ -181,7 +183,7 @@ gtk_label_set (GtkLabel *label, p = label->label; while ((p = strchr(p, '\n'))) label->row = g_slist_append (label->row, ++p); - + if (GTK_WIDGET_VISIBLE (label)) { if (GTK_WIDGET_MAPPED (label)) @@ -190,43 +192,44 @@ gtk_label_set (GtkLabel *label, GTK_WIDGET (label)->allocation.y, GTK_WIDGET (label)->allocation.width, GTK_WIDGET (label)->allocation.height); - + gtk_widget_queue_resize (GTK_WIDGET (label)); } } void -gtk_label_set_justify (GtkLabel *label, GtkJustification jtype) +gtk_label_set_justify (GtkLabel *label, + GtkJustification jtype) { g_return_if_fail (label != NULL); g_return_if_fail (GTK_IS_LABEL (label)); - + if ((GtkJustification) label->jtype != jtype) { label->jtype = jtype; if (GTK_WIDGET_VISIBLE (label)) - { - if (GTK_WIDGET_MAPPED (label)) - gdk_window_clear_area (GTK_WIDGET (label)->window, - GTK_WIDGET (label)->allocation.x, - GTK_WIDGET (label)->allocation.y, - GTK_WIDGET (label)->allocation.width, - GTK_WIDGET (label)->allocation.height); - - gtk_widget_queue_resize (GTK_WIDGET (label)); - } + { + if (GTK_WIDGET_MAPPED (label)) + gdk_window_clear_area (GTK_WIDGET (label)->window, + GTK_WIDGET (label)->allocation.x, + GTK_WIDGET (label)->allocation.y, + GTK_WIDGET (label)->allocation.width, + GTK_WIDGET (label)->allocation.height); + + gtk_widget_queue_resize (GTK_WIDGET (label)); + } } } void -gtk_label_get (GtkLabel *label, - char **str) +gtk_label_get (GtkLabel *label, + gchar **str) { g_return_if_fail (label != NULL); g_return_if_fail (GTK_IS_LABEL (label)); g_return_if_fail (str != NULL); - + *str = label->label; } @@ -254,36 +257,37 @@ gtk_label_size_request (GtkWidget *widget, GtkLabel *label; GSList *row; gint width; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LABEL (widget)); g_return_if_fail (requisition != NULL); - + label = GTK_LABEL (widget); - + row = label->row; width = 0; while (row) { if (row->next) - width = MAX (width, - gdk_text_width (GTK_WIDGET (label)->style->font, - row->data, - (gchar*) row->next->data - (gchar*) row->data - 1)); + width = MAX (width, + gdk_text_width (GTK_WIDGET (label)->style->font, + row->data, + (gchar*) row->next->data - (gchar*) row->data - 1)); else - width = MAX (width, gdk_string_width (GTK_WIDGET (label)->style->font, row->data)); + width = MAX (width, gdk_string_width (GTK_WIDGET (label)->style->font, row->data)); row = row->next; } - + + label->max_width = width; requisition->width = width + label->misc.xpad * 2; requisition->height = ((GTK_WIDGET (label)->style->font->ascent + - GTK_WIDGET (label)->style->font->descent + 2) * - g_slist_length(label->row) + - label->misc.ypad * 2); + GTK_WIDGET (label)->style->font->descent + 2) * + g_slist_length(label->row) + + label->misc.ypad * 2); } static gint -gtk_label_expose (GtkWidget *widget, +gtk_label_expose (GtkWidget *widget, GdkEventExpose *event) { GtkLabel *label; @@ -292,28 +296,25 @@ gtk_label_expose (GtkWidget *widget, gint state; gint offset; gint len; - gint maxl; gint x, y; - + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_LABEL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget)) { label = GTK_LABEL (widget); misc = GTK_MISC (widget); - + state = widget->state; - - maxl = widget->requisition.width - misc->xpad * 2; - + /* * GC Clipping */ gdk_gc_set_clip_rectangle (widget->style->white_gc, &event->area); gdk_gc_set_clip_rectangle (widget->style->fg_gc[state], &event->area); - + /* We clear the whole allocation here so that if a partial * expose is triggered we don't just clear part and mess up * when the queued redraw comes along. (There will always @@ -327,31 +328,31 @@ gtk_label_expose (GtkWidget *widget, widget->allocation.y, widget->allocation.width, widget->allocation.height); - + label->needs_clear = FALSE; } - + x = widget->allocation.x + misc->xpad + - (widget->allocation.width - widget->requisition.width) + (widget->allocation.width - (label->max_width + label->misc.xpad * 2)) * misc->xalign + 0.5; - + y = (widget->allocation.y * (1.0 - misc->yalign) + (widget->allocation.y + widget->allocation.height - (widget->requisition.height - misc->ypad * 2)) * misc->yalign + widget->style->font->ascent) + 1.5; - + row = label->row; while (row && row->next) { len = (gchar*) row->next->data - (gchar*) row->data - 1; offset = 0; - + if (label->jtype == GTK_JUSTIFY_CENTER) - offset = (maxl - gdk_text_width (widget->style->font, row->data, len)) / 2; - + offset = (label->max_width - gdk_text_width (widget->style->font, row->data, len)) / 2; + else if (label->jtype == GTK_JUSTIFY_RIGHT) - offset = (maxl - gdk_text_width (widget->style->font, row->data, len)); - + offset = (label->max_width - gdk_text_width (widget->style->font, row->data, len)); + if (state == GTK_STATE_INSENSITIVE) gdk_draw_text (widget->window, widget->style->font, widget->style->white_gc, @@ -370,13 +371,13 @@ gtk_label_expose (GtkWidget *widget, * Once we have a wrapping interface we can support GTK_JUSTIFY_FILL. */ offset = 0; - + if (label->jtype == GTK_JUSTIFY_CENTER) - offset = (maxl - gdk_string_width (widget->style->font, row->data)) / 2; - + offset = (label->max_width - gdk_string_width (widget->style->font, row->data)) / 2; + else if (label->jtype == GTK_JUSTIFY_RIGHT) - offset = (maxl - gdk_string_width (widget->style->font, row->data)); - + offset = (label->max_width - gdk_string_width (widget->style->font, row->data)); + if (state == GTK_STATE_INSENSITIVE) gdk_draw_string (widget->window, widget->style->font, widget->style->white_gc, @@ -385,27 +386,27 @@ gtk_label_expose (GtkWidget *widget, gdk_draw_string (widget->window, widget->style->font, widget->style->fg_gc[state], offset + x, y, row->data); - + gdk_gc_set_clip_mask (widget->style->white_gc, NULL); gdk_gc_set_clip_mask (widget->style->fg_gc[state], NULL); - + } return TRUE; } static void -gtk_label_state_changed (GtkWidget *widget, - guint previous_state) +gtk_label_state_changed (GtkWidget *widget, + guint previous_state) { if (GTK_WIDGET_DRAWABLE (widget)) - GTK_LABEL (widget)->needs_clear = 1; + GTK_LABEL (widget)->needs_clear = TRUE; } static void -gtk_label_style_set (GtkWidget *widget, - GtkStyle *previous_style) +gtk_label_style_set (GtkWidget *widget, + GtkStyle *previous_style) { if (GTK_WIDGET_DRAWABLE (widget)) - GTK_LABEL (widget)->needs_clear = 1; + GTK_LABEL (widget)->needs_clear = TRUE; } diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index 047c78b680..331b2a788f 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -26,12 +26,14 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ - -#define GTK_LABEL(obj) GTK_CHECK_CAST (obj, gtk_label_get_type (), GtkLabel) -#define GTK_LABEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_label_get_type (), GtkLabelClass) -#define GTK_IS_LABEL(obj) GTK_CHECK_TYPE (obj, gtk_label_get_type ()) +#define GTK_TYPE_LABEL (gtk_label_get_type ()) +#define GTK_LABEL(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_LABEL, GtkLabel)) +#define GTK_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_LABEL, GtkLabelClass)) +#define GTK_IS_LABEL(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_LABEL)) +#define GTK_IS_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_LABEL)) typedef struct _GtkLabel GtkLabel; @@ -40,11 +42,12 @@ typedef struct _GtkLabelClass GtkLabelClass; struct _GtkLabel { GtkMisc misc; - - char *label; + + gchar *label; GSList *row; - guint jtype : 2; - gint needs_clear : 1; + guint max_width : 16; + guint jtype : 2; + guint needs_clear : 1; }; struct _GtkLabelClass @@ -53,14 +56,14 @@ struct _GtkLabelClass }; -guint gtk_label_get_type (void); -GtkWidget* gtk_label_new (const char *str); -void gtk_label_set (GtkLabel *label, - const char *str); -void gtk_label_set_justify (GtkLabel *label, - GtkJustification jtype); -void gtk_label_get (GtkLabel *label, - char **str); +GtkType gtk_label_get_type (void); +GtkWidget* gtk_label_new (const gchar *string); +void gtk_label_set (GtkLabel *label, + const gchar *string); +void gtk_label_set_justify (GtkLabel *label, + GtkJustification jtype); +void gtk_label_get (GtkLabel *label, + gchar **string); #ifdef __cplusplus diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index a04d953f2f..fc38a776ad 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -231,8 +231,13 @@ void gtk_init (int *argc, char ***argv) { + static gboolean gtk_initialized = FALSE; gchar *current_locale; + if (gtk_initialized) + return; + gtk_initialized = TRUE; + if (0) { g_set_error_handler (gtk_error); diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 82a60310c6..475e3576b8 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -24,8 +24,8 @@ #include "gtksignal.h" -#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass) - +#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass) +#define MENU_NEEDS_RESIZE(m) GTK_MENU_SHELL (m)->menu_flag typedef struct _GtkMenuAttachData GtkMenuAttachData; @@ -36,40 +36,40 @@ struct _GtkMenuAttachData }; -static void gtk_menu_class_init (GtkMenuClass *klass); -static void gtk_menu_init (GtkMenu *menu); -static void gtk_menu_destroy (GtkObject *object); -static void gtk_menu_show (GtkWidget *widget); -static void gtk_menu_map (GtkWidget *widget); -static void gtk_menu_unmap (GtkWidget *widget); -static void gtk_menu_realize (GtkWidget *widget); -static void gtk_menu_size_request (GtkWidget *widget, +static void gtk_menu_class_init (GtkMenuClass *klass); +static void gtk_menu_init (GtkMenu *menu); +static void gtk_menu_destroy (GtkObject *object); +static void gtk_menu_show (GtkWidget *widget); +static void gtk_menu_map (GtkWidget *widget); +static void gtk_menu_unmap (GtkWidget *widget); +static void gtk_menu_realize (GtkWidget *widget); +static void gtk_menu_size_request (GtkWidget *widget, GtkRequisition *requisition); -static void gtk_menu_size_allocate (GtkWidget *widget, +static void gtk_menu_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_menu_paint (GtkWidget *widget); -static void gtk_menu_draw (GtkWidget *widget, +static void gtk_menu_paint (GtkWidget *widget); +static void gtk_menu_draw (GtkWidget *widget, GdkRectangle *area); -static gint gtk_menu_expose (GtkWidget *widget, +static gint gtk_menu_expose (GtkWidget *widget, GdkEventExpose *event); -static gint gtk_menu_configure (GtkWidget *widget, +static gint gtk_menu_configure (GtkWidget *widget, GdkEventConfigure *event); -static gint gtk_menu_key_press (GtkWidget *widget, +static gint gtk_menu_key_press (GtkWidget *widget, GdkEventKey *event); static gint gtk_menu_need_resize (GtkContainer *container); -static void gtk_menu_deactivate (GtkMenuShell *menu_shell); -static void gtk_menu_show_all (GtkWidget *widget); -static void gtk_menu_hide_all (GtkWidget *widget); +static void gtk_menu_deactivate (GtkMenuShell *menu_shell); +static void gtk_menu_show_all (GtkWidget *widget); +static void gtk_menu_hide_all (GtkWidget *widget); static GtkMenuShellClass *parent_class = NULL; static const gchar *attach_data_key = "gtk-menu-attach-data"; -guint +GtkType gtk_menu_get_type (void) { - static guint menu_type = 0; - + static GtkType menu_type = 0; + if (!menu_type) { GtkTypeInfo menu_info = @@ -80,12 +80,12 @@ gtk_menu_get_type (void) (GtkClassInitFunc) gtk_menu_class_init, (GtkObjectInitFunc) gtk_menu_init, (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL, + (GtkArgGetFunc) NULL, }; - + menu_type = gtk_type_unique (gtk_menu_shell_get_type (), &menu_info); } - + return menu_type; } @@ -96,15 +96,15 @@ gtk_menu_class_init (GtkMenuClass *class) GtkWidgetClass *widget_class; GtkContainerClass *container_class; GtkMenuShellClass *menu_shell_class; - + object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; menu_shell_class = (GtkMenuShellClass*) class; parent_class = gtk_type_class (gtk_menu_shell_get_type ()); - + object_class->destroy = gtk_menu_destroy; - + widget_class->show = gtk_menu_show; widget_class->map = gtk_menu_map; widget_class->unmap = gtk_menu_unmap; @@ -119,7 +119,7 @@ gtk_menu_class_init (GtkMenuClass *class) widget_class->hide_all = gtk_menu_hide_all; container_class->need_resize = gtk_menu_need_resize; - + menu_shell_class->submenu_placement = GTK_LEFT_RIGHT; menu_shell_class->deactivate = gtk_menu_deactivate; } @@ -128,55 +128,55 @@ static void gtk_menu_init (GtkMenu *menu) { GTK_WIDGET_SET_FLAGS (menu, GTK_TOPLEVEL); - + menu->parent_menu_item = NULL; menu->old_active_menu_item = NULL; - menu->accelerator_table = NULL; + menu->accel_group = NULL; menu->position_func = NULL; menu->position_func_data = NULL; - - GTK_MENU_SHELL (menu)->menu_flag = TRUE; + + MENU_NEEDS_RESIZE (menu) = TRUE; } static void -gtk_menu_destroy (GtkObject *object) +gtk_menu_destroy (GtkObject *object) { GtkMenuAttachData *data; - + g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_MENU (object)); - + gtk_widget_ref (GTK_WIDGET (object)); - + data = gtk_object_get_data (object, attach_data_key); if (data) gtk_menu_detach (GTK_MENU (object)); - - gtk_menu_set_accelerator_table (GTK_MENU (object), NULL); - + + gtk_menu_set_accel_group (GTK_MENU (object), NULL); + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); - + gtk_widget_unref (GTK_WIDGET (object)); } void -gtk_menu_attach_to_widget (GtkMenu *menu, - GtkWidget *attach_widget, - GtkMenuDetachFunc detacher) +gtk_menu_attach_to_widget (GtkMenu *menu, + GtkWidget *attach_widget, + GtkMenuDetachFunc detacher) { GtkMenuAttachData *data; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); g_return_if_fail (attach_widget != NULL); g_return_if_fail (GTK_IS_WIDGET (attach_widget)); g_return_if_fail (detacher != NULL); - + /* keep this function in sync with gtk_widget_set_parent() */ - + data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); if (data) { @@ -184,31 +184,31 @@ gtk_menu_attach_to_widget (GtkMenu *menu, gtk_type_name (GTK_OBJECT_TYPE (data->attach_widget))); return; } - + gtk_widget_ref (GTK_WIDGET (menu)); gtk_object_sink (GTK_OBJECT (menu)); - + data = g_new (GtkMenuAttachData, 1); data->attach_widget = attach_widget; data->detacher = detacher; gtk_object_set_data (GTK_OBJECT (menu), attach_data_key, data); - + if (GTK_WIDGET_STATE (menu) != GTK_STATE_NORMAL) gtk_widget_set_state (GTK_WIDGET (menu), GTK_STATE_NORMAL); - + /* we don't need to set the style here, since * we are a toplevel widget. */ } GtkWidget* -gtk_menu_get_attach_widget (GtkMenu *menu) +gtk_menu_get_attach_widget (GtkMenu *menu) { GtkMenuAttachData *data; - + g_return_val_if_fail (menu != NULL, NULL); g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - + data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); if (data) return data->attach_widget; @@ -216,13 +216,13 @@ gtk_menu_get_attach_widget (GtkMenu *menu) } void -gtk_menu_detach (GtkMenu *menu) +gtk_menu_detach (GtkMenu *menu) { GtkMenuAttachData *data; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + /* keep this function in sync with gtk_widget_unparent() */ data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); @@ -232,14 +232,14 @@ gtk_menu_detach (GtkMenu *menu) return; } gtk_object_remove_data (GTK_OBJECT (menu), attach_data_key); - + data->detacher (data->attach_widget, menu); - + if (GTK_WIDGET_REALIZED (menu)) gtk_widget_unrealize (GTK_WIDGET (menu)); - + g_free (data); - + gtk_widget_unref (GTK_WIDGET (menu)); } @@ -266,37 +266,37 @@ gtk_menu_prepend (GtkMenu *menu, void gtk_menu_insert (GtkMenu *menu, GtkWidget *child, - gint position) + gint position) { gtk_menu_shell_insert (GTK_MENU_SHELL (menu), child, position); } void -gtk_menu_popup (GtkMenu *menu, - GtkWidget *parent_menu_shell, - GtkWidget *parent_menu_item, +gtk_menu_popup (GtkMenu *menu, + GtkWidget *parent_menu_shell, + GtkWidget *parent_menu_item, GtkMenuPositionFunc func, - gpointer data, - guint button, - guint32 activate_time) + gpointer data, + guint button, + guint32 activate_time) { GtkWidget *xgrab_shell; GtkWidget *parent; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + GTK_MENU_SHELL (menu)->parent_menu_shell = parent_menu_shell; GTK_MENU_SHELL (menu)->active = TRUE; GTK_MENU_SHELL (menu)->button = button; - + menu->parent_menu_item = parent_menu_item; menu->position_func = func; menu->position_func_data = data; GTK_MENU_SHELL (menu)->activate_time = activate_time; - + gtk_widget_show (GTK_WIDGET (menu)); - + /* Find the last viewable ancestor, and make an X grab on it */ parent = GTK_WIDGET (menu); @@ -315,13 +315,13 @@ gtk_menu_popup (GtkMenu *menu, } tmp = tmp->parent; } - + if (viewable) xgrab_shell = parent; - + parent = GTK_MENU_SHELL (parent)->parent_menu_shell; } - + if (xgrab_shell && (!GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) { GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); @@ -333,7 +333,7 @@ gtk_menu_popup (GtkMenu *menu, NULL, cursor, activate_time) == 0); gdk_cursor_destroy (cursor); } - + gtk_grab_add (GTK_WIDGET (menu)); } @@ -341,27 +341,27 @@ void gtk_menu_popdown (GtkMenu *menu) { GtkMenuShell *menu_shell; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + menu_shell = GTK_MENU_SHELL (menu); - + menu_shell->parent_menu_shell = NULL; menu_shell->active = FALSE; - + if (menu_shell->active_menu_item) { menu->old_active_menu_item = menu_shell->active_menu_item; gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item)); menu_shell->active_menu_item = NULL; } - + /* The X Grab, if present, will automatically be removed when we hide * the window */ gtk_widget_hide (GTK_WIDGET (menu)); menu_shell->have_xgrab = FALSE; - + gtk_grab_remove (GTK_WIDGET (menu)); } @@ -370,28 +370,28 @@ gtk_menu_get_active (GtkMenu *menu) { GtkWidget *child; GList *children; - + g_return_val_if_fail (menu != NULL, NULL); g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - + if (!menu->old_active_menu_item) { child = NULL; children = GTK_MENU_SHELL (menu)->children; - + while (children) { child = children->data; children = children->next; - + if (GTK_BIN (child)->child) break; child = NULL; } - + menu->old_active_menu_item = child; } - + return menu->old_active_menu_item; } @@ -401,10 +401,10 @@ gtk_menu_set_active (GtkMenu *menu, { GtkWidget *child; GList *tmp_list; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + tmp_list = g_list_nth (GTK_MENU_SHELL (menu)->children, index); if (tmp_list) { @@ -415,19 +415,19 @@ gtk_menu_set_active (GtkMenu *menu, } void -gtk_menu_set_accelerator_table (GtkMenu *menu, - GtkAcceleratorTable *table) +gtk_menu_set_accel_group (GtkMenu *menu, + GtkAccelGroup *accel_group) { g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - - if (menu->accelerator_table != table) + + if (menu->accel_group != accel_group) { - if (menu->accelerator_table) - gtk_accelerator_table_unref (menu->accelerator_table); - menu->accelerator_table = table; - if (menu->accelerator_table) - gtk_accelerator_table_ref (menu->accelerator_table); + if (menu->accel_group) + gtk_accel_group_unref (menu->accel_group); + menu->accel_group = accel_group; + if (menu->accel_group) + gtk_accel_group_ref (menu->accel_group); } } @@ -437,11 +437,56 @@ gtk_menu_show (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE); + if (MENU_NEEDS_RESIZE (widget)) + gtk_container_need_resize (GTK_CONTAINER (widget)); gtk_widget_map (widget); } +void +gtk_menu_reposition (GtkMenu *menu) +{ + GtkWidget *widget; + + g_return_if_fail (menu != NULL); + g_return_if_fail (GTK_IS_MENU (menu)); + + widget = GTK_WIDGET (menu); + + if (GTK_WIDGET_DRAWABLE (menu)) + { + gint x, y; + + gdk_window_get_pointer (NULL, &x, &y, NULL); + + if (menu->position_func) + (* menu->position_func) (menu, &x, &y, menu->position_func_data); + else + { + gint screen_width; + gint screen_height; + + screen_width = gdk_screen_width (); + screen_height = gdk_screen_height (); + + x -= 2; + y -= 2; + + if ((x + widget->requisition.width) > screen_width) + x -= ((x + widget->requisition.width) - screen_width); + if (x < 0) + x = 0; + if ((y + widget->requisition.height) > screen_height) + y -= ((y + widget->requisition.height) - screen_height); + if (y < 0) + y = 0; + } + + gdk_window_move (widget->window, x, y); + } +} + static void gtk_menu_map (GtkWidget *widget) { @@ -449,69 +494,26 @@ gtk_menu_map (GtkWidget *widget) GtkMenuShell *menu_shell; GtkWidget *child; GList *children; - GtkAllocation allocation; - gint x, y; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); GTK_WIDGET_SET_FLAGS (menu_shell, GTK_MAPPED); - gtk_widget_size_request (widget, &widget->requisition); - - if (menu_shell->menu_flag) - { - menu_shell->menu_flag = FALSE; - - allocation.x = widget->allocation.x; - allocation.y = widget->allocation.y; - allocation.width = widget->requisition.width; - allocation.height = widget->requisition.height; - - gtk_widget_size_allocate (widget, &allocation); - } - - gdk_window_get_pointer (NULL, &x, &y, NULL); - - if (menu->position_func) - (* menu->position_func) (menu, &x, &y, menu->position_func_data); - else - { - gint screen_width; - gint screen_height; - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - x -= 2; - y -= 2; - - if ((x + widget->requisition.width) > screen_width) - x -= ((x + widget->requisition.width) - screen_width); - if (x < 0) - x = 0; - if ((y + widget->requisition.height) > screen_height) - y -= ((y + widget->requisition.height) - screen_height); - if (y < 0) - y = 0; - } - - gdk_window_move_resize (widget->window, x, y, - widget->requisition.width, - widget->requisition.height); - + gtk_menu_reposition (menu); + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child)) - gtk_widget_map (child); + gtk_widget_map (child); } - + gdk_window_show (widget->window); } @@ -520,7 +522,7 @@ gtk_menu_unmap (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); gdk_window_hide (widget->window); } @@ -530,12 +532,12 @@ gtk_menu_realize (GtkWidget *widget) { GdkWindowAttr attributes; gint attributes_mask; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - + attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; @@ -548,11 +550,11 @@ gtk_menu_realize (GtkWidget *widget) attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK); - + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (NULL, &attributes, attributes_mask); gdk_window_set_user_data (widget->window, widget); - + widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); } @@ -565,54 +567,50 @@ gtk_menu_size_request (GtkWidget *widget, GtkMenuShell *menu_shell; GtkWidget *child; GList *children; - gint max_accelerator_size; gint max_toggle_size; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (requisition != NULL); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); - + requisition->width = 0; requisition->height = 0; - - max_accelerator_size = 0; + max_toggle_size = 0; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child)) { GTK_MENU_ITEM (child)->show_submenu_indicator = TRUE; gtk_widget_size_request (child, &child->requisition); - + requisition->width = MAX (requisition->width, child->requisition.width); requisition->height += child->requisition.height; - - max_accelerator_size = MAX (max_accelerator_size, GTK_MENU_ITEM (child)->accelerator_size); + max_toggle_size = MAX (max_toggle_size, MENU_ITEM_CLASS (child)->toggle_size); } } - - requisition->width += max_toggle_size + max_accelerator_size; + + requisition->width += max_toggle_size; requisition->width += (GTK_CONTAINER (menu)->border_width + widget->style->klass->xthickness) * 2; requisition->height += (GTK_CONTAINER (menu)->border_width + widget->style->klass->ythickness) * 2; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - - GTK_MENU_ITEM (child)->accelerator_size = max_accelerator_size; + GTK_MENU_ITEM (child)->toggle_size = max_toggle_size; } } @@ -626,14 +624,14 @@ gtk_menu_size_allocate (GtkWidget *widget, GtkWidget *child; GtkAllocation child_allocation; GList *children; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (allocation != NULL); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); - + widget->allocation = *allocation; if (menu_shell->children) @@ -643,23 +641,31 @@ gtk_menu_size_allocate (GtkWidget *widget, child_allocation.y = (GTK_CONTAINER (menu)->border_width + widget->style->klass->ythickness); child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child)) { child_allocation.height = child->requisition.height; - + gtk_widget_size_allocate (child, &child_allocation); - + gtk_widget_queue_draw (child); + child_allocation.y += child_allocation.height; } } } + + if (GTK_WIDGET_REALIZED (widget)) + { + gdk_window_resize (widget->window, + widget->requisition.width, + widget->requisition.height); + } } static void @@ -667,7 +673,7 @@ gtk_menu_paint (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_draw_shadow (widget->style, @@ -688,23 +694,23 @@ gtk_menu_draw (GtkWidget *widget, GtkWidget *child; GdkRectangle child_area; GList *children; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (area != NULL); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_menu_paint (widget); - + menu_shell = GTK_MENU_SHELL (widget); - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (gtk_widget_intersect (child, area, &child_area)) gtk_widget_draw (child, &child_area); } @@ -712,154 +718,122 @@ gtk_menu_draw (GtkWidget *widget, } static gint -gtk_menu_expose (GtkWidget *widget, +gtk_menu_expose (GtkWidget *widget, GdkEventExpose *event) { GtkMenuShell *menu_shell; GtkWidget *child; GdkEventExpose child_event; GList *children; - + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_menu_paint (widget); - + menu_shell = GTK_MENU_SHELL (widget); child_event = *event; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_NO_WINDOW (child) && gtk_widget_intersect (child, &event->area, &child_event.area)) gtk_widget_event (child, (GdkEvent*) &child_event); } } - + return FALSE; } static gint -gtk_menu_configure (GtkWidget *widget, +gtk_menu_configure (GtkWidget *widget, GdkEventConfigure *event) { GtkAllocation allocation; - + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + /* If the window was merely moved, do nothing */ if ((widget->allocation.width == event->width) && (widget->allocation.height == event->height)) return FALSE; - - if (GTK_MENU_SHELL (widget)->menu_flag) + + if (MENU_NEEDS_RESIZE (widget)) { - GTK_MENU_SHELL (widget)->menu_flag = FALSE; - + MENU_NEEDS_RESIZE (widget) = FALSE; + allocation.x = 0; allocation.y = 0; allocation.width = event->width; allocation.height = event->height; - + gtk_widget_size_allocate (widget, &allocation); } - + return FALSE; } static gint -gtk_menu_key_press (GtkWidget *widget, +gtk_menu_key_press (GtkWidget *widget, GdkEventKey *event) { - GtkAllocation allocation; - GtkAcceleratorTable *table; - gchar *signame; - int delete; - + gboolean delete; + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - - delete = ((event->keyval == GDK_Delete) || - (event->keyval == GDK_BackSpace)); - - if (delete || ((event->keyval >= 0x20) && (event->keyval <= 0xFF))) + + delete = (event->keyval == GDK_Delete || + event->keyval == GDK_KP_Delete || + event->keyval == GDK_BackSpace); + + if (delete || gtk_accelerator_valid (event->keyval, event->keyval)) { GtkMenuShell *menu_shell; - + menu_shell = GTK_MENU_SHELL (widget); - - if (menu_shell->active_menu_item && GTK_BIN (menu_shell->active_menu_item)->child) + + if (menu_shell->active_menu_item && + GTK_BIN (menu_shell->active_menu_item)->child && + GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) { GtkMenuItem *menu_item; - + GtkAccelGroup *accel_group; + menu_item = GTK_MENU_ITEM (menu_shell->active_menu_item); - /* block resizes */ - gtk_container_block_resize (GTK_CONTAINER (widget)); - - table = NULL; - /* if the menu item currently has an accelerator then we'll - * remove it before we do anything else. - */ - if (menu_item->accelerator_signal) - { - signame = gtk_signal_name (menu_item->accelerator_signal); - table = gtk_accelerator_table_find (GTK_OBJECT (widget), - signame, - menu_item->accelerator_key, - menu_item->accelerator_mods); - if (!table) - table = GTK_MENU (widget)->accelerator_table; - gtk_widget_remove_accelerator (GTK_WIDGET (menu_item), - table, signame); - } - - if (!table) - table = GTK_MENU (widget)->accelerator_table; - - /* if we aren't simply deleting the accelerator, then we'll install - * the new one now. - */ - if (!delete) - gtk_widget_install_accelerator (GTK_WIDGET (menu_item), - table, "activate", - toupper (event->keyval), - event->state); - - /* check and see if the menu has changed size. */ - gtk_widget_size_request (widget, &widget->requisition); - - allocation.x = widget->allocation.x; - allocation.y = widget->allocation.y; - allocation.width = widget->requisition.width; - allocation.height = widget->requisition.height; - - if ((allocation.width == widget->allocation.width) && - (allocation.height == widget->allocation.height)) - { - gtk_widget_queue_draw (widget); - } + if (!GTK_MENU (widget)->accel_group) + accel_group = gtk_accel_group_get_default (); else - { - gtk_widget_size_allocate (GTK_WIDGET (widget), &allocation); - gtk_menu_map (widget); - } + accel_group = GTK_MENU (widget)->accel_group; - /* unblock resizes */ - gtk_container_unblock_resize (GTK_CONTAINER (widget)); + gtk_widget_remove_accelerators (GTK_WIDGET (menu_item), + gtk_signal_name (menu_item->accelerator_signal), + TRUE); + + if (!delete && + gtk_widget_accelerator_signal (GTK_WIDGET (menu_item), + accel_group, + event->keyval, + event->state) == 0) + gtk_widget_add_accelerator (GTK_WIDGET (menu_item), + gtk_signal_name (menu_item->accelerator_signal), + accel_group, + event->keyval, + event->state, + GTK_ACCEL_VISIBLE); } } - + return FALSE; } @@ -867,29 +841,29 @@ static gint gtk_menu_need_resize (GtkContainer *container) { GtkAllocation allocation; - + GtkWidget *widget; + g_return_val_if_fail (container != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (container), FALSE); + widget = GTK_WIDGET (container); + if (GTK_WIDGET_VISIBLE (container)) { - GTK_MENU_SHELL (container)->menu_flag = FALSE; - - gtk_widget_size_request (GTK_WIDGET (container), - >K_WIDGET (container)->requisition); - - allocation.x = GTK_WIDGET (container)->allocation.x; - allocation.y = GTK_WIDGET (container)->allocation.y; - allocation.width = GTK_WIDGET (container)->requisition.width; - allocation.height = GTK_WIDGET (container)->requisition.height; - - gtk_widget_size_allocate (GTK_WIDGET (container), &allocation); + MENU_NEEDS_RESIZE (container) = FALSE; + + gtk_widget_size_request (widget, &widget->requisition); + + allocation.x = widget->allocation.x; + allocation.y = widget->allocation.y; + allocation.width = widget->requisition.width; + allocation.height = widget->requisition.height; + + gtk_widget_size_allocate (widget, &allocation); } else - { - GTK_MENU_SHELL (container)->menu_flag = TRUE; - } - + MENU_NEEDS_RESIZE (container) = TRUE; + return FALSE; } @@ -897,15 +871,15 @@ static void gtk_menu_deactivate (GtkMenuShell *menu_shell) { GtkWidget *parent; - + g_return_if_fail (menu_shell != NULL); g_return_if_fail (GTK_IS_MENU (menu_shell)); - + parent = menu_shell->parent_menu_shell; menu_shell->activate_time = 0; gtk_menu_popdown (GTK_MENU (menu_shell)); - + if (parent) gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent)); } @@ -915,11 +889,11 @@ static void gtk_menu_show_all (GtkWidget *widget) { GtkContainer *container; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); container = GTK_CONTAINER (widget); - + /* Show children, but not self. */ gtk_container_foreach (container, (GtkCallback) gtk_widget_show_all, NULL); } @@ -929,12 +903,11 @@ static void gtk_menu_hide_all (GtkWidget *widget) { GtkContainer *container; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); container = GTK_CONTAINER (widget); - + /* Hide children, but not self. */ gtk_container_foreach (container, (GtkCallback) gtk_widget_hide_all, NULL); } - diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h index 23a8a6c009..ac47f54baf 100644 --- a/gtk/gtkmenu.h +++ b/gtk/gtkmenu.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -21,40 +21,41 @@ #include <gdk/gdk.h> -#include <gtk/gtkaccelerator.h> +#include <gtk/gtkaccelgroup.h> #include <gtk/gtkmenushell.h> #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -#define GTK_MENU(obj) GTK_CHECK_CAST (obj, gtk_menu_get_type (), GtkMenu) -#define GTK_MENU_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_menu_get_type (), GtkMenuClass) -#define GTK_IS_MENU(obj) GTK_CHECK_TYPE (obj, gtk_menu_get_type ()) +#define GTK_TYPE_MENU (gtk_menu_get_type ()) +#define GTK_MENU(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_MENU, GtkMenu)) +#define GTK_MENU_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU, GtkMenuClass)) +#define GTK_IS_MENU(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_MENU)) +#define GTK_IS_MENU_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU)) -typedef struct _GtkMenu GtkMenu; +typedef struct _GtkMenu GtkMenu; typedef struct _GtkMenuClass GtkMenuClass; typedef void (*GtkMenuPositionFunc) (GtkMenu *menu, gint *x, gint *y, - gpointer user_data); + gpointer user_data); typedef void (*GtkMenuDetachFunc) (GtkWidget *attach_widget, GtkMenu *menu); struct _GtkMenu { GtkMenuShell menu_shell; - - GList *children; - + GtkWidget *parent_menu_item; GtkWidget *old_active_menu_item; - - GtkAcceleratorTable *accelerator_table; + + GtkAccelGroup *accel_group; GtkMenuPositionFunc position_func; gpointer position_func_data; }; @@ -65,28 +66,29 @@ struct _GtkMenuClass }; -guint gtk_menu_get_type (void); -GtkWidget* gtk_menu_new (void); -void gtk_menu_append (GtkMenu *menu, - GtkWidget *child); -void gtk_menu_prepend (GtkMenu *menu, - GtkWidget *child); -void gtk_menu_insert (GtkMenu *menu, - GtkWidget *child, - gint position); -void gtk_menu_popup (GtkMenu *menu, - GtkWidget *parent_menu_shell, - GtkWidget *parent_menu_item, - GtkMenuPositionFunc func, - gpointer data, - guint button, - guint32 activate_time); -void gtk_menu_popdown (GtkMenu *menu); -GtkWidget* gtk_menu_get_active (GtkMenu *menu); -void gtk_menu_set_active (GtkMenu *menu, - guint index); -void gtk_menu_set_accelerator_table (GtkMenu *menu, - GtkAcceleratorTable *table); +GtkType gtk_menu_get_type (void); +GtkWidget* gtk_menu_new (void); +void gtk_menu_append (GtkMenu *menu, + GtkWidget *child); +void gtk_menu_prepend (GtkMenu *menu, + GtkWidget *child); +void gtk_menu_insert (GtkMenu *menu, + GtkWidget *child, + gint position); +void gtk_menu_popup (GtkMenu *menu, + GtkWidget *parent_menu_shell, + GtkWidget *parent_menu_item, + GtkMenuPositionFunc func, + gpointer data, + guint button, + guint32 activate_time); +void gtk_menu_reposition (GtkMenu *menu); +void gtk_menu_popdown (GtkMenu *menu); +GtkWidget* gtk_menu_get_active (GtkMenu *menu); +void gtk_menu_set_active (GtkMenu *menu, + guint index); +void gtk_menu_set_accel_group (GtkMenu *menu, + GtkAccelGroup *accel_group); void gtk_menu_attach_to_widget (GtkMenu *menu, GtkWidget *attach_widget, GtkMenuDetachFunc detacher); diff --git a/gtk/gtkmenufactory.c b/gtk/gtkmenufactory.c index 2ed91d3d69..3e610b07ed 100644 --- a/gtk/gtkmenufactory.c +++ b/gtk/gtkmenufactory.c @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -29,41 +29,38 @@ enum { CREATE = 1 << 0, DESTROY = 1 << 1, - CHECK = 1 << 2 + CHECK = 1 << 2 }; -static void gtk_menu_factory_create (GtkMenuFactory *factory, +static void gtk_menu_factory_create (GtkMenuFactory *factory, GtkMenuEntry *entry, GtkWidget *parent, - const char *path); -static void gtk_menu_factory_remove (GtkMenuFactory *factory, + const gchar *path); +static void gtk_menu_factory_remove (GtkMenuFactory *factory, GtkWidget *parent, - const char *path); + const gchar *path); static GtkWidget* gtk_menu_factory_make_widget (GtkMenuFactory *factory); -static GtkMenuPath* gtk_menu_factory_get (GtkWidget *parent, - const char *path, - int flags); +static GtkMenuPath* gtk_menu_factory_get (GtkWidget *parent, + const gchar *path, + gint flags); static GtkMenuPath* gtk_menu_factory_find_recurse (GtkMenuFactory *factory, GtkWidget *parent, - const char *path); -static void gtk_menu_factory_parse_accelerator (const char *accelerator, - char *accelerator_key, - guint8 *accelerator_mods); + const gchar *path); GtkMenuFactory* gtk_menu_factory_new (GtkMenuFactoryType type) { GtkMenuFactory *factory; - + factory = g_new (GtkMenuFactory, 1); factory->path = NULL; factory->type = type; - factory->table = NULL; + factory->accel_group = NULL; factory->widget = NULL; factory->subfactories = NULL; - + return factory; } @@ -72,25 +69,25 @@ gtk_menu_factory_destroy (GtkMenuFactory *factory) { GtkMenuFactory *subfactory; GList *tmp_list; - + g_return_if_fail (factory != NULL); - + if (factory->path) g_free (factory->path); - + tmp_list = factory->subfactories; while (tmp_list) { subfactory = tmp_list->data; tmp_list = tmp_list->next; - + gtk_menu_factory_destroy (subfactory); } - - if (factory->table) + + if (factory->accel_group) { - gtk_accelerator_table_unref (factory->table); - factory->table = NULL; + gtk_accel_group_unref (factory->accel_group); + factory->accel_group = NULL; } if (factory->widget) @@ -100,21 +97,21 @@ gtk_menu_factory_destroy (GtkMenuFactory *factory) void gtk_menu_factory_add_entries (GtkMenuFactory *factory, GtkMenuEntry *entries, - int nentries) + int nentries) { int i; - + g_return_if_fail (factory != NULL); g_return_if_fail (entries != NULL); g_return_if_fail (nentries > 0); - + if (!factory->widget) { factory->widget = gtk_menu_factory_make_widget (factory); gtk_widget_ref (factory->widget); gtk_object_sink (GTK_OBJECT (factory->widget)); } - + for (i = 0; i < nentries; i++) gtk_menu_factory_create (factory, &entries[i], factory->widget, entries[i].path); } @@ -122,30 +119,30 @@ gtk_menu_factory_add_entries (GtkMenuFactory *factory, void gtk_menu_factory_add_subfactory (GtkMenuFactory *factory, GtkMenuFactory *subfactory, - const char *path) + const char *path) { g_return_if_fail (factory != NULL); g_return_if_fail (subfactory != NULL); g_return_if_fail (path != NULL); - + if (subfactory->path) g_free (subfactory->path); subfactory->path = g_strdup (path); - + factory->subfactories = g_list_append (factory->subfactories, subfactory); } void gtk_menu_factory_remove_paths (GtkMenuFactory *factory, - char **paths, - int npaths) + char **paths, + int npaths) { int i; - + g_return_if_fail (factory != NULL); g_return_if_fail (paths != NULL); g_return_if_fail (npaths > 0); - + if (factory->widget) { for (i = 0; i < npaths; i++) @@ -155,15 +152,15 @@ gtk_menu_factory_remove_paths (GtkMenuFactory *factory, void gtk_menu_factory_remove_entries (GtkMenuFactory *factory, - GtkMenuEntry *entries, - int nentries) + GtkMenuEntry *entries, + int nentries) { int i; - + g_return_if_fail (factory != NULL); g_return_if_fail (entries != NULL); g_return_if_fail (nentries > 0); - + if (factory->widget) { for (i = 0; i < nentries; i++) @@ -174,12 +171,12 @@ gtk_menu_factory_remove_entries (GtkMenuFactory *factory, void gtk_menu_factory_remove_subfactory (GtkMenuFactory *factory, GtkMenuFactory *subfactory, - const char *path) + const char *path) { g_return_if_fail (factory != NULL); g_return_if_fail (subfactory != NULL); g_return_if_fail (path != NULL); - + g_warning ("FIXME: gtk_menu_factory_remove_subfactory"); } @@ -189,29 +186,29 @@ gtk_menu_factory_find (GtkMenuFactory *factory, { g_return_val_if_fail (factory != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - + return gtk_menu_factory_find_recurse (factory, factory->widget, path); } static void gtk_menu_factory_create (GtkMenuFactory *factory, - GtkMenuEntry *entry, - GtkWidget *parent, - const char *path) + GtkMenuEntry *entry, + GtkWidget *parent, + const char *path) { GtkMenuFactory *subfactory; GtkMenuPath *menu_path; GtkWidget *menu; GList *tmp_list; char tmp_path[256]; - char accelerator_key; - guint8 accelerator_mods; - char *p; - + guint accelerator_key; + guint accelerator_mods; + gchar *p; + g_return_if_fail (factory != NULL); g_return_if_fail (entry != NULL); - + /* If 'path' is empty, then simply return. */ if (!path || path[0] == '\0') @@ -223,11 +220,11 @@ gtk_menu_factory_create (GtkMenuFactory *factory, g_warning ("gtk_menu_factory_create(): argument `path' exceeds maximum size."); return; } - + /* Strip off the next part of the path. */ p = strchr (path, '/'); - + /* If this is the last part of the path ('p' is * NULL), then we create an item. */ @@ -248,25 +245,26 @@ gtk_menu_factory_create (GtkMenuFactory *factory, else menu_path = gtk_menu_factory_get (parent, path, CREATE); entry->widget = menu_path->widget; - + if (strcmp (path, "<nothing>") == 0) gtk_widget_hide (entry->widget); - + if (entry->accelerator) { - gtk_menu_factory_parse_accelerator (entry->accelerator, - &accelerator_key, - &accelerator_mods); - if (!factory->table) - factory->table = gtk_accelerator_table_new (); + gtk_accelerator_parse (entry->accelerator, + &accelerator_key, + &accelerator_mods); + if (!factory->accel_group) + factory->accel_group = gtk_accel_group_new (); - gtk_widget_install_accelerator (menu_path->widget, - factory->table, - "activate", - accelerator_key, - accelerator_mods); + gtk_widget_add_accelerator (menu_path->widget, + "activate", + factory->accel_group, + accelerator_key, + accelerator_mods, + GTK_ACCEL_VISIBLE); } - + if (entry->callback) gtk_signal_connect (GTK_OBJECT (menu_path->widget), "activate", (GtkSignalFunc) entry->callback, @@ -277,7 +275,7 @@ gtk_menu_factory_create (GtkMenuFactory *factory, { strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path)); tmp_path[(long) p - (long) path] = '\0'; - + menu_path = gtk_menu_factory_get (parent, tmp_path, 0); if (!menu_path) { @@ -286,7 +284,7 @@ gtk_menu_factory_create (GtkMenuFactory *factory, { subfactory = tmp_list->data; tmp_list = tmp_list->next; - + if (subfactory->path && (strcmp (subfactory->path, tmp_path) == 0)) { @@ -296,36 +294,36 @@ gtk_menu_factory_create (GtkMenuFactory *factory, gtk_widget_ref (subfactory->widget); gtk_object_sink (GTK_OBJECT (subfactory->widget)); } - + gtk_menu_factory_create (subfactory, entry, subfactory->widget, p + 1); return; } } - + menu_path = gtk_menu_factory_get (parent, tmp_path, CREATE); } - + entry->widget = menu_path->widget; menu = GTK_MENU_ITEM (menu_path->widget)->submenu; - + if (!menu) { menu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_path->widget), menu); - - if (!factory->table) - factory->table = gtk_accelerator_table_new (); - gtk_menu_set_accelerator_table (GTK_MENU (menu), factory->table); + + if (!factory->accel_group) + factory->accel_group = gtk_accel_group_new (); + gtk_menu_set_accel_group (GTK_MENU (menu), factory->accel_group); } - + gtk_menu_factory_create (factory, entry, menu, p + 1); } } static void gtk_menu_factory_remove (GtkMenuFactory *factory, - GtkWidget *parent, - const char *path) + GtkWidget *parent, + const char *path) { GtkMenuFactory *subfactory; GtkMenuPath *menu_path; @@ -333,7 +331,7 @@ gtk_menu_factory_remove (GtkMenuFactory *factory, GList *tmp_list; char tmp_path[256]; char *p; - + if (!path || path[0] == '\0') return; else if (strlen (path) >= 250) @@ -345,7 +343,7 @@ gtk_menu_factory_remove (GtkMenuFactory *factory, } p = strchr (path, '/'); - + if (!p) { if (parent) @@ -355,7 +353,7 @@ gtk_menu_factory_remove (GtkMenuFactory *factory, { strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path)); tmp_path[(long) p - (long) path] = '\0'; - + menu_path = gtk_menu_factory_get (parent, tmp_path, 0); if (!menu_path) { @@ -364,7 +362,7 @@ gtk_menu_factory_remove (GtkMenuFactory *factory, { subfactory = tmp_list->data; tmp_list = tmp_list->next; - + if (subfactory->path && (strcmp (subfactory->path, tmp_path) == 0)) { @@ -387,17 +385,17 @@ static GtkWidget* gtk_menu_factory_make_widget (GtkMenuFactory *factory) { GtkWidget *widget; - + g_return_val_if_fail (factory != NULL, NULL); - + switch (factory->type) { case GTK_MENU_FACTORY_MENU: widget = gtk_menu_new (); - - if (!factory->table) - factory->table = gtk_accelerator_table_new (); - gtk_menu_set_accelerator_table (GTK_MENU (widget), factory->table); + + if (!factory->accel_group) + factory->accel_group = gtk_accel_group_new (); + gtk_menu_set_accel_group (GTK_MENU (widget), factory->accel_group); return widget; case GTK_MENU_FACTORY_MENU_BAR: return gtk_menu_bar_new (); @@ -405,24 +403,24 @@ gtk_menu_factory_make_widget (GtkMenuFactory *factory) g_error ("not implemented"); break; } - + return NULL; } static GtkMenuPath* gtk_menu_factory_get (GtkWidget *parent, const char *path, - int flags) + int flags) { GtkMenuPath *menu_path; GList *tmp_list; - + tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent)); while (tmp_list) { menu_path = tmp_list->data; tmp_list = tmp_list->next; - + if (strcmp (menu_path->path, path) == 0) { if (flags & DESTROY) @@ -430,11 +428,11 @@ gtk_menu_factory_get (GtkWidget *parent, tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent)); tmp_list = g_list_remove (tmp_list, menu_path); gtk_object_set_user_data (GTK_OBJECT (parent), tmp_list); - + gtk_widget_destroy (menu_path->widget); g_free (menu_path->path); g_free (menu_path); - + return NULL; } else @@ -443,28 +441,28 @@ gtk_menu_factory_get (GtkWidget *parent, } } } - + if (flags & CREATE) { menu_path = g_new (GtkMenuPath, 1); menu_path->path = g_strdup (path); - + if (flags & CHECK) menu_path->widget = gtk_check_menu_item_new_with_label (path); else menu_path->widget = gtk_menu_item_new_with_label (path); - + gtk_container_add (GTK_CONTAINER (parent), menu_path->widget); gtk_object_set_user_data (GTK_OBJECT (menu_path->widget), NULL); gtk_widget_show (menu_path->widget); - + tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent)); tmp_list = g_list_prepend (tmp_list, menu_path); gtk_object_set_user_data (GTK_OBJECT (parent), tmp_list); - + return menu_path; } - + return NULL; } @@ -479,7 +477,7 @@ gtk_menu_factory_find_recurse (GtkMenuFactory *factory, GList *tmp_list; char tmp_path[256]; char *p; - + if (!path || path[0] == '\0') return NULL; else if (strlen (path) >= 250) @@ -491,7 +489,7 @@ gtk_menu_factory_find_recurse (GtkMenuFactory *factory, } p = strchr (path, '/'); - + if (!p) { if (parent) @@ -501,7 +499,7 @@ gtk_menu_factory_find_recurse (GtkMenuFactory *factory, { strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path)); tmp_path[(long) p - (long) path] = '\0'; - + menu_path = gtk_menu_factory_get (parent, tmp_path, 0); if (!menu_path) { @@ -510,7 +508,7 @@ gtk_menu_factory_find_recurse (GtkMenuFactory *factory, { subfactory = tmp_list->data; tmp_list = tmp_list->next; - + if (subfactory->path && (strcmp (subfactory->path, tmp_path) == 0)) { @@ -519,54 +517,14 @@ gtk_menu_factory_find_recurse (GtkMenuFactory *factory, return gtk_menu_factory_find_recurse (subfactory, subfactory->widget, p + 1); } } - + return NULL; } - + menu = GTK_MENU_ITEM (menu_path->widget)->submenu; if (menu) return gtk_menu_factory_find_recurse (factory, menu, p + 1); } - + return NULL; } - -static void -gtk_menu_factory_parse_accelerator (const char *accelerator, - char *accelerator_key, - guint8 *accelerator_mods) -{ - int done; - - g_return_if_fail (accelerator != NULL); - g_return_if_fail (accelerator_key != NULL); - g_return_if_fail (accelerator_mods != NULL); - - *accelerator_key = 0; - *accelerator_mods = 0; - - done = FALSE; - while (!done) - { - if (strncmp (accelerator, "<shift>", 7) == 0) - { - accelerator += 7; - *accelerator_mods |= GDK_SHIFT_MASK; - } - else if (strncmp (accelerator, "<alt>", 5) == 0) - { - accelerator += 5; - *accelerator_mods |= GDK_MOD1_MASK; - } - else if (strncmp (accelerator, "<control>", 9) == 0) - { - accelerator += 9; - *accelerator_mods |= GDK_CONTROL_MASK; - } - else - { - done = TRUE; - *accelerator_key = accelerator[0]; - } - } -} diff --git a/gtk/gtkmenufactory.h b/gtk/gtkmenufactory.h index 0b5de8ed61..d040fe6f97 100644 --- a/gtk/gtkmenufactory.h +++ b/gtk/gtkmenufactory.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -25,20 +25,21 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -typedef struct _GtkMenuEntry GtkMenuEntry; -typedef struct _GtkMenuPath GtkMenuPath; -typedef struct _GtkMenuFactory GtkMenuFactory; +typedef struct _GtkMenuEntry GtkMenuEntry; +typedef struct _GtkMenuPath GtkMenuPath; +typedef struct _GtkMenuFactory GtkMenuFactory; typedef void (*GtkMenuCallback) (GtkWidget *widget, gpointer user_data); struct _GtkMenuEntry { - char *path; - char *accelerator; + gchar *path; + gchar *accelerator; GtkMenuCallback callback; gpointer callback_data; GtkWidget *widget; @@ -52,33 +53,38 @@ struct _GtkMenuPath struct _GtkMenuFactory { - char *path; + gchar *path; GtkMenuFactoryType type; - GtkAcceleratorTable *table; + GtkAccelGroup *accel_group; GtkWidget *widget; GList *subfactories; }; +/* Note: the use of GtkMenuFactory is strongly deprecated. + * use GtkItemFactory instead (gtkitemfactory.h and gtkitemfactory.c). + * gtkmenufactory.h and gtkmenufactory.c are sheduled for removal + * in some future gtk versions. + */ -GtkMenuFactory* gtk_menu_factory_new (GtkMenuFactoryType type); -void gtk_menu_factory_destroy (GtkMenuFactory *factory); -void gtk_menu_factory_add_entries (GtkMenuFactory *factory, +GtkMenuFactory* gtk_menu_factory_new (GtkMenuFactoryType type); +void gtk_menu_factory_destroy (GtkMenuFactory *factory); +void gtk_menu_factory_add_entries (GtkMenuFactory *factory, GtkMenuEntry *entries, - int nentries); -void gtk_menu_factory_add_subfactory (GtkMenuFactory *factory, + int nentries); +void gtk_menu_factory_add_subfactory (GtkMenuFactory *factory, GtkMenuFactory *subfactory, - const char *path); -void gtk_menu_factory_remove_paths (GtkMenuFactory *factory, - char **paths, - int npaths); -void gtk_menu_factory_remove_entries (GtkMenuFactory *factory, + const char *path); +void gtk_menu_factory_remove_paths (GtkMenuFactory *factory, + char **paths, + int npaths); +void gtk_menu_factory_remove_entries (GtkMenuFactory *factory, GtkMenuEntry *entries, - int nentries); -void gtk_menu_factory_remove_subfactory (GtkMenuFactory *factory, + int nentries); +void gtk_menu_factory_remove_subfactory (GtkMenuFactory *factory, GtkMenuFactory *subfactory, - const char *path); -GtkMenuPath* gtk_menu_factory_find (GtkMenuFactory *factory, - const char *path); + const char *path); +GtkMenuPath* gtk_menu_factory_find (GtkMenuFactory *factory, + const char *path); #ifdef __cplusplus diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index 291d8fe031..ea76e03a34 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -17,7 +17,7 @@ * Boston, MA 02111-1307, USA. */ #include <string.h> -#include "gtklabel.h" +#include "gtkaccellabel.h" #include "gtkmain.h" #include "gtkmenu.h" #include "gtkmenuitem.h" @@ -43,12 +43,6 @@ static void gtk_menu_item_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_menu_item_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static gint gtk_menu_item_install_accel (GtkWidget *widget, - const gchar *signal_name, - gchar key, - guint8 modifiers); -static void gtk_menu_item_remove_accel (GtkWidget *widget, - const gchar *signal_name); static void gtk_menu_item_paint (GtkWidget *widget, GdkRectangle *area); static void gtk_menu_item_draw (GtkWidget *widget, @@ -69,10 +63,10 @@ static GtkItemClass *parent_class; static guint menu_item_signals[LAST_SIGNAL] = { 0 }; -guint +GtkType gtk_menu_item_get_type (void) { - static guint menu_item_type = 0; + static GtkType menu_item_type = 0; if (!menu_item_type) { @@ -122,8 +116,6 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass) widget_class->activate_signal = menu_item_signals[ACTIVATE]; widget_class->size_request = gtk_menu_item_size_request; widget_class->size_allocate = gtk_menu_item_size_allocate; - widget_class->install_accelerator = gtk_menu_item_install_accel; - widget_class->remove_accelerator = gtk_menu_item_remove_accel; widget_class->draw = gtk_menu_item_draw; widget_class->expose_event = gtk_menu_item_expose; widget_class->show_all = gtk_menu_item_show_all; @@ -135,20 +127,13 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass) klass->activate = NULL; klass->toggle_size = 0; - klass->shift_text = "Shft"; - klass->control_text = "Ctl"; - klass->alt_text = "Alt"; - klass->separator_text = "+"; } static void gtk_menu_item_init (GtkMenuItem *menu_item) { menu_item->submenu = NULL; - menu_item->accelerator_key = 0; - menu_item->accelerator_mods = 0; - menu_item->accelerator_size = 0; - menu_item->accelerator_signal = 0; + menu_item->accelerator_signal = menu_item_signals[ACTIVATE]; menu_item->toggle_size = 0; menu_item->show_toggle_indicator = FALSE; menu_item->show_submenu_indicator = FALSE; @@ -169,14 +154,15 @@ GtkWidget* gtk_menu_item_new_with_label (const gchar *label) { GtkWidget *menu_item; - GtkWidget *label_widget; + GtkWidget *accel_label; menu_item = gtk_menu_item_new (); - label_widget = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); + accel_label = gtk_accel_label_new (label); + gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5); - gtk_container_add (GTK_CONTAINER (menu_item), label_widget); - gtk_widget_show (label_widget); + gtk_container_add (GTK_CONTAINER (menu_item), accel_label); + gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), menu_item); + gtk_widget_show (accel_label); return menu_item; } @@ -255,58 +241,6 @@ gtk_menu_item_set_placement (GtkMenuItem *menu_item, } void -gtk_menu_item_accelerator_size (GtkMenuItem *menu_item) -{ - char buf[32]; - - g_return_if_fail (menu_item != NULL); - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - if (menu_item->accelerator_key) - { - gtk_menu_item_accelerator_text (menu_item, buf); - menu_item->accelerator_size = gdk_string_width (GTK_WIDGET (menu_item)->style->font, buf) + 13; - } - else if (menu_item->submenu && menu_item->show_submenu_indicator) - { - menu_item->accelerator_size = 21; - } - else - { - menu_item->accelerator_size = 0; - } -} - -void -gtk_menu_item_accelerator_text (GtkMenuItem *menu_item, - gchar *buffer) -{ - g_return_if_fail (menu_item != NULL); - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - if (menu_item->accelerator_key) - { - buffer[0] = '\0'; - if (menu_item->accelerator_mods & GDK_SHIFT_MASK) - { - strcat (buffer, MENU_ITEM_CLASS (menu_item)->shift_text); - strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text); - } - if (menu_item->accelerator_mods & GDK_CONTROL_MASK) - { - strcat (buffer, MENU_ITEM_CLASS (menu_item)->control_text); - strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text); - } - if (menu_item->accelerator_mods & GDK_MOD1_MASK) - { - strcat (buffer, MENU_ITEM_CLASS (menu_item)->alt_text); - strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text); - } - strncat (buffer, &menu_item->accelerator_key, 1); - } -} - -void gtk_menu_item_configure (GtkMenuItem *menu_item, gint show_toggle_indicator, gint show_submenu_indicator) @@ -341,6 +275,7 @@ static void gtk_menu_item_size_request (GtkWidget *widget, GtkRequisition *requisition) { + GtkMenuItem *menu_item; GtkBin *bin; g_return_if_fail (widget != NULL); @@ -348,8 +283,7 @@ gtk_menu_item_size_request (GtkWidget *widget, g_return_if_fail (requisition != NULL); bin = GTK_BIN (widget); - - gtk_menu_item_accelerator_size (GTK_MENU_ITEM (widget)); + menu_item = GTK_MENU_ITEM (widget); requisition->width = (GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness + @@ -364,12 +298,15 @@ gtk_menu_item_size_request (GtkWidget *widget, requisition->width += bin->child->requisition.width; requisition->height += bin->child->requisition.height; } + if (menu_item->submenu && menu_item->show_submenu_indicator) + requisition->width += 21; } static void gtk_menu_item_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { + GtkMenuItem *menu_item; GtkBin *bin; GtkAllocation child_allocation; @@ -377,13 +314,10 @@ gtk_menu_item_size_allocate (GtkWidget *widget, g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (allocation != NULL); - widget->allocation = *allocation; - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height); - + menu_item = GTK_MENU_ITEM (widget); bin = GTK_BIN (widget); + + widget->allocation = *allocation; if (bin->child) { @@ -395,70 +329,20 @@ gtk_menu_item_size_allocate (GtkWidget *widget, child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2); child_allocation.x += GTK_MENU_ITEM (widget)->toggle_size; - child_allocation.width -= (GTK_MENU_ITEM (widget)->toggle_size + - GTK_MENU_ITEM (widget)->accelerator_size); - + child_allocation.width -= GTK_MENU_ITEM (widget)->toggle_size; + if (menu_item->submenu && menu_item->show_submenu_indicator) + child_allocation.width -= 21; + gtk_widget_size_allocate (bin->child, &child_allocation); } -} - -static gint -gtk_menu_item_install_accel (GtkWidget *widget, - const gchar *signal_name, - gchar key, - guint8 modifiers) -{ - GtkMenuItem *menu_item; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE); - g_return_val_if_fail (signal_name != NULL, FALSE); - - menu_item = GTK_MENU_ITEM (widget); - - menu_item->accelerator_signal = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (widget)); - if (menu_item->accelerator_signal > 0) - { - menu_item->accelerator_key = key; - menu_item->accelerator_mods = modifiers; - - if (widget->parent) - gtk_widget_queue_resize (widget); - - return TRUE; - } - return FALSE; -} - -static void -gtk_menu_item_remove_accel (GtkWidget *widget, - const gchar *signal_name) -{ - GtkMenuItem *menu_item; - guint signal_num; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - g_return_if_fail (signal_name != NULL); - - menu_item = GTK_MENU_ITEM (widget); - - signal_num = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (widget)); - if (menu_item->accelerator_signal == signal_num) - { - menu_item->accelerator_key = 0; - menu_item->accelerator_mods = 0; - menu_item->accelerator_signal = 0; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); - if (GTK_WIDGET_VISIBLE (widget)) - { - gtk_widget_queue_draw (widget); - GTK_MENU_SHELL (widget->parent)->menu_flag = TRUE; - } - else - gtk_container_need_resize (GTK_CONTAINER (widget->parent)); - } + if (menu_item->submenu) + gtk_menu_reposition (GTK_MENU (menu_item->submenu)); } static void @@ -468,10 +352,8 @@ gtk_menu_item_paint (GtkWidget *widget, GtkMenuItem *menu_item; GtkStateType state_type; GtkShadowType shadow_type; - GdkFont *font; gint width, height; gint x, y; - char buf[32]; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); @@ -500,24 +382,7 @@ gtk_menu_item_paint (GtkWidget *widget, GTK_SHADOW_OUT, x, y, width, height); - if (menu_item->accelerator_key) - { - gtk_menu_item_accelerator_text (menu_item, buf); - - font = widget->style->font; - x = x + width - menu_item->accelerator_size + 13 - 4; - y = y + ((height - (font->ascent + font->descent)) / 2) + font->ascent; - - if (state_type == GTK_STATE_INSENSITIVE) - gdk_draw_string (widget->window, widget->style->font, - widget->style->white_gc, - x + 1, y + 1, buf); - - gdk_draw_string (widget->window, widget->style->font, - widget->style->fg_gc[state_type], - x, y, buf); - } - else if (menu_item->submenu && menu_item->show_submenu_indicator) + if (menu_item->submenu && menu_item->show_submenu_indicator) { shadow_type = GTK_SHADOW_OUT; if (state_type == GTK_STATE_PRELIGHT) diff --git a/gtk/gtkmenuitem.h b/gtk/gtkmenuitem.h index 756fa57310..55529f2d87 100644 --- a/gtk/gtkmenuitem.h +++ b/gtk/gtkmenuitem.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -26,70 +26,62 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -#define GTK_MENU_ITEM(obj) GTK_CHECK_CAST (obj, gtk_menu_item_get_type (), GtkMenuItem) -#define GTK_MENU_ITEM_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_menu_item_get_type (), GtkMenuItemClass) -#define GTK_IS_MENU_ITEM(obj) GTK_CHECK_TYPE (obj, gtk_menu_item_get_type ()) +#define GTK_TYPE_MENU_ITEM (gtk_menu_item_get_type ()) +#define GTK_MENU_ITEM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem)) +#define GTK_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ITEM, GtkMenuItemClass)) +#define GTK_IS_MENU_ITEM(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_MENU_ITEM)) +#define GTK_IS_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ITEM)) -typedef struct _GtkMenuItem GtkMenuItem; +typedef struct _GtkMenuItem GtkMenuItem; typedef struct _GtkMenuItemClass GtkMenuItemClass; struct _GtkMenuItem { GtkItem item; - + GtkWidget *submenu; - - guint accelerator_signal; - gchar accelerator_key; - guint8 accelerator_mods; - guint16 accelerator_size; + + guint accelerator_signal; guint16 toggle_size; - + guint show_toggle_indicator : 1; guint show_submenu_indicator : 1; guint submenu_placement : 1; guint submenu_direction : 1; guint right_justify: 1; - gint timer; + guint timer; }; struct _GtkMenuItemClass { GtkItemClass parent_class; - - gint toggle_size; - - gchar *shift_text; - gchar *control_text; - gchar *alt_text; - gchar *separator_text; - + + guint toggle_size; + void (* activate) (GtkMenuItem *menu_item); }; -guint gtk_menu_item_get_type (void); -GtkWidget* gtk_menu_item_new (void); -GtkWidget* gtk_menu_item_new_with_label (const gchar *label); -void gtk_menu_item_set_submenu (GtkMenuItem *menu_item, - GtkWidget *submenu); -void gtk_menu_item_remove_submenu (GtkMenuItem *menu_item); -void gtk_menu_item_set_placement (GtkMenuItem *menu_item, - GtkSubmenuPlacement placement); -void gtk_menu_item_accelerator_size (GtkMenuItem *menu_item); -void gtk_menu_item_accelerator_text (GtkMenuItem *menu_item, - gchar *buffer); -void gtk_menu_item_configure (GtkMenuItem *menu_item, - gint show_toggle_indicator, - gint show_submenu_indicator); -void gtk_menu_item_select (GtkMenuItem *menu_item); -void gtk_menu_item_deselect (GtkMenuItem *menu_item); -void gtk_menu_item_activate (GtkMenuItem *menu_item); -void gtk_menu_item_right_justify (GtkMenuItem *menu_item); +GtkType gtk_menu_item_get_type (void); +GtkWidget* gtk_menu_item_new (void); +GtkWidget* gtk_menu_item_new_with_label (const gchar *label); +void gtk_menu_item_set_submenu (GtkMenuItem *menu_item, + GtkWidget *submenu); +void gtk_menu_item_remove_submenu (GtkMenuItem *menu_item); +void gtk_menu_item_set_placement (GtkMenuItem *menu_item, + GtkSubmenuPlacement placement); +void gtk_menu_item_configure (GtkMenuItem *menu_item, + gint show_toggle_indicator, + gint show_submenu_indicator); +void gtk_menu_item_select (GtkMenuItem *menu_item); +void gtk_menu_item_deselect (GtkMenuItem *menu_item); +void gtk_menu_item_activate (GtkMenuItem *menu_item); +void gtk_menu_item_right_justify (GtkMenuItem *menu_item); #ifdef __cplusplus diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index c3476d2fdd..d89a68c381 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -28,6 +28,7 @@ enum { DEACTIVATE, + SELECTION_DONE, LAST_SIGNAL }; @@ -62,10 +63,10 @@ static GtkContainerClass *parent_class = NULL; static guint menu_shell_signals[LAST_SIGNAL] = { 0 }; -guint +GtkType gtk_menu_shell_get_type (void) { - static guint menu_shell_type = 0; + static GtkType menu_shell_type = 0; if (!menu_shell_type) { @@ -106,7 +107,13 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) GTK_SIGNAL_OFFSET (GtkMenuShellClass, deactivate), gtk_signal_default_marshaller, GTK_TYPE_NONE, 0); - + menu_shell_signals[SELECTION_DONE] = + gtk_signal_new ("selection-done", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkMenuShellClass, selection_done), + gtk_signal_default_marshaller, + GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, menu_shell_signals, LAST_SIGNAL); widget_class->map = gtk_menu_shell_map; @@ -122,6 +129,7 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) klass->submenu_placement = GTK_TOP_BOTTOM; klass->deactivate = gtk_real_menu_shell_deactivate; + klass->selection_done = NULL; } static void @@ -328,7 +336,10 @@ gtk_menu_shell_button_press (GtkWidget *widget, { widget = gtk_get_event_widget ((GdkEvent*) event); if (widget == GTK_WIDGET (menu_shell)) - gtk_menu_shell_deactivate (menu_shell); + { + gtk_menu_shell_deactivate (menu_shell); + gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]); + } } return TRUE; @@ -369,7 +380,15 @@ gtk_menu_shell_button_release (GtkWidget *widget, if (GTK_MENU_ITEM (menu_item)->submenu == NULL) { gtk_menu_shell_deactivate (menu_shell); + + /* flush the x-queue, so any grabs are removed and + * the menu is actually taken down + */ + gdk_flush (); gtk_widget_activate (menu_item); + + gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]); + return TRUE; } } @@ -396,7 +415,10 @@ gtk_menu_shell_button_release (GtkWidget *widget, deactivate = TRUE; if (deactivate) - gtk_menu_shell_deactivate (menu_shell); + { + gtk_menu_shell_deactivate (menu_shell); + gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]); + } } return TRUE; @@ -470,15 +492,15 @@ gtk_menu_shell_leave_notify (GtkWidget *widget, menu_item = GTK_MENU_ITEM (event_widget); - if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) - return TRUE; - if (menu_shell->ignore_leave) { menu_shell->ignore_leave = FALSE; return TRUE; } + if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) + return TRUE; + if ((menu_shell->active_menu_item == event_widget) && (menu_item->submenu == NULL)) { diff --git a/gtk/gtkmenushell.h b/gtk/gtkmenushell.h index 9224000be6..808e50ab81 100644 --- a/gtk/gtkmenushell.h +++ b/gtk/gtkmenushell.h @@ -8,7 +8,7 @@ * * This library 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -26,54 +26,58 @@ #ifdef __cplusplus extern "C" { +#pragma } #endif /* __cplusplus */ -#define GTK_MENU_SHELL(obj) GTK_CHECK_CAST (obj, gtk_menu_shell_get_type (), GtkMenuShell) -#define GTK_MENU_SHELL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_menu_shell_get_type (), GtkMenuShellClass) -#define GTK_IS_MENU_SHELL(obj) GTK_CHECK_TYPE (obj, gtk_menu_shell_get_type ()) +#define GTK_TYPE_MENU_SHELL (gtk_menu_shell_get_type ()) +#define GTK_MENU_SHELL(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_MENU_SHELL, GtkMenuShell)) +#define GTK_MENU_SHELL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_SHELL, GtkMenuShellClass)) +#define GTK_IS_MENU_SHELL(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_MENU_SHELL)) +#define GTK_IS_MENU_SHELL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_SHELL)) -typedef struct _GtkMenuShell GtkMenuShell; +typedef struct _GtkMenuShell GtkMenuShell; typedef struct _GtkMenuShellClass GtkMenuShellClass; struct _GtkMenuShell { GtkContainer container; - + GList *children; GtkWidget *active_menu_item; GtkWidget *parent_menu_shell; - + guint active : 1; guint have_grab : 1; guint have_xgrab : 1; guint button : 2; guint ignore_leave : 1; guint menu_flag : 1; - + guint32 activate_time; }; struct _GtkMenuShellClass { GtkContainerClass parent_class; - + guint submenu_placement : 1; - - void (*deactivate) (GtkMenuShell *menu_shell); + + void (*deactivate) (GtkMenuShell *menu_shell); + void (*selection_done) (GtkMenuShell *menu_shell); }; -guint gtk_menu_shell_get_type (void); -void gtk_menu_shell_append (GtkMenuShell *menu_shell, - GtkWidget *child); -void gtk_menu_shell_prepend (GtkMenuShell *menu_shell, - GtkWidget *child); -void gtk_menu_shell_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position); -void gtk_menu_shell_deactivate (GtkMenuShell *menu_shell); +GtkType gtk_menu_shell_get_type (void); +void gtk_menu_shell_append (GtkMenuShell *menu_shell, + GtkWidget *child); +void gtk_menu_shell_prepend (GtkMenuShell *menu_shell, + GtkWidget *child); +void gtk_menu_shell_insert (GtkMenuShell *menu_shell, + GtkWidget *child, + gint position); +void gtk_menu_shell_deactivate (GtkMenuShell *menu_shell); #ifdef __cplusplus diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index d4704506d0..52eb3e9fa5 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -2913,9 +2913,14 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook, page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label); else page->menu_label = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (page->menu_label), 0.0, 0.5); } gtk_widget_show (page->menu_label); menu_item = gtk_menu_item_new (); + gtk_signal_connect (GTK_OBJECT (menu_item), + "add_accelerator", + GTK_SIGNAL_FUNC (gtk_widget_stop_accelerator), + NULL); gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label); gtk_menu_insert (GTK_MENU (notebook->menu), menu_item, position); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c index de013a2475..9a5579416c 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -365,14 +365,6 @@ gtk_object_class_add_signals (GtkObjectClass *class, class->nsignals += nsignals; } -/***************************************** - * gtk_object_class_add_user_signal: - * - * arguments: - * - * results: - *****************************************/ - guint gtk_object_class_add_user_signal (GtkObjectClass *class, const gchar *name, @@ -419,6 +411,52 @@ gtk_object_class_add_user_signal (GtkObjectClass *class, return signal_id; } +guint +gtk_object_class_add_user_signal_no_recurse (GtkObjectClass *class, + const gchar *name, + GtkSignalMarshaller marshaller, + GtkType return_val, + guint nparams, + ...) +{ + GtkType *params; + guint i; + va_list args; + guint signal_id; + + g_return_val_if_fail (class != NULL, 0); + + if (nparams > 0) + { + params = g_new (GtkType, nparams); + + va_start (args, nparams); + + for (i = 0; i < nparams; i++) + params[i] = va_arg (args, GtkType); + + va_end (args); + } + else + params = NULL; + + signal_id = gtk_signal_newv (name, + GTK_RUN_NO_RECURSE, + class->type, + 0, + marshaller, + return_val, + nparams, + params); + + g_free (params); + + if (signal_id) + gtk_object_class_add_signals (class, &signal_id, 1); + + return signal_id; +} + /***************************************** * gtk_object_sink: * diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index d41d0f6fb0..aea23a9353 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -98,14 +98,14 @@ extern "C" { * is a kinda nasty break up, it does make the size of * derived objects smaller. */ -enum +typedef enum { GTK_DESTROYED = 1 << 0, GTK_FLOATING = 1 << 1, GTK_CONNECTED = 1 << 2, GTK_RESERVED_2 = 1 << 3, GTK_OBJECT_FLAG_LAST = GTK_RESERVED_2 -}; +} GtkObjectFlags; /* Macros for extracting the object_flags from GtkObject. */ @@ -121,15 +121,16 @@ enum /* GtkArg flag bits for gtk_object_add_arg_type */ -enum +typedef enum { GTK_ARG_READABLE = 1 << 0, GTK_ARG_WRITABLE = 1 << 1, GTK_ARG_CONSTRUCT = 1 << 2, + GTK_ARG_MASK = 0x03, /* aliases */ GTK_ARG_READWRITE = GTK_ARG_READABLE | GTK_ARG_WRITABLE -}; +} GtkArgFlags; typedef struct _GtkObjectClass GtkObjectClass; @@ -233,6 +234,12 @@ guint gtk_object_class_add_user_signal (GtkObjectClass *klass, GtkType return_val, guint nparams, ...); +guint gtk_object_class_add_user_signal_no_recurse (GtkObjectClass *klass, + const gchar *name, + GtkSignalMarshaller marshaller, + GtkType return_val, + guint nparams, + ...); GtkObject* gtk_object_new (GtkType type, ...); diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 41b2dacf71..664632bca3 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -32,7 +32,7 @@ extern "C" { /* The private flags that are used in the private_flags member of GtkWidget. */ -enum +typedef enum { PRIVATE_GTK_USER_STYLE = 1 << 0, PRIVATE_GTK_REDRAW_PENDING = 1 << 1, @@ -41,7 +41,7 @@ enum PRIVATE_GTK_LEAVE_PENDING = 1 << 4, PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5, PRIVATE_GTK_IN_REPARENT = 1 << 6 -}; +} GtkPrivateFlags; /* Macros for extracting a widgets private_flags from GtkWidget. */ diff --git a/gtk/gtkradiomenuitem.c b/gtk/gtkradiomenuitem.c index 9e00fef26e..ddfc0c6984 100644 --- a/gtk/gtkradiomenuitem.c +++ b/gtk/gtkradiomenuitem.c @@ -16,7 +16,7 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ -#include "gtklabel.h" +#include "gtkaccellabel.h" #include "gtkradiomenuitem.h" @@ -115,14 +115,14 @@ gtk_radio_menu_item_new_with_label (GSList *group, const gchar *label) { GtkWidget *radio_menu_item; - GtkWidget *label_widget; + GtkWidget *accel_label; radio_menu_item = gtk_radio_menu_item_new (group); - label_widget = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); - - gtk_container_add (GTK_CONTAINER (radio_menu_item), label_widget); - gtk_widget_show (label_widget); + accel_label = gtk_accel_label_new (label); + gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5); + gtk_container_add (GTK_CONTAINER (radio_menu_item), accel_label); + gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), radio_menu_item); + gtk_widget_show (accel_label); return radio_menu_item; } diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c index 6cc3eccd2a..f7f6c1d4b1 100644 --- a/gtk/gtkrc.c +++ b/gtk/gtkrc.c @@ -24,6 +24,7 @@ #include <string.h> #include <stdio.h> #include "gtkrc.h" +#include "gtkbindings.h" enum { @@ -86,8 +87,8 @@ struct _GtkRcStyle struct _GtkRcSet { - char *set; - GtkRcStyle *rc_style; + GtkPatternSpec pspec; + GtkRcStyle *rc_style; }; struct _GtkRcFile @@ -103,9 +104,9 @@ static gint gtk_rc_style_compare (const char *a, const char *b); static GtkRcStyle* gtk_rc_style_find (const char *name); static GtkRcStyle* gtk_rc_styles_match (GSList *sets, - const char *path); -static gint gtk_rc_style_match (const char *set, - const char *path); + guint path_length, + gchar *path, + gchar *path_reversed); static GtkStyle* gtk_rc_style_init (GtkRcStyle *rc_style, GdkColormap *cmap); static void gtk_rc_parse_file (const gchar *filename, @@ -142,8 +143,6 @@ static char* gtk_rc_find_pixmap_in_path (GScanner *scanner, gchar *pixmap_file); static gint gtk_rc_parse_widget_style (GScanner *scanner); static gint gtk_rc_parse_widget_class_style (GScanner *scanner); -static char* gtk_rc_widget_path (GtkWidget *widget); -static char* gtk_rc_widget_class_path (GtkWidget *widget); static void gtk_rc_clear_hash_node (gpointer key, gpointer data, gpointer user_data); @@ -363,7 +362,6 @@ static void gtk_rc_clear_styles (void) { GSList *tmp_list; - GtkRcSet *rc_set; /* Clear out all old rc_styles */ @@ -374,8 +372,10 @@ gtk_rc_clear_styles (void) tmp_list = widget_sets; while (tmp_list) { - rc_set = (GtkRcSet *)tmp_list->data; - g_free (rc_set->set); + GtkRcSet *rc_set; + + rc_set = tmp_list->data; + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); tmp_list = tmp_list->next; @@ -386,8 +386,10 @@ gtk_rc_clear_styles (void) tmp_list = widget_class_sets; while (tmp_list) { - rc_set = (GtkRcSet *)tmp_list->data; - g_free (rc_set->set); + GtkRcSet *rc_set; + + rc_set = tmp_list->data; + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); tmp_list = tmp_list->next; @@ -447,38 +449,33 @@ GtkStyle* gtk_rc_get_style (GtkWidget *widget) { GtkRcStyle *rc_style; - char *path; if (widget_sets) { - path = gtk_rc_widget_path (widget); - if (path) - { - rc_style = gtk_rc_styles_match (widget_sets, path); - g_free (path); - - if (rc_style) - { - return gtk_rc_style_init (rc_style, - gtk_widget_get_colormap (widget)); - } - } + gchar *path, *path_reversed; + guint path_length; + + gtk_widget_path (widget, &path_length, &path, &path_reversed); + rc_style = gtk_rc_styles_match (widget_sets, path_length, path, path_reversed); + g_free (path); + g_free (path_reversed); + + if (rc_style) + return gtk_rc_style_init (rc_style, gtk_widget_get_colormap (widget)); } if (widget_class_sets) { - path = gtk_rc_widget_class_path (widget); - if (path) - { - rc_style = gtk_rc_styles_match (widget_class_sets, path); - g_free (path); - - if (rc_style) - { - return gtk_rc_style_init (rc_style, - gtk_widget_get_colormap (widget)); - } - } + gchar *path, *path_reversed; + guint path_length; + + gtk_widget_class_path (widget, &path_length, &path, &path_reversed); + rc_style = gtk_rc_styles_match (widget_class_sets, path_length, path, path_reversed); + g_free (path); + g_free (path_reversed); + + if (rc_style) + return gtk_rc_style_init (rc_style, gtk_widget_get_colormap (widget)); } return NULL; @@ -503,9 +500,9 @@ gtk_rc_add_widget_name_style (GtkStyle *style, rc_style->bg_pixmap_name[i] = NULL; rc_style->styles = g_list_append (NULL, style); - + rc_set = g_new (GtkRcSet, 1); - rc_set->set = g_strdup (pattern); + gtk_pattern_spec_init (&rc_set->pspec, pattern); rc_set->rc_style = rc_style; widget_sets = g_slist_append (widget_sets, rc_set); @@ -532,7 +529,7 @@ gtk_rc_add_widget_class_style (GtkStyle *style, rc_style->styles = g_list_append (NULL, style); rc_set = g_new (GtkRcSet, 1); - rc_set->set = g_strdup (pattern); + gtk_pattern_spec_init (&rc_set->pspec, pattern); rc_set->rc_style = rc_style; widget_class_sets = g_slist_append (widget_class_sets, rc_set); @@ -627,73 +624,24 @@ gtk_rc_style_find (const char *name) static GtkRcStyle* gtk_rc_styles_match (GSList *sets, - const char *path) + guint path_length, + gchar *path, + gchar *path_reversed) { GtkRcSet *rc_set; - + while (sets) { rc_set = sets->data; sets = sets->next; - - if (gtk_rc_style_match (rc_set->set, path)) + + if (gtk_pattern_match (&rc_set->pspec, path_length, path, path_reversed)) return rc_set->rc_style; } return NULL; } -static gint -gtk_rc_style_match (const char *set, - const char *path) -{ - char ch; - - while (1) - { - ch = *set++; - if (ch == '\0') - return (*path == '\0'); - - switch (ch) - { - case '*': - while (*set == '*') - set++; - - ch = *set++; - if (ch == '\0') - return TRUE; - - while (*path) - { - while (*path && (ch != *path)) - path++; - - if (!(*path)) - return FALSE; - - path++; - if (gtk_rc_style_match (set, path)) - return TRUE; - } - break; - - case '?': - break; - - default: - if (ch == *path) - path++; - else - return FALSE; - break; - } - } - - return TRUE; -} - static GtkStyle * gtk_rc_style_init (GtkRcStyle *rc_style, GdkColormap *cmap) { @@ -1478,14 +1426,14 @@ gtk_rc_parse_widget_style (GScanner *scanner) token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_STRING) return PARSE_ERROR; - + rc_set = g_new (GtkRcSet, 1); - rc_set->set = g_strdup (scanner->value.v_string); + gtk_pattern_spec_init (&rc_set->pspec, scanner->value.v_string); token = g_scanner_get_next_token (scanner); if (token != TOKEN_STYLE) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1493,7 +1441,7 @@ gtk_rc_parse_widget_style (GScanner *scanner) token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_STRING) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1501,7 +1449,7 @@ gtk_rc_parse_widget_style (GScanner *scanner) rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string); if (!rc_set->rc_style) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1529,12 +1477,12 @@ gtk_rc_parse_widget_class_style (GScanner *scanner) return PARSE_ERROR; rc_set = g_new (GtkRcSet, 1); - rc_set->set = g_strdup (scanner->value.v_string); - + gtk_pattern_spec_init (&rc_set->pspec, scanner->value.v_string); + token = g_scanner_get_next_token (scanner); if (token != TOKEN_STYLE) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1542,7 +1490,7 @@ gtk_rc_parse_widget_class_style (GScanner *scanner) token = g_scanner_get_next_token (scanner); if (token != G_TOKEN_STRING) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1550,7 +1498,7 @@ gtk_rc_parse_widget_class_style (GScanner *scanner) rc_set->rc_style = gtk_rc_style_find (scanner->value.v_string); if (!rc_set->rc_style) { - g_free (rc_set->set); + gtk_pattern_spec_free_segs (&rc_set->pspec); g_free (rc_set); return PARSE_ERROR; } @@ -1560,102 +1508,6 @@ gtk_rc_parse_widget_class_style (GScanner *scanner) return PARSE_OK; } -static char* -gtk_rc_widget_path (GtkWidget *widget) -{ - GtkWidget *tmp_widget; - char *path; - char *name; - int pathlength; - int namelength; - - path = NULL; - pathlength = 0; - - tmp_widget = widget; - while (tmp_widget) - { - name = gtk_widget_get_name (tmp_widget); - pathlength += strlen (name); - - tmp_widget = tmp_widget->parent; - - if (tmp_widget) - pathlength += 1; - } - - path = g_new (char, pathlength + 1); - path[pathlength] = '\0'; - - tmp_widget = widget; - while (tmp_widget) - { - name = gtk_widget_get_name (tmp_widget); - namelength = strlen (name); - - strncpy (&path[pathlength - namelength], name, namelength); - pathlength -= namelength; - - tmp_widget = tmp_widget->parent; - - if (tmp_widget) - { - pathlength -= 1; - path[pathlength] = '.'; - } - } - - return path; -} - -static char* -gtk_rc_widget_class_path (GtkWidget *widget) -{ - GtkWidget *tmp_widget; - char *path; - char *name; - int pathlength; - int namelength; - - path = NULL; - pathlength = 0; - - tmp_widget = widget; - while (tmp_widget) - { - name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget)); - pathlength += strlen (name); - - tmp_widget = tmp_widget->parent; - - if (tmp_widget) - pathlength += 1; - } - - path = g_new (char, pathlength + 1); - path[pathlength] = '\0'; - - tmp_widget = widget; - while (tmp_widget) - { - name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget)); - namelength = strlen (name); - - strncpy (&path[pathlength - namelength], name, namelength); - pathlength -= namelength; - - tmp_widget = tmp_widget->parent; - - if (tmp_widget) - { - pathlength -= 1; - path[pathlength] = '.'; - } - } - - return path; -} - /* typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window, GdkColormap *colormap, diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c index ddb18c5f35..ef8f13607d 100644 --- a/gtk/gtksignal.c +++ b/gtk/gtksignal.c @@ -18,6 +18,7 @@ */ #include <stdarg.h> #include <string.h> +#include <stdio.h> #include "gtksignal.h" @@ -475,12 +476,14 @@ gtk_signal_emitv (GtkObject *object, g_return_if_fail (object != NULL); g_return_if_fail (signal_id >= 1); - g_return_if_fail (params != NULL); signal = LOOKUP_SIGNAL_ID (signal_id); g_return_if_fail (signal != NULL); g_return_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object), signal->object_type)); + if (signal->nparams > 0) + g_return_if_fail (params != NULL); + gtk_signal_real_emit (object, signal, params); } @@ -1341,6 +1344,8 @@ gtk_signal_handler_insert (GtkObject *object, } } +static GtkObject *gtk_trace_signal_object = NULL; + static void gtk_signal_real_emit (GtkObject *object, GtkSignal *signal, @@ -1351,9 +1356,14 @@ gtk_signal_real_emit (GtkObject *object, guchar **signal_func_offset; register guint signal_id = signal->signal_id; - if(gtk_debug_flags & GTK_DEBUG_SIGNALS) - g_print("Sending signal %s to object %p (%s)\n", - signal->name, object, gtk_type_name(object->klass->type)); +#ifdef G_ENABLE_DEBUG + if (gtk_debug_flags & GTK_DEBUG_SIGNALS || + object == gtk_trace_signal_object) + fprintf (stdout, "trace: signal_emit(\"%s\") for %s:%p\n", + signal->name, + gtk_type_name (GTK_OBJECT_TYPE (object)), + object); +#endif /* G_ENABLE_DEBUG */ if ((signal->run_type & GTK_RUN_NO_RECURSE) && gtk_emission_check (current_emissions, object, signal_id)) @@ -1524,6 +1534,9 @@ gtk_signal_connect_by_type (GtkObject *object, * sure the one we are adding is valid. We need to perform * the lookup on the objects parents as well. If it isn't * valid then issue a warning and return. + * As of now (1998-05-27) this lookup shouldn't be neccessarry + * anymore since gtk_signal_lookup() has been reworked to only + * return correct signal ids per class-branch. */ found_it = FALSE; class = object->klass; @@ -1898,7 +1911,7 @@ gtk_params_get (GtkArg *params, case GTK_TYPE_C_CALLBACK: case GTK_TYPE_ARGS: default: - g_error ("unsupported type `%s' in signal return", + g_error ("Gtk: unsupported type `%s' in signal return", gtk_type_name (return_val)); break; } diff --git a/gtk/gtktypebuiltins.c b/gtk/gtktypebuiltins.c index 868f40fe48..8ca1418a40 100644 --- a/gtk/gtktypebuiltins.c +++ b/gtk/gtktypebuiltins.c @@ -1,60 +1,71 @@ /* generated by gentypeinfo from "gtk.defs" */ - { "GtkWindowType", GTK_TYPE_ENUM }, - { "GtkStateType", GTK_TYPE_ENUM }, - { "GtkDirectionType", GTK_TYPE_ENUM }, - { "GtkShadowType", GTK_TYPE_ENUM }, - { "GtkArrowType", GTK_TYPE_ENUM }, - { "GtkPackType", GTK_TYPE_ENUM }, - { "GtkPolicyType", GTK_TYPE_ENUM }, - { "GtkUpdateType", GTK_TYPE_ENUM }, - { "GtkAttachOptions", GTK_TYPE_FLAGS }, - { "GtkSignalRunType", GTK_TYPE_FLAGS }, - { "GtkWindowPosition", GTK_TYPE_ENUM }, - { "GtkSubmenuDirection", GTK_TYPE_ENUM }, - { "GtkSubmenuPlacement", GTK_TYPE_ENUM }, - { "GtkMenuFactoryType", GTK_TYPE_ENUM }, - { "GtkMetricType", GTK_TYPE_ENUM }, - { "GtkScrollType", GTK_TYPE_ENUM }, - { "GtkTroughType", GTK_TYPE_ENUM }, - { "GtkPositionType", GTK_TYPE_ENUM }, - { "GtkPreviewType", GTK_TYPE_ENUM }, - { "GtkWidgetFlags", GTK_TYPE_FLAGS }, - { "GtkSelectionMode", GTK_TYPE_ENUM }, - { "GtkCurveType", GTK_TYPE_ENUM }, - { "GtkFundamentalType", GTK_TYPE_ENUM }, - { "GtkJustification", GTK_TYPE_ENUM }, - { "GtkButtonBoxStyle", GTK_TYPE_ENUM }, - { "GtkOrientation", GTK_TYPE_ENUM }, - { "GdkWindowType", GTK_TYPE_ENUM }, - { "GdkWindowClass", GTK_TYPE_ENUM }, - { "GdkImageType", GTK_TYPE_ENUM }, - { "GdkVisualType", GTK_TYPE_ENUM }, - { "GdkWindowAttributesType", GTK_TYPE_FLAGS }, - { "GdkWindowHints", GTK_TYPE_FLAGS }, - { "GdkFunction", GTK_TYPE_ENUM }, - { "GdkFill", GTK_TYPE_ENUM }, - { "GdkLineStyle", GTK_TYPE_ENUM }, - { "GdkCapStyle", GTK_TYPE_ENUM }, - { "GdkJoinStyle", GTK_TYPE_ENUM }, - { "GdkCursorType", GTK_TYPE_ENUM }, - { "GdkEventType", GTK_TYPE_ENUM }, - { "GdkEventMask", GTK_TYPE_FLAGS }, - { "GdkNotifyType", GTK_TYPE_ENUM }, - { "GdkModifierType", GTK_TYPE_FLAGS }, - { "GdkSubwindowMode", GTK_TYPE_ENUM }, - { "GdkInputCondition", GTK_TYPE_FLAGS }, - { "GdkStatus", GTK_TYPE_ENUM }, - { "GdkByteOrder", GTK_TYPE_ENUM }, - { "GdkGCValuesMask", GTK_TYPE_FLAGS }, - { "GdkSelection", GTK_TYPE_ENUM }, - { "GdkPropertyState", GTK_TYPE_ENUM }, - { "GdkPropMode", GTK_TYPE_ENUM }, - { "GtkAcceleratorTable", GTK_TYPE_BOXED }, - { "GtkStyle", GTK_TYPE_BOXED }, - { "GdkColormap", GTK_TYPE_BOXED }, - { "GdkVisual", GTK_TYPE_BOXED }, - { "GdkFont", GTK_TYPE_BOXED }, - { "GdkWindow", GTK_TYPE_BOXED }, - { "GdkEvent", GTK_TYPE_BOXED }, - { "GdkColor", GTK_TYPE_BOXED }, + { "GtkAccelFlags", GTK_TYPE_FLAGS, enum_values_GtkAccelFlags }, + { "GtkArrowType", GTK_TYPE_ENUM, enum_values_GtkArrowType }, + { "GtkAttachOptions", GTK_TYPE_FLAGS, enum_values_GtkAttachOptions }, + { "GtkButtonBoxStyle", GTK_TYPE_ENUM, enum_values_GtkButtonBoxStyle }, + { "GtkDirectionType", GTK_TYPE_ENUM, enum_values_GtkDirectionType }, + { "GtkJustification", GTK_TYPE_ENUM, enum_values_GtkJustification }, + { "GtkMatchType", GTK_TYPE_ENUM, enum_values_GtkMatchType }, + { "GtkMenuFactoryType", GTK_TYPE_ENUM, enum_values_GtkMenuFactoryType }, + { "GtkMetricType", GTK_TYPE_ENUM, enum_values_GtkMetricType }, + { "GtkOrientation", GTK_TYPE_ENUM, enum_values_GtkOrientation }, + { "GtkPackType", GTK_TYPE_ENUM, enum_values_GtkPackType }, + { "GtkPathPriorityType", GTK_TYPE_ENUM, enum_values_GtkPathPriorityType }, + { "GtkPathType", GTK_TYPE_ENUM, enum_values_GtkPathType }, + { "GtkPolicyType", GTK_TYPE_ENUM, enum_values_GtkPolicyType }, + { "GtkPositionType", GTK_TYPE_ENUM, enum_values_GtkPositionType }, + { "GtkPreviewType", GTK_TYPE_ENUM, enum_values_GtkPreviewType }, + { "GtkReliefStyle", GTK_TYPE_ENUM, enum_values_GtkReliefStyle }, + { "GtkScrollType", GTK_TYPE_ENUM, enum_values_GtkScrollType }, + { "GtkSelectionMode", GTK_TYPE_ENUM, enum_values_GtkSelectionMode }, + { "GtkShadowType", GTK_TYPE_ENUM, enum_values_GtkShadowType }, + { "GtkSignalRunType", GTK_TYPE_FLAGS, enum_values_GtkSignalRunType }, + { "GtkStateType", GTK_TYPE_ENUM, enum_values_GtkStateType }, + { "GtkSubmenuDirection", GTK_TYPE_ENUM, enum_values_GtkSubmenuDirection }, + { "GtkSubmenuPlacement", GTK_TYPE_ENUM, enum_values_GtkSubmenuPlacement }, + { "GtkToolbarStyle", GTK_TYPE_ENUM, enum_values_GtkToolbarStyle }, + { "GtkTroughType", GTK_TYPE_ENUM, enum_values_GtkTroughType }, + { "GtkUpdateType", GTK_TYPE_ENUM, enum_values_GtkUpdateType }, + { "GtkVisibility", GTK_TYPE_ENUM, enum_values_GtkVisibility }, + { "GtkWindowPosition", GTK_TYPE_ENUM, enum_values_GtkWindowPosition }, + { "GtkWindowType", GTK_TYPE_ENUM, enum_values_GtkWindowType }, + { "GtkObjectFlags", GTK_TYPE_FLAGS, enum_values_GtkObjectFlags }, + { "GtkArgFlags", GTK_TYPE_FLAGS, enum_values_GtkArgFlags }, + { "GtkWidgetFlags", GTK_TYPE_FLAGS, enum_values_GtkWidgetFlags }, + { "GtkPrivateFlags", GTK_TYPE_FLAGS, enum_values_GtkPrivateFlags }, + { "GtkCurveType", GTK_TYPE_ENUM, enum_values_GtkCurveType }, + { "GtkFundamentalType", GTK_TYPE_ENUM, enum_values_GtkFundamentalType }, + { "GdkWindowType", GTK_TYPE_ENUM, enum_values_GdkWindowType }, + { "GdkWindowClass", GTK_TYPE_ENUM, enum_values_GdkWindowClass }, + { "GdkImageType", GTK_TYPE_ENUM, enum_values_GdkImageType }, + { "GdkVisualType", GTK_TYPE_ENUM, enum_values_GdkVisualType }, + { "GdkWindowAttributesType", GTK_TYPE_FLAGS, enum_values_GdkWindowAttributesType }, + { "GdkWindowHints", GTK_TYPE_FLAGS, enum_values_GdkWindowHints }, + { "GdkFunction", GTK_TYPE_ENUM, enum_values_GdkFunction }, + { "GdkFill", GTK_TYPE_ENUM, enum_values_GdkFill }, + { "GdkLineStyle", GTK_TYPE_ENUM, enum_values_GdkLineStyle }, + { "GdkCapStyle", GTK_TYPE_ENUM, enum_values_GdkCapStyle }, + { "GdkJoinStyle", GTK_TYPE_ENUM, enum_values_GdkJoinStyle }, + { "GdkCursorType", GTK_TYPE_ENUM, enum_values_GdkCursorType }, + { "GdkEventType", GTK_TYPE_ENUM, enum_values_GdkEventType }, + { "GdkEventMask", GTK_TYPE_FLAGS, enum_values_GdkEventMask }, + { "GdkNotifyType", GTK_TYPE_ENUM, enum_values_GdkNotifyType }, + { "GdkCrossingMode", GTK_TYPE_FLAGS, enum_values_GdkCrossingMode }, + { "GdkModifierType", GTK_TYPE_FLAGS, enum_values_GdkModifierType }, + { "GdkSubwindowMode", GTK_TYPE_ENUM, enum_values_GdkSubwindowMode }, + { "GdkInputCondition", GTK_TYPE_FLAGS, enum_values_GdkInputCondition }, + { "GdkStatus", GTK_TYPE_ENUM, enum_values_GdkStatus }, + { "GdkByteOrder", GTK_TYPE_ENUM, enum_values_GdkByteOrder }, + { "GdkGCValuesMask", GTK_TYPE_FLAGS, enum_values_GdkGCValuesMask }, + { "GdkSelection", GTK_TYPE_ENUM, enum_values_GdkSelection }, + { "GdkPropertyState", GTK_TYPE_ENUM, enum_values_GdkPropertyState }, + { "GdkPropMode", GTK_TYPE_ENUM, enum_values_GdkPropMode }, + { "GtkAccelGroup", GTK_TYPE_BOXED, NULL }, + { "GtkStyle", GTK_TYPE_BOXED, NULL }, + { "GdkColormap", GTK_TYPE_BOXED, NULL }, + { "GdkVisual", GTK_TYPE_BOXED, NULL }, + { "GdkFont", GTK_TYPE_BOXED, NULL }, + { "GdkWindow", GTK_TYPE_BOXED, NULL }, + { "GdkEvent", GTK_TYPE_BOXED, NULL }, + { "GdkColor", GTK_TYPE_BOXED, NULL }, diff --git a/gtk/gtktypebuiltins.h b/gtk/gtktypebuiltins.h index 73a1d10135..a37e4aaa20 100644 --- a/gtk/gtktypebuiltins.h +++ b/gtk/gtktypebuiltins.h @@ -1,61 +1,72 @@ /* generated by gentypeinfo from "gtk.defs" */ -#define GTK_TYPE_WINDOW_TYPE (gtk_type_builtins[0]) -#define GTK_TYPE_STATE_TYPE (gtk_type_builtins[1]) -#define GTK_TYPE_DIRECTION_TYPE (gtk_type_builtins[2]) -#define GTK_TYPE_SHADOW_TYPE (gtk_type_builtins[3]) -#define GTK_TYPE_ARROW_TYPE (gtk_type_builtins[4]) -#define GTK_TYPE_PACK_TYPE (gtk_type_builtins[5]) -#define GTK_TYPE_POLICY_TYPE (gtk_type_builtins[6]) -#define GTK_TYPE_UPDATE_TYPE (gtk_type_builtins[7]) -#define GTK_TYPE_ATTACH_OPTIONS (gtk_type_builtins[8]) -#define GTK_TYPE_SIGNAL_RUN_TYPE (gtk_type_builtins[9]) -#define GTK_TYPE_WINDOW_POSITION (gtk_type_builtins[10]) -#define GTK_TYPE_SUBMENU_DIRECTION (gtk_type_builtins[11]) -#define GTK_TYPE_SUBMENU_PLACEMENT (gtk_type_builtins[12]) -#define GTK_TYPE_MENU_FACTORY_TYPE (gtk_type_builtins[13]) -#define GTK_TYPE_METRIC_TYPE (gtk_type_builtins[14]) -#define GTK_TYPE_SCROLL_TYPE (gtk_type_builtins[15]) -#define GTK_TYPE_TROUGH_TYPE (gtk_type_builtins[16]) -#define GTK_TYPE_POSITION_TYPE (gtk_type_builtins[17]) -#define GTK_TYPE_PREVIEW_TYPE (gtk_type_builtins[18]) -#define GTK_TYPE_WIDGET_FLAGS (gtk_type_builtins[19]) -#define GTK_TYPE_SELECTION_MODE (gtk_type_builtins[20]) -#define GTK_TYPE_CURVE_TYPE (gtk_type_builtins[21]) -#define GTK_TYPE_FUNDAMENTAL_TYPE (gtk_type_builtins[22]) -#define GTK_TYPE_JUSTIFICATION (gtk_type_builtins[23]) -#define GTK_TYPE_BUTTON_BOX_STYLE (gtk_type_builtins[24]) -#define GTK_TYPE_ORIENTATION (gtk_type_builtins[25]) -#define GTK_TYPE_GDK_WINDOW_TYPE (gtk_type_builtins[26]) -#define GTK_TYPE_GDK_WINDOW_CLASS (gtk_type_builtins[27]) -#define GTK_TYPE_GDK_IMAGE_TYPE (gtk_type_builtins[28]) -#define GTK_TYPE_GDK_VISUAL_TYPE (gtk_type_builtins[29]) -#define GTK_TYPE_GDK_WINDOW_ATTRIBUTES_TYPE (gtk_type_builtins[30]) -#define GTK_TYPE_GDK_WINDOW_HINTS (gtk_type_builtins[31]) -#define GTK_TYPE_GDK_FUNCTION (gtk_type_builtins[32]) -#define GTK_TYPE_GDK_FILL (gtk_type_builtins[33]) -#define GTK_TYPE_GDK_LINE_STYLE (gtk_type_builtins[34]) -#define GTK_TYPE_GDK_CAP_STYLE (gtk_type_builtins[35]) -#define GTK_TYPE_GDK_JOIN_STYLE (gtk_type_builtins[36]) -#define GTK_TYPE_GDK_CURSOR_TYPE (gtk_type_builtins[37]) -#define GTK_TYPE_GDK_EVENT_TYPE (gtk_type_builtins[38]) -#define GTK_TYPE_GDK_EVENT_MASK (gtk_type_builtins[39]) -#define GTK_TYPE_GDK_NOTIFY_TYPE (gtk_type_builtins[40]) -#define GTK_TYPE_GDK_MODIFIER_TYPE (gtk_type_builtins[41]) -#define GTK_TYPE_GDK_SUBWINDOW_MODE (gtk_type_builtins[42]) -#define GTK_TYPE_GDK_INPUT_CONDITION (gtk_type_builtins[43]) -#define GTK_TYPE_GDK_STATUS (gtk_type_builtins[44]) -#define GTK_TYPE_GDK_BYTE_ORDER (gtk_type_builtins[45]) -#define GTK_TYPE_GDK_GCVALUES_MASK (gtk_type_builtins[46]) -#define GTK_TYPE_GDK_SELECTION (gtk_type_builtins[47]) -#define GTK_TYPE_GDK_PROPERTY_STATE (gtk_type_builtins[48]) -#define GTK_TYPE_GDK_PROP_MODE (gtk_type_builtins[49]) -#define GTK_TYPE_ACCELERATOR_TABLE (gtk_type_builtins[50]) -#define GTK_TYPE_STYLE (gtk_type_builtins[51]) -#define GTK_TYPE_GDK_COLORMAP (gtk_type_builtins[52]) -#define GTK_TYPE_GDK_VISUAL (gtk_type_builtins[53]) -#define GTK_TYPE_GDK_FONT (gtk_type_builtins[54]) -#define GTK_TYPE_GDK_WINDOW (gtk_type_builtins[55]) -#define GTK_TYPE_GDK_EVENT (gtk_type_builtins[56]) -#define GTK_TYPE_GDK_COLOR (gtk_type_builtins[57]) -#define GTK_TYPE_NUM_BUILTINS 58 +#define GTK_TYPE_ACCEL_FLAGS (gtk_type_builtins[0]) +#define GTK_TYPE_ARROW_TYPE (gtk_type_builtins[1]) +#define GTK_TYPE_ATTACH_OPTIONS (gtk_type_builtins[2]) +#define GTK_TYPE_BUTTON_BOX_STYLE (gtk_type_builtins[3]) +#define GTK_TYPE_DIRECTION_TYPE (gtk_type_builtins[4]) +#define GTK_TYPE_JUSTIFICATION (gtk_type_builtins[5]) +#define GTK_TYPE_MATCH_TYPE (gtk_type_builtins[6]) +#define GTK_TYPE_MENU_FACTORY_TYPE (gtk_type_builtins[7]) +#define GTK_TYPE_METRIC_TYPE (gtk_type_builtins[8]) +#define GTK_TYPE_ORIENTATION (gtk_type_builtins[9]) +#define GTK_TYPE_PACK_TYPE (gtk_type_builtins[10]) +#define GTK_TYPE_PATH_PRIORITY_TYPE (gtk_type_builtins[11]) +#define GTK_TYPE_PATH_TYPE (gtk_type_builtins[12]) +#define GTK_TYPE_POLICY_TYPE (gtk_type_builtins[13]) +#define GTK_TYPE_POSITION_TYPE (gtk_type_builtins[14]) +#define GTK_TYPE_PREVIEW_TYPE (gtk_type_builtins[15]) +#define GTK_TYPE_RELIEF_STYLE (gtk_type_builtins[16]) +#define GTK_TYPE_SCROLL_TYPE (gtk_type_builtins[17]) +#define GTK_TYPE_SELECTION_MODE (gtk_type_builtins[18]) +#define GTK_TYPE_SHADOW_TYPE (gtk_type_builtins[19]) +#define GTK_TYPE_SIGNAL_RUN_TYPE (gtk_type_builtins[20]) +#define GTK_TYPE_STATE_TYPE (gtk_type_builtins[21]) +#define GTK_TYPE_SUBMENU_DIRECTION (gtk_type_builtins[22]) +#define GTK_TYPE_SUBMENU_PLACEMENT (gtk_type_builtins[23]) +#define GTK_TYPE_TOOLBAR_STYLE (gtk_type_builtins[24]) +#define GTK_TYPE_TROUGH_TYPE (gtk_type_builtins[25]) +#define GTK_TYPE_UPDATE_TYPE (gtk_type_builtins[26]) +#define GTK_TYPE_VISIBILITY (gtk_type_builtins[27]) +#define GTK_TYPE_WINDOW_POSITION (gtk_type_builtins[28]) +#define GTK_TYPE_WINDOW_TYPE (gtk_type_builtins[29]) +#define GTK_TYPE_OBJECT_FLAGS (gtk_type_builtins[30]) +#define GTK_TYPE_ARG_FLAGS (gtk_type_builtins[31]) +#define GTK_TYPE_WIDGET_FLAGS (gtk_type_builtins[32]) +#define GTK_TYPE_PRIVATE_FLAGS (gtk_type_builtins[33]) +#define GTK_TYPE_CURVE_TYPE (gtk_type_builtins[34]) +#define GTK_TYPE_FUNDAMENTAL_TYPE (gtk_type_builtins[35]) +#define GTK_TYPE_GDK_WINDOW_TYPE (gtk_type_builtins[36]) +#define GTK_TYPE_GDK_WINDOW_CLASS (gtk_type_builtins[37]) +#define GTK_TYPE_GDK_IMAGE_TYPE (gtk_type_builtins[38]) +#define GTK_TYPE_GDK_VISUAL_TYPE (gtk_type_builtins[39]) +#define GTK_TYPE_GDK_WINDOW_ATTRIBUTES_TYPE (gtk_type_builtins[40]) +#define GTK_TYPE_GDK_WINDOW_HINTS (gtk_type_builtins[41]) +#define GTK_TYPE_GDK_FUNCTION (gtk_type_builtins[42]) +#define GTK_TYPE_GDK_FILL (gtk_type_builtins[43]) +#define GTK_TYPE_GDK_LINE_STYLE (gtk_type_builtins[44]) +#define GTK_TYPE_GDK_CAP_STYLE (gtk_type_builtins[45]) +#define GTK_TYPE_GDK_JOIN_STYLE (gtk_type_builtins[46]) +#define GTK_TYPE_GDK_CURSOR_TYPE (gtk_type_builtins[47]) +#define GTK_TYPE_GDK_EVENT_TYPE (gtk_type_builtins[48]) +#define GTK_TYPE_GDK_EVENT_MASK (gtk_type_builtins[49]) +#define GTK_TYPE_GDK_NOTIFY_TYPE (gtk_type_builtins[50]) +#define GTK_TYPE_GDK_CROSSING_MODE (gtk_type_builtins[51]) +#define GTK_TYPE_GDK_MODIFIER_TYPE (gtk_type_builtins[52]) +#define GTK_TYPE_GDK_SUBWINDOW_MODE (gtk_type_builtins[53]) +#define GTK_TYPE_GDK_INPUT_CONDITION (gtk_type_builtins[54]) +#define GTK_TYPE_GDK_STATUS (gtk_type_builtins[55]) +#define GTK_TYPE_GDK_BYTE_ORDER (gtk_type_builtins[56]) +#define GTK_TYPE_GDK_GCVALUES_MASK (gtk_type_builtins[57]) +#define GTK_TYPE_GDK_SELECTION (gtk_type_builtins[58]) +#define GTK_TYPE_GDK_PROPERTY_STATE (gtk_type_builtins[59]) +#define GTK_TYPE_GDK_PROP_MODE (gtk_type_builtins[60]) +#define GTK_TYPE_ACCEL_GROUP (gtk_type_builtins[61]) +#define GTK_TYPE_STYLE (gtk_type_builtins[62]) +#define GTK_TYPE_GDK_COLORMAP (gtk_type_builtins[63]) +#define GTK_TYPE_GDK_VISUAL (gtk_type_builtins[64]) +#define GTK_TYPE_GDK_FONT (gtk_type_builtins[65]) +#define GTK_TYPE_GDK_WINDOW (gtk_type_builtins[66]) +#define GTK_TYPE_GDK_EVENT (gtk_type_builtins[67]) +#define GTK_TYPE_GDK_COLOR (gtk_type_builtins[68]) +#define GTK_TYPE_NUM_BUILTINS 69 diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c index 41d3d13077..5704bb487d 100644 --- a/gtk/gtktypeutils.c +++ b/gtk/gtktypeutils.c @@ -60,7 +60,9 @@ static void gtk_type_init_builtin_types (void); static GtkTypeNode *type_nodes = NULL; static guint n_type_nodes = 0; -static GHashTable *type_name_2_type_ht = NULL; +static GHashTable *type_name_2_type_ht = NULL; +static const gchar *key_enum_vals = "gtk-type-enum-values"; +static guint key_id_enum_vals = 0; static GtkTypeNode* @@ -494,6 +496,46 @@ gtk_arg_copy (GtkArg *src_arg, return dest_arg; } +GtkEnumValue* +gtk_enum_get_values (GtkType enum_type) +{ + if (gtk_type_is_a (enum_type, GTK_TYPE_ENUM) || + gtk_type_is_a (enum_type, GTK_TYPE_FLAGS)) + return g_dataset_id_get_data (gtk_type_name (enum_type), key_id_enum_vals); + + g_warning ("gtk_enum_get_values(): type `%s' is not derived from `enum' or `flags'", + gtk_type_name (enum_type)); + + return NULL; +} + +void +gtk_enum_set_values (GtkType enum_type, + GtkEnumValue *values) +{ + if (!key_id_enum_vals) + key_id_enum_vals = g_dataset_force_id (key_enum_vals); + + if (gtk_type_is_a (enum_type, GTK_TYPE_ENUM) || + gtk_type_is_a (enum_type, GTK_TYPE_FLAGS)) + { + gchar *type_name; + + type_name = gtk_type_name (enum_type); + if (g_dataset_id_get_data (type_name, key_id_enum_vals)) + g_warning ("gtk_enum_set_values(): enum values for `%s' are already set", + type_name); + else + g_dataset_id_set_data (type_name, + key_id_enum_vals, + values); + return; + } + + g_warning ("gtk_enum_set_values(): type `%s' is not derived from `enum' or `flags'", + gtk_type_name (enum_type)); +} + static void gtk_type_class_init (GtkTypeNode *node) { @@ -573,54 +615,59 @@ extern void gtk_object_init_type (void); GtkType gtk_type_builtins[GTK_TYPE_NUM_BUILTINS]; +#include "gtkwidget.h" /* include for enum values from GtkWidgetFlags */ +#include "gtkprivate.h" /* include for enum values from GtkPrivateFlags */ +#include "gtkenumvalues.c" + static void gtk_type_init_builtin_types (void) { /* GTK_TYPE_INVALID has typeid 0. The first type id returned by - gtk_type_unique is 1, which is GTK_TYPE_NONE. And so on. */ + * gtk_type_unique is 1, which is GTK_TYPE_NONE. And so on. + */ - static struct { - GtkType enum_id; + struct { + GtkType type_id; gchar *name; } fundamental_info[] = { - { GTK_TYPE_NONE, "void" }, - { GTK_TYPE_CHAR, "char" }, - { GTK_TYPE_BOOL, "bool" }, - { GTK_TYPE_INT, "int" }, - { GTK_TYPE_UINT, "uint" }, - { GTK_TYPE_LONG, "long" }, - { GTK_TYPE_ULONG, "ulong" }, - { GTK_TYPE_FLOAT, "float" }, - { GTK_TYPE_DOUBLE, "double" }, - { GTK_TYPE_STRING, "string" }, - { GTK_TYPE_ENUM, "enum" }, - { GTK_TYPE_FLAGS, "flags" }, - { GTK_TYPE_BOXED, "boxed" }, - { GTK_TYPE_FOREIGN, "foreign" }, - { GTK_TYPE_CALLBACK, "callback" }, - { GTK_TYPE_ARGS, "args" }, + { GTK_TYPE_NONE, "void" }, + { GTK_TYPE_CHAR, "char" }, + { GTK_TYPE_BOOL, "bool" }, + { GTK_TYPE_INT, "int" }, + { GTK_TYPE_UINT, "uint" }, + { GTK_TYPE_LONG, "long" }, + { GTK_TYPE_ULONG, "ulong" }, + { GTK_TYPE_FLOAT, "float" }, + { GTK_TYPE_DOUBLE, "double" }, + { GTK_TYPE_STRING, "string" }, + { GTK_TYPE_ENUM, "enum" }, + { GTK_TYPE_FLAGS, "flags" }, + { GTK_TYPE_BOXED, "boxed" }, + { GTK_TYPE_FOREIGN, "foreign" }, + { GTK_TYPE_CALLBACK, "callback" }, + { GTK_TYPE_ARGS, "args" }, - { GTK_TYPE_POINTER, "pointer" }, - { GTK_TYPE_SIGNAL, "signal" }, - { GTK_TYPE_C_CALLBACK, "c_callback" } + { GTK_TYPE_POINTER, "pointer" }, + { GTK_TYPE_SIGNAL, "signal" }, + { GTK_TYPE_C_CALLBACK, "c_callback" } }; - - static struct { - char *name; + struct { + gchar *name; GtkType parent; + GtkEnumValue *values; } builtin_info[] = { #include "gtktypebuiltins.c" { NULL } }; - - int i; + guint i; for (i = 0; i < sizeof (fundamental_info) / sizeof (fundamental_info[0]); i++) { GtkType id; + id = gtk_type_register_builtin (fundamental_info[i].name, GTK_TYPE_INVALID); - g_assert (id == fundamental_info[i].enum_id); + g_assert (id == fundamental_info[i].type_id); } gtk_object_init_type (); @@ -630,5 +677,8 @@ gtk_type_init_builtin_types (void) gtk_type_builtins[i] = gtk_type_register_builtin (builtin_info[i].name, builtin_info[i].parent); + if (gtk_type_is_a (gtk_type_builtins[i], GTK_TYPE_ENUM) || + gtk_type_is_a (gtk_type_builtins[i], GTK_TYPE_FLAGS)) + gtk_enum_set_values (gtk_type_builtins[i], builtin_info[i].values); } } diff --git a/gtk/gtktypeutils.h b/gtk/gtktypeutils.h index 2f85f2588a..87853259a5 100644 --- a/gtk/gtktypeutils.h +++ b/gtk/gtktypeutils.h @@ -78,6 +78,8 @@ extern GtkType gtk_type_builtins[]; typedef struct _GtkArg GtkArg; typedef struct _GtkObject GtkObject; /* forward declaration of object type */ typedef struct _GtkTypeInfo GtkTypeInfo; +typedef struct _GtkEnumValue GtkEnumValue; +typedef struct _GtkEnumValue GtkFlagValue; typedef void (*GtkClassInitFunc) (gpointer klass); typedef void (*GtkObjectInitFunc) (gpointer object); @@ -177,6 +179,13 @@ struct _GtkTypeInfo GtkArgGetFunc arg_get_func; }; +struct _GtkEnumValue +{ + guint value; + gchar *value_name; + gchar *value_nick; +}; + void gtk_type_init (void); GtkType gtk_type_unique (guint parent_type, @@ -206,7 +215,9 @@ void gtk_type_set_arg (GtkObject *object, guint arg_id); GtkArg* gtk_arg_copy (GtkArg *src_arg, GtkArg *dest_arg); - +GtkEnumValue *gtk_enum_get_values (GtkType enum_type); +void gtk_enum_set_values (GtkType enum_type, + GtkEnumValue*values); #ifdef __cplusplus diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 2014fcdd6a..21ff38d534 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -25,12 +25,14 @@ #include "gtksignal.h" #include "gtkwidget.h" #include "gtkwindow.h" +#include "gtkbindings.h" #include "gtkprivate.h" #include "gdk/gdk.h" #include "gdk/gdkx.h" #define WIDGET_CLASS(w) GTK_WIDGET_CLASS (GTK_OBJECT (w)->klass) +#define INIT_PATH_SIZE (512) enum { @@ -48,7 +50,7 @@ enum { STATE_CHANGED, PARENT_SET, STYLE_SET, - INSTALL_ACCELERATOR, + ADD_ACCELERATOR, REMOVE_ACCELERATOR, EVENT, BUTTON_PRESS_EVENT, @@ -144,14 +146,6 @@ static void gtk_widget_marshal_signal_1 (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args); -static void gtk_widget_marshal_signal_2 (GtkObject *object, - GtkSignalFunc func, - gpointer func_data, - GtkArg *args); -static void gtk_widget_marshal_signal_3 (GtkObject *object, - GtkSignalFunc func, - gpointer func_data, - GtkArg *args); static void gtk_widget_marshal_signal_4 (GtkObject *object, GtkSignalFunc func, gpointer func_data, @@ -417,24 +411,12 @@ gtk_widget_class_init (GtkWidgetClass *klass) gtk_widget_marshal_signal_7, GTK_TYPE_NONE, 1, GTK_TYPE_BOXED); - widget_signals[INSTALL_ACCELERATOR] = - gtk_signal_new ("install_accelerator", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GtkWidgetClass, install_accelerator), - gtk_widget_marshal_signal_2, - GTK_TYPE_BOOL, 3, - GTK_TYPE_STRING, - GTK_TYPE_CHAR, - GTK_TYPE_INT); + widget_signals[ADD_ACCELERATOR] = + gtk_accel_group_create_add (object_class->type, GTK_RUN_LAST, + GTK_SIGNAL_OFFSET (GtkWidgetClass, add_accelerator)); widget_signals[REMOVE_ACCELERATOR] = - gtk_signal_new ("remove_accelerator", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator), - gtk_widget_marshal_signal_3, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); + gtk_accel_group_create_remove (object_class->type, GTK_RUN_LAST, + GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator)); widget_signals[EVENT] = gtk_signal_new ("event", GTK_RUN_LAST, @@ -723,8 +705,8 @@ gtk_widget_class_init (GtkWidgetClass *klass) klass->state_changed = NULL; klass->parent_set = NULL; klass->style_set = gtk_widget_style_set; - klass->install_accelerator = NULL; - klass->remove_accelerator = NULL; + klass->add_accelerator = (void*) gtk_accel_group_handle_add; + klass->remove_accelerator = (void*) gtk_accel_group_handle_remove; klass->event = NULL; klass->button_press_event = NULL; klass->button_release_event = NULL; @@ -755,6 +737,16 @@ gtk_widget_class_init (GtkWidgetClass *klass) klass->drop_data_available_event = NULL; klass->other_event = NULL; klass->no_expose_event = NULL; + + /* bindings test + */ + { + GtkBindingSet *binding_set; + + binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, '9', GDK_CONTROL_MASK, "hide", 0); + gtk_binding_entry_add_signal (binding_set, '9', GDK_CONTROL_MASK, "show", 0); + } } /***************************************** @@ -1854,58 +1846,99 @@ gtk_widget_size_allocate (GtkWidget *widget, gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation); } -/***************************************** - * gtk_widget_install_accelerator: - * - * arguments: - * - * results: - *****************************************/ - void -gtk_widget_install_accelerator (GtkWidget *widget, - GtkAcceleratorTable *table, - const gchar *signal_name, - gchar key, - guint8 modifiers) +gtk_widget_add_accelerator (GtkWidget *widget, + const gchar *accel_signal, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags) { - gint return_val; + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (accel_group != NULL); + + gtk_accel_group_add (accel_group, + accel_key, + accel_mods, + accel_flags, + (GtkObject*) widget, + accel_signal); +} +void +gtk_widget_stop_accelerator (GtkWidget *widget) +{ g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); - gtk_widget_ref (widget); - return_val = TRUE; - gtk_signal_emit (GTK_OBJECT (widget), widget_signals[INSTALL_ACCELERATOR], - signal_name, key, modifiers, &return_val); - if (return_val) - gtk_accelerator_table_install (table, - GTK_OBJECT (widget), - signal_name, - key, - modifiers); - gtk_widget_unref (widget); + gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[ADD_ACCELERATOR]); } -/***************************************** - * gtk_widget_remove_accelerator: - * - * arguments: - * - * results: - *****************************************/ +void +gtk_widget_remove_accelerator (GtkWidget *widget, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (accel_group != NULL); + + gtk_accel_group_remove (accel_group, + accel_key, + accel_mods, + (GtkObject*) widget); +} void -gtk_widget_remove_accelerator (GtkWidget *widget, - GtkAcceleratorTable *table, - const gchar *signal_name) +gtk_widget_remove_accelerators (GtkWidget *widget, + const gchar *accel_signal, + gboolean visible_only) { + GSList *slist; + guint signal_id; + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (accel_signal != NULL); + + signal_id = gtk_signal_lookup (accel_signal, GTK_OBJECT_TYPE (widget)); + g_return_if_fail (signal_id != 0); + + slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget)); + while (slist) + { + GtkAccelEntry *ac_entry; + + ac_entry = slist->data; + slist = slist->next; + if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE && + ac_entry->signal_id == signal_id) + gtk_widget_remove_accelerator (GTK_WIDGET (widget), + ac_entry->accel_group, + ac_entry->accelerator_key, + ac_entry->accelerator_mods); + } +} - gtk_widget_ref (widget); - gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR], - signal_name); - gtk_accelerator_table_remove (table, GTK_OBJECT (widget), signal_name); - gtk_widget_unref (widget); +guint +gtk_widget_accelerator_signal (GtkWidget *widget, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods) +{ + GtkAccelEntry *ac_entry; + + g_return_val_if_fail (widget != NULL, 0); + g_return_val_if_fail (GTK_IS_WIDGET (widget), 0); + g_return_val_if_fail (accel_group != NULL, 0); + + ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods); + + if (ac_entry && ac_entry->object == (GtkObject*) widget) + return ac_entry->signal_id; + return 0; } /***************************************** @@ -3339,56 +3372,6 @@ gtk_widget_marshal_signal_1 (GtkObject *object, } /***************************************** - * gtk_widget_marshal_signal_2: - * - * arguments: - * - * results: - *****************************************/ - -static void -gtk_widget_marshal_signal_2 (GtkObject *object, - GtkSignalFunc func, - gpointer func_data, - GtkArg *args) -{ - GtkWidgetSignal2 rfunc; - gint *return_val; - - rfunc = (GtkWidgetSignal2) func; - return_val = GTK_RETLOC_BOOL (args[3]); - - *return_val = (* rfunc) (object, - GTK_VALUE_STRING (args[0]), - GTK_VALUE_CHAR (args[1]), - GTK_VALUE_INT (args[2]), - func_data); -} - -/***************************************** - * gtk_widget_marshal_signal_3: - * - * arguments: - * - * results: - *****************************************/ - -static void -gtk_widget_marshal_signal_3 (GtkObject *object, - GtkSignalFunc func, - gpointer func_data, - GtkArg *args) -{ - GtkWidgetSignal3 rfunc; - - rfunc = (GtkWidgetSignal3) func; - - (* rfunc) (object, - GTK_VALUE_STRING (args[0]), - func_data); -} - -/***************************************** * gtk_widget_marshal_signal_4: * * arguments: @@ -3519,7 +3502,6 @@ gtk_widget_real_destroy (GtkObject *object) gtk_grab_remove (widget); gtk_selection_remove_all (widget); - gtk_accelerator_tables_delete (object); saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id); if (saved_style) @@ -4144,3 +4126,109 @@ gtk_widget_unref (GtkWidget *widget) gtk_object_unref ((GtkObject*) widget); } + +void +gtk_widget_path (GtkWidget *widget, + guint *path_length_p, + gchar **path_p, + gchar **path_reversed_p) +{ + static gchar *rev_path = NULL; + static guint path_len = 0; + guint len; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + len = 0; + do + { + gchar *string; + gchar *d, *s; + guint l; + + string = gtk_widget_get_name (widget); + l = strlen (string); + while (path_len <= len + l + 1) + { + path_len += INIT_PATH_SIZE; + rev_path = g_realloc (rev_path, path_len); + } + s = string + l - 1; + d = rev_path + len; + while (s >= string) + *(d++) = *(s--); + len += l; + + widget = widget->parent; + + if (widget) + rev_path[len++] = '.'; + else + rev_path[len++] = 0; + } + while (widget); + + if (path_length_p) + *path_length_p = len - 1; + if (path_reversed_p) + *path_reversed_p = g_strdup (rev_path); + if (path_p) + { + *path_p = g_strdup (rev_path); + g_strreverse (*path_p); + } +} + +void +gtk_widget_class_path (GtkWidget *widget, + guint *path_length_p, + gchar **path_p, + gchar **path_reversed_p) +{ + static gchar *rev_path = NULL; + static guint path_len = 0; + guint len; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + len = 0; + do + { + gchar *string; + gchar *d, *s; + guint l; + + string = gtk_type_name (GTK_WIDGET_TYPE (widget)); + l = strlen (string); + while (path_len <= len + l + 1) + { + path_len += INIT_PATH_SIZE; + rev_path = g_realloc (rev_path, path_len); + } + s = string + l - 1; + d = rev_path + len; + while (s >= string) + *(d++) = *(s--); + len += l; + + widget = widget->parent; + + if (widget) + rev_path[len++] = '.'; + else + rev_path[len++] = 0; + } + while (widget); + + if (path_length_p) + *path_length_p = len - 1; + if (path_reversed_p) + *path_reversed_p = g_strdup (rev_path); + if (path_p) + { + *path_p = g_strdup (rev_path); + g_strreverse (*path_p); + } +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 2cfeef874c..12446033d7 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -21,7 +21,7 @@ #include <gdk/gdk.h> -#include <gtk/gtkaccelerator.h> +#include <gtk/gtkaccelgroup.h> #include <gtk/gtkobject.h> #include <gtk/gtkstyle.h> @@ -35,7 +35,7 @@ extern "C" { /* The flags that are used by GtkWidget on top of the * flags field of GtkObject. */ -enum +typedef enum { GTK_TOPLEVEL = 1 << 4, GTK_NO_WINDOW = 1 << 5, @@ -49,10 +49,9 @@ enum GTK_CAN_DEFAULT = 1 << 13, GTK_HAS_DEFAULT = 1 << 14, GTK_HAS_GRAB = 1 << 15, - GTK_BASIC = 1 << 16, - GTK_RESERVED_3 = 1 << 17, - GTK_RC_STYLE = 1 << 18 -}; + GTK_RC_STYLE = 1 << 16, + GTK_BASIC = 1 << 17 +} GtkWidgetFlags; /* Macro for casting a pointer to a GtkWidget or GtkWidgetClass pointer. @@ -259,12 +258,16 @@ struct _GtkWidgetClass GtkStyle *previous_style); /* accelerators */ - gint (* install_accelerator) (GtkWidget *widget, - const gchar *signal_name, - gchar key, - guint8 modifiers); + gint (* add_accelerator) (GtkWidget *widget, + guint accel_signal_id, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags); void (* remove_accelerator) (GtkWidget *widget, - const gchar *signal_name); + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); /* events */ gint (* event) (GtkWidget *widget, @@ -395,14 +398,24 @@ void gtk_widget_size_request (GtkWidget *widget, GtkRequisition *requisition); void gtk_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -void gtk_widget_install_accelerator (GtkWidget *widget, - GtkAcceleratorTable *table, - const gchar *signal_name, - gchar key, - guint8 modifiers); -void gtk_widget_remove_accelerator (GtkWidget *widget, - GtkAcceleratorTable *table, - const gchar *signal_name); +void gtk_widget_add_accelerator (GtkWidget *widget, + const gchar *accel_signal, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods, + GtkAccelFlags accel_flags); +void gtk_widget_stop_accelerator (GtkWidget *widget); +void gtk_widget_remove_accelerator (GtkWidget *widget, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); +void gtk_widget_remove_accelerators (GtkWidget *widget, + const gchar *accel_signal, + gboolean visible_only); +guint gtk_widget_accelerator_signal (GtkWidget *widget, + GtkAccelGroup *accel_group, + guint accel_key, + guint accel_mods); gint gtk_widget_event (GtkWidget *widget, GdkEvent *event); @@ -502,6 +515,18 @@ void gtk_widget_shape_combine_mask (GtkWidget *widget, gint offset_x, gint offset_y); +/* Compute a widget's path in the form "GtkWindow.MyLabel", and + * return newly alocated strings. + */ +void gtk_widget_path (GtkWidget *widget, + guint *path_length, + gchar **path, + gchar **path_reversed); +void gtk_widget_class_path (GtkWidget *widget, + guint *path_length, + gchar **path, + gchar **path_reversed); + /* When you get a drag_enter event, you can use this to tell Gtk of other * items that are to be dragged as well... */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index c618097d03..0af3fe0b79 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -25,6 +25,7 @@ #include "gtkrc.h" #include "gtksignal.h" #include "gtkwindow.h" +#include "gtkbindings.h" enum { MOVE_RESIZE, @@ -107,9 +108,6 @@ static void gtk_real_window_set_focus (GtkWindow *window, static gint gtk_window_move_resize (GtkWidget *widget); static void gtk_window_set_hints (GtkWidget *widget, GtkRequisition *requisition); -static gint gtk_window_check_accelerator (GtkWindow *window, - gint key, - guint mods); static void gtk_window_read_rcfiles (GtkWidget *widget, GdkEventClient *event); @@ -220,7 +218,6 @@ gtk_window_init (GtkWindow *window) window->wmclass_name = g_strdup (gdk_progname); window->wmclass_class = g_strdup (gdk_progclass); window->type = GTK_WINDOW_TOPLEVEL; - window->accelerator_tables = NULL; window->focus_widget = NULL; window->default_widget = NULL; window->resize_count = 0; @@ -397,38 +394,25 @@ gtk_window_set_policy (GtkWindow *window, } void -gtk_window_add_accelerator_table (GtkWindow *window, - GtkAcceleratorTable *table) +gtk_window_add_accel_group (GtkWindow *window, + GtkAccelGroup *accel_group) { g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); - g_return_if_fail (table != NULL); + g_return_if_fail (accel_group != NULL); - gtk_accelerator_table_ref (table); - window->accelerator_tables = g_list_prepend (window->accelerator_tables, - table); + gtk_accel_group_attach (accel_group, GTK_OBJECT (window)); } void -gtk_window_remove_accelerator_table (GtkWindow *window, - GtkAcceleratorTable *table) +gtk_window_remove_accel_group (GtkWindow *window, + GtkAccelGroup *accel_group) { - GList *list; - g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); - g_return_if_fail (table != NULL); + g_return_if_fail (accel_group != NULL); - for (list = window->accelerator_tables; list; list = list->next) - { - if (list->data == table) - { - gtk_accelerator_table_unref (table); - window->accelerator_tables = g_list_remove_link (window->accelerator_tables, list); - g_list_free_1 (list); - break; - } - } + gtk_accel_group_detach (accel_group, GTK_OBJECT (window)); } void @@ -507,18 +491,11 @@ gtk_window_marshal_signal_2 (GtkObject *object, static void gtk_window_destroy (GtkObject *object) { - GList *list; - g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_WINDOW (object)); gtk_container_unregister_toplevel (GTK_CONTAINER (object)); - for (list = GTK_WINDOW (object)->accelerator_tables; list; list = list->next) - gtk_accelerator_table_unref (list->data); - g_list_free (GTK_WINDOW (object)->accelerator_tables); - GTK_WINDOW (object)->accelerator_tables = NULL; - if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -765,7 +742,7 @@ gtk_window_key_press_event (GtkWidget *widget, { GtkWindow *window; GtkDirectionType direction = 0; - gint return_val; + gboolean handled; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE); @@ -773,14 +750,21 @@ gtk_window_key_press_event (GtkWidget *widget, window = GTK_WINDOW (widget); - return_val = FALSE; + handled = FALSE; + if (window->focus_widget) - return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event); + { + handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event); - if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state)) - return_val = TRUE; + if (!handled) + handled = gtk_bindings_activate (GTK_OBJECT (window->focus_widget), + event->keyval, event->state); + } + + if (!handled) + handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state); - if (!return_val) + if (!handled) { switch (event->keyval) { @@ -788,7 +772,7 @@ gtk_window_key_press_event (GtkWidget *widget, if (window->focus_widget) { gtk_widget_activate (window->focus_widget); - return_val = TRUE; + handled = TRUE; } break; case GDK_Return: @@ -796,12 +780,12 @@ gtk_window_key_press_event (GtkWidget *widget, if (window->default_widget) { gtk_widget_activate (window->default_widget); - return_val = TRUE; + handled = TRUE; } else if (window->focus_widget) { gtk_widget_activate (window->focus_widget); - return_val = TRUE; + handled = TRUE; } break; case GDK_Up: @@ -840,12 +824,12 @@ gtk_window_key_press_event (GtkWidget *widget, if (!GTK_CONTAINER (window)->focus_child) gtk_window_set_focus (GTK_WINDOW (widget), NULL); else - return_val = TRUE; + handled = TRUE; break; } } - return return_val; + return handled; } static gint @@ -853,18 +837,24 @@ gtk_window_key_release_event (GtkWidget *widget, GdkEventKey *event) { GtkWindow *window; - gint return_val; - + gint handled; + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + window = GTK_WINDOW (widget); - return_val = FALSE; + handled = FALSE; if (window->focus_widget) - return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event); - - return return_val; + { + handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event); + + if (!handled) + handled = gtk_bindings_activate (GTK_OBJECT (window->focus_widget), + event->keyval, event->state | GDK_AFTER_MASK); + } + + return handled; } static gint @@ -1320,30 +1310,3 @@ gtk_window_set_hints (GtkWidget *widget, } } } - -static gint -gtk_window_check_accelerator (GtkWindow *window, - gint key, - guint mods) -{ - GtkAcceleratorTable *table; - GList *tmp; - - if ((key >= 0x20) && (key <= 0xFF)) - { - tmp = window->accelerator_tables; - while (tmp) - { - table = tmp->data; - tmp = tmp->next; - - if (gtk_accelerator_table_check (table, key, mods)) - return TRUE; - } - - if (gtk_accelerator_table_check (NULL, key, mods)) - return TRUE; - } - - return FALSE; -} diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h index 5c90caf6a1..e8d3dc02ba 100644 --- a/gtk/gtkwindow.h +++ b/gtk/gtkwindow.h @@ -21,7 +21,7 @@ #include <gdk/gdk.h> -#include <gtk/gtkaccelerator.h> +#include <gtk/gtkaccelgroup.h> #include <gtk/gtkbin.h> #include <gtk/gtkenums.h> #include <gtk/gtkwidget.h> @@ -50,7 +50,6 @@ struct _GtkWindow gchar *wmclass_name; gchar *wmclass_class; GtkWindowType type; - GList *accelerator_tables; GtkWidget *focus_widget; GtkWidget *default_widget; @@ -94,10 +93,10 @@ void gtk_window_set_policy (GtkWindow *window, gint allow_shrink, gint allow_grow, gint auto_shrink); -void gtk_window_add_accelerator_table (GtkWindow *window, - GtkAcceleratorTable *table); -void gtk_window_remove_accelerator_table (GtkWindow *window, - GtkAcceleratorTable *table); +void gtk_window_add_accel_group (GtkWindow *window, + GtkAccelGroup *accel_group); +void gtk_window_remove_accel_group (GtkWindow *window, + GtkAccelGroup *accel_group); void gtk_window_position (GtkWindow *window, GtkWindowPosition position); gint gtk_window_activate_focus (GtkWindow *window); diff --git a/gtk/makeenums.awk b/gtk/makeenums.awk new file mode 100644 index 0000000000..be9df4076b --- /dev/null +++ b/gtk/makeenums.awk @@ -0,0 +1,105 @@ + +BEGIN { + in_def=0; + TI=0; + delete type_names; + delete type_nicks; + delete type_flags; + n_defs = 0; +} + +(init == 0) { + printf ("/* generated by makeenums.awk from \"%s\" */\n\n", FILENAME); + init=1; +} + +";" { + sub (";.*", ""); +} + +/\(/ { + if (in_def == 0) + { + if ($1 == "(define-enum") + { + in_def = 1; + type_flags[TI]=0; + } + else if ($1 == "(define-flags") + { + in_def = 1; + type_flags[TI]=1; + } + } + else + in_def += 1; +} + +(in_def == 1) { + VI = 0; + delete value_names; + delete value_nicks; + + type_nicks[TI] = $2; + type_names[TI] = "GTK_TYPE"; + for (i = 0; i < length(type_nicks[TI]); i++) + { + ch = substr(type_nicks[TI], i + 1, 1); + Ch = toupper(ch); + if (Ch == ch) + type_names[TI] = type_names[TI] "_" Ch; + else + type_names[TI] = type_names[TI] Ch; + } +} + +(in_def == 2) { + value_nicks[VI] = tolower ($1); + value_names[VI] = $2; + kill_pat="[^-A-z0123456789_]+"; + while (match (value_nicks[VI],kill_pat)) + sub(kill_pat,"",value_nicks[VI]); + while (match (value_names[VI],kill_pat)) + sub(kill_pat,"",value_names[VI]); +} + +/\)/ { + if (in_def > 0) + { + while (match($0,")")) + { + sub(")",""); + if (in_def == 2) + VI += 1; + if (in_def == 1) + { + TI += 1; + } + in_def -= 1; + } + + if (in_def == 0) + { + printf ("static GtkEnumValue enum_values_%s[] = {\n", type_nicks[TI-1]); + for (j = 0; value_names[j] != ""; j++) + { + printf (" { %s, \"%s\", \"%s\" },\n", + value_names[j], value_names[j], value_nicks[j]); + } + printf (" { 0, NULL, NULL },\n"); + printf ("};\n"); + } + } +} + +END { +# printf("%u{\n", TI); + for (i = 0; i < TI; i++) + { +# printf(" { %s, \"%s\", %s, %s_values },\n", +# type_names[i], type_nicks[i], +# type_flags[i] ? "TRUE" : "FALSE", +# tolower(type_nicks[i])); + } +# printf("};\n"); +} diff --git a/gtk/testgtkrc b/gtk/testgtkrc index 1615eeea69..7f5646cc37 100644 --- a/gtk/testgtkrc +++ b/gtk/testgtkrc @@ -55,7 +55,7 @@ style "toggle_button" = "button" style "text" { bg_pixmap[NORMAL] = "marble.xpm" - text[NORMAL] = { 1.0, 1.0, 1.0 } + text[NORMAL] = { 0.2, 0.2, 1.0 } fg[NORMAL] = { 1.0, 1.0, 1.0 } base[NORMAL] = { 0.0, 0.0, 0.0 } } diff --git a/tests/testgtkrc b/tests/testgtkrc index 1615eeea69..7f5646cc37 100644 --- a/tests/testgtkrc +++ b/tests/testgtkrc @@ -55,7 +55,7 @@ style "toggle_button" = "button" style "text" { bg_pixmap[NORMAL] = "marble.xpm" - text[NORMAL] = { 1.0, 1.0, 1.0 } + text[NORMAL] = { 0.2, 0.2, 1.0 } fg[NORMAL] = { 1.0, 1.0, 1.0 } base[NORMAL] = { 0.0, 0.0, 0.0 } } |