diff options
author | Cody Russell <bratsche@gnome.org> | 2010-05-06 12:38:23 +0200 |
---|---|---|
committer | Cody Russell <bratsche@gnome.org> | 2010-05-06 12:38:23 +0200 |
commit | dd70103f39aab0509760406fe2ccc6f1bce6f755 (patch) | |
tree | c50b2ad8931e173672726c18310c93e503b215fb | |
parent | 227d59c19015d488eda2895c1022b95ac1463d2a (diff) | |
download | gtk+-menuproxy.tar.gz |
Abstract GtkMenuProxy type module work in progress.menuproxy
-rw-r--r-- | gtk/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/gtk.h | 2 | ||||
-rw-r--r-- | gtk/gtkmenuproxy.c | 133 | ||||
-rw-r--r-- | gtk/gtkmenuproxy.h | 69 | ||||
-rw-r--r-- | gtk/gtkmenuproxymodule.c | 239 | ||||
-rw-r--r-- | gtk/gtkmenuproxymodule.h | 69 | ||||
-rw-r--r-- | gtk/gtkmenushell.c | 15 | ||||
-rw-r--r-- | gtk/tests/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/tests/menuproxy.c | 278 |
9 files changed, 813 insertions, 0 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index ce39a1c6b4..92b6bac0d4 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -252,6 +252,8 @@ gtk_public_h_sources = \ gtkmenu.h \ gtkmenubar.h \ gtkmenuitem.h \ + gtkmenuproxy.h \ + gtkmenuproxymodule.h \ gtkmenushell.h \ gtkmenutoolbutton.h \ gtkmessagedialog.h \ @@ -520,6 +522,8 @@ gtk_base_c_sources = \ gtkmenu.c \ gtkmenubar.c \ gtkmenuitem.c \ + gtkmenuproxy.c \ + gtkmenuproxymodule.c \ gtkmenushell.c \ gtkmenutoolbutton.c \ gtkmessagedialog.c \ @@ -65,6 +65,8 @@ #include <gtk/gtkcellview.h> #include <gtk/gtkcheckbutton.h> #include <gtk/gtkcheckmenuitem.h> +#include <gtk/gtkmenuproxy.h> +#include <gtk/gtkmenuproxymodule.h> #include <gtk/gtkclipboard.h> #include <gtk/gtkcolorbutton.h> #include <gtk/gtkcolorsel.h> diff --git a/gtk/gtkmenuproxy.c b/gtk/gtkmenuproxy.c new file mode 100644 index 0000000000..72ff2e1ea6 --- /dev/null +++ b/gtk/gtkmenuproxy.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Authors: Cody Russell <bratsche@gnome.org> + */ + +#include "config.h" +#include "gtkintl.h" +#include "gtkmarshalers.h" +#include "gtkmenuproxy.h" +#include "gtkmenuproxymodule.h" +#include "gtkmodules.h" +#include "gtkalias.h" + +enum { + INSERTED, + LAST_SIGNAL +}; + +static guint menu_proxy_signals[LAST_SIGNAL] = { 0 }; +static GObjectClass *parent_class = NULL; +static GtkMenuProxy *proxy_singleton = NULL; + +static void gtk_menu_proxy_real_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position); + + + +/* --------------------------------------------------------- */ + +G_DEFINE_TYPE (GtkMenuProxy, gtk_menu_proxy, G_TYPE_OBJECT) + +static GObject * +gtk_menu_proxy_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + + if (proxy_singleton != NULL) + { + object = g_object_ref (proxy_singleton); + } + else + { + object = G_OBJECT_CLASS (gtk_menu_proxy_parent_class)->constructor (type, + n_params, + params); + + proxy_singleton = GTK_MENU_PROXY (object); + g_object_add_weak_pointer (object, (gpointer) &proxy_singleton); + } + + return object; +} + +static void +gtk_menu_proxy_init (GtkMenuProxy *proxy) +{ +} + +static void +gtk_menu_proxy_class_init (GtkMenuProxyClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + menu_proxy_signals[INSERTED] = + g_signal_new (I_("inserted"), + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkMenuProxyClass, inserted), + NULL, NULL, + _gtk_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, 2, + GTK_TYPE_WIDGET, G_TYPE_UINT); + + class->insert = gtk_menu_proxy_real_insert; + + object_class->constructor = gtk_menu_proxy_constructor; +} + +GtkMenuProxy * +gtk_menu_proxy_get (void) +{ + if (!proxy_singleton) + { + gtk_menu_proxy_module_get (); + } + + return proxy_singleton; +} + +static void +gtk_menu_proxy_real_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position) +{ +} + +void +gtk_menu_proxy_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position) +{ + g_return_if_fail (GTK_IS_MENU_PROXY (proxy)); + + GTK_MENU_PROXY_GET_CLASS (proxy)->insert (proxy, + child, + position); + + //g_signal_emit_by_name (proxy, "inserted", child, position); +} + +#define __GTK_MENU_PROXY_C__ +#include "gtkaliasdef.c" diff --git a/gtk/gtkmenuproxy.h b/gtk/gtkmenuproxy.h new file mode 100644 index 0000000000..b8fb93d097 --- /dev/null +++ b/gtk/gtkmenuproxy.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Authors: Cody Russell <bratsche@gnome.org> + */ + +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only <gtk/gtk.h> can be included directly." +#endif + +#ifndef __GTK_MENU_PROXY_H__ +#define __GTK_MENU_PROXY_H__ + +#include <gtk/gtkwidget.h> +#include <gtk/gtktypeutils.h> + +G_BEGIN_DECLS + +#define GTK_TYPE_MENU_PROXY (gtk_menu_proxy_get_type ()) +#define GTK_MENU_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_MENU_PROXY, GtkMenuProxy)) +#define GTK_MENU_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_MENU_PROXY, GtkMenuProxyClass)) +#define GTK_IS_MENU_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_MENU_PROXY)) +#define GTK_IS_MENU_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_MENU_PROXY)) +#define GTK_MENU_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_MENU_PROXY, GtkMenuProxyClass)) + + +typedef struct _GtkMenuProxy GtkMenuProxy; +typedef struct _GtkMenuProxyClass GtkMenuProxyClass; + +struct _GtkMenuProxy +{ + GObject parent_object; +}; + +struct _GtkMenuProxyClass +{ + GObjectClass parent_class; + + /* vtable */ + void (* insert) (GtkMenuProxy *proxy, GtkWidget *child, guint position); + + /* signals */ + void (* inserted) (GtkMenuProxy *proxy, GtkWidget *child); +}; + +GType gtk_menu_proxy_get_type (void) G_GNUC_CONST; +GtkMenuProxy* gtk_menu_proxy_get (void); +void gtk_menu_proxy_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position); + +G_END_DECLS + +#endif /* __GTK_MENU_PROXY_H__ */ diff --git a/gtk/gtkmenuproxymodule.c b/gtk/gtkmenuproxymodule.c new file mode 100644 index 0000000000..5aaf6c0aa5 --- /dev/null +++ b/gtk/gtkmenuproxymodule.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Authors: Cody Russell <bratsche@gnome.org> + */ + +#include "config.h" +#include "gtkintl.h" +#include "gtkmenuproxy.h" +#include "gtkmenuproxymodule.h" +#include "gtkmodules.h" +#include "gtkalias.h" + +enum { + PROP_0, + PROP_MODULENAME +}; + +static GObject *gtk_menu_proxy_module_constructor (GType type, + guint n_params, + GObjectConstructParam *params); +static void gtk_menu_proxy_module_finalize (GObject *object); +static gboolean gtk_menu_proxy_module_real_load (GTypeModule *gmodule); +static void gtk_menu_proxy_module_real_unload (GTypeModule *gmodule); + + +G_DEFINE_TYPE (GtkMenuProxyModule, gtk_menu_proxy_module, G_TYPE_TYPE_MODULE); + +static GtkMenuProxyModule *proxy_module_singleton = NULL; + +static void +gtk_menu_proxy_module_class_init (GtkMenuProxyModuleClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class); + + //object_class->constructor = gtk_menu_proxy_module_constructor; + object_class->finalize = gtk_menu_proxy_module_finalize; + + type_module_class->load = gtk_menu_proxy_module_real_load; + type_module_class->unload = gtk_menu_proxy_module_real_unload; +} + +/* +static GObject * +gtk_menu_proxy_module_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + + if (proxy_module_singleton != NULL) + { + object = g_object_ref (proxy_module_singleton); + } + else + { + object = G_OBJECT_CLASS (gtk_menu_proxy_module_parent_class)->constructor (type, + n_params, + params); + + proxy_module_singleton = GTK_MENU_PROXY_MODULE (object); + g_object_add_weak_pointer (object, (gpointer) &proxy_module_singleton); + } + + return object; +} +*/ + +static void +gtk_menu_proxy_module_init (GtkMenuProxyModule *module) +{ + module->name = g_strdup (g_getenv ("GTK_MENUPROXY")); + module->library = NULL; + module->load = NULL; + module->unload = NULL; +} + +static void +gtk_menu_proxy_module_finalize (GObject *object) +{ + GtkMenuProxyModule *module = GTK_MENU_PROXY_MODULE (object); + + if (module->name != NULL) + { + g_free (module->name); + } + + G_OBJECT_CLASS (gtk_menu_proxy_module_parent_class)->finalize (object); +} + +static gboolean +gtk_menu_proxy_module_real_load (GTypeModule *gmodule) +{ + GtkMenuProxyModule *module = GTK_MENU_PROXY_MODULE (gmodule); + gchar *path; + + if (proxy_module_singleton != NULL) + return TRUE; + + if (!module->name) + { + g_warning ("Module path not set"); + return FALSE; + } + + path = _gtk_find_module (module->name, "menuproxies"); + + module->library = g_module_open (path, 0); + + if (!module->library) + { + g_printerr ("%s\n", g_module_error ()); + return FALSE; + } + + /* Make sure that the loaded library contains the required methods */ + if (!g_module_symbol (module->library, + "menu_proxy_module_load", + (gpointer *) &module->load) || + !g_module_symbol (module->library, + "menu_proxy_module_unload", + (gpointer *) &module->unload)) + { + g_printerr ("%s\n", g_module_error ()); + g_module_close (module->library); + + return FALSE; + } + + /* Initialize the loaded module */ + module->load (module); + + return TRUE; +} + +static void +gtk_menu_proxy_module_real_unload (GTypeModule *gmodule) +{ + GtkMenuProxyModule *module = GTK_MENU_PROXY_MODULE (gmodule); + + module->unload (module); + + g_module_close (module->library); + module->library = NULL; + + module->load = NULL; + module->unload = NULL; +} + +static gboolean +is_valid_module_name (const gchar *name) +{ +#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN) + return g_str_has_prefix (name, "lib") && g_str_has_suffix (name, ".so"); +#else + return g_str_has_suffix (name, ".dll"); +#endif +} + +static void +setup_instance (GtkMenuProxyModule *module) +{ + GType *proxy_types; + guint n_proxies; + + proxy_types = g_type_children (GTK_TYPE_MENU_PROXY, + &n_proxies); + + if (n_proxies > 1) + { + g_warning ("There are %d child types of GtkMenuProxy, should be 0 or 1.\n", + n_proxies); + } + else if (n_proxies == 1) + { + g_object_new (proxy_types[0], NULL); + } +} + +GtkMenuProxyModule * +gtk_menu_proxy_module_get (void) +{ + if (!proxy_module_singleton) + { + GtkMenuProxyModule *module = NULL; + const gchar *module_name; + + module_name = g_getenv ("GTK_MENUPROXY"); + + if (module_name != NULL) + { + if (is_valid_module_name (module_name)) + { + gchar *path = _gtk_find_module (module_name, "menuproxies"); + + module = g_object_new (GTK_TYPE_MENU_PROXY_MODULE, + NULL); + + if (!g_type_module_use (G_TYPE_MODULE (module))) + { + g_warning ("Failed to load type module: %s\n", path); + + g_object_unref (module); + g_free (path); + + return NULL; + } + + setup_instance (module); + + g_free (path); + g_type_module_unuse (G_TYPE_MODULE (module)); + } + + proxy_module_singleton = module; + } + } + + return proxy_module_singleton; +} + +#define __GTK_MENU_PROXY_MODULE_C__ +#include "gtkaliasdef.c" diff --git a/gtk/gtkmenuproxymodule.h b/gtk/gtkmenuproxymodule.h new file mode 100644 index 0000000000..83898ea5da --- /dev/null +++ b/gtk/gtkmenuproxymodule.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Authors: Cody Russell <bratsche@gnome.org> + */ + +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only <gtk/gtk.h> can be included directly." +#endif + +#ifndef __GTK_MENU_PROXY_MODULE_H__ +#define __GTK_MENU_PROXY_MODULE_H__ + +#include <glib-object.h> +#include <gmodule.h> + +G_BEGIN_DECLS + +#define GTK_TYPE_MENU_PROXY_MODULE (gtk_menu_proxy_module_get_type ()) +#define GTK_MENU_PROXY_MODULE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_MENU_PROXY_MODULE, GtkMenuProxyModule)) +#define GTK_MENU_PROXY_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_MENU_PROXY_MODULE, GtkMenuProxyModuleClass)) +#define GTK_IS_MENU_MODULE_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_MENU_PROXY_MODULE)) +#define GTK_IS_MENU_PROXY_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_MENU_PROXY_MODULE)) +#define GTK_MENU_PROXY_MODULE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_MENU_PROXY_MODULE, GtkMenuProxyModuleClass)) + +typedef struct _GtkMenuProxyModule GtkMenuProxyModule; +typedef struct _GtkMenuProxyModuleClass GtkMenuProxyModuleClass; +typedef struct _GtkMenuProxyModulePrivate GtkMenuProxyModulePrivate; + +struct _GtkMenuProxyModule +{ + GTypeModule parent_instance; + + GtkMenuProxyModulePrivate *priv; + + GModule *library; + gchar *name; + + void (* load) (GtkMenuProxyModule *module); + void (* unload) (GtkMenuProxyModule *module); +}; + +struct _GtkMenuProxyModuleClass +{ + GTypeModuleClass parent_class; +}; + +GType gtk_menu_proxy_module_get_type (void) G_GNUC_CONST; + +GtkMenuProxyModule *gtk_menu_proxy_module_get (void); + +G_END_DECLS + +#endif /* __GTK_MENU_PROXY_MODULE_H__ */ diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index c3e107fa1c..def6aa2c93 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -37,6 +37,7 @@ #include "gtkmenubar.h" #include "gtkmenuitem.h" #include "gtkmenushell.h" +#include "gtkmenuproxy.h" #include "gtkmnemonichash.h" #include "gtktearoffmenuitem.h" #include "gtkwindow.h" @@ -135,6 +136,8 @@ struct _GtkMenuShellPrivate GtkMnemonicHash *mnemonic_hash; GtkKeyHash *key_hash; + GtkMenuProxy *proxy; + guint take_focus : 1; guint activated_submenu : 1; /* This flag is a crutch to keep mnemonics in the same menu @@ -408,6 +411,8 @@ gtk_menu_shell_init (GtkMenuShell *menu_shell) priv->key_hash = NULL; priv->take_focus = TRUE; priv->activated_submenu = FALSE; + priv->proxy = gtk_menu_proxy_get (); + //priv->proxy = gtk_menu_proxy_factory_get_proxy (); } static void @@ -483,12 +488,22 @@ gtk_menu_shell_insert (GtkMenuShell *menu_shell, gint position) { GtkMenuShellClass *class; + GtkMenuShellPrivate *priv; g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (GTK_IS_MENU_ITEM (child)); class = GTK_MENU_SHELL_GET_CLASS (menu_shell); + priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell); + + // XXX + // insert to proxy + if (priv->proxy != NULL) + gtk_menu_proxy_insert (priv->proxy, + child, + position); + if (class->insert) class->insert (menu_shell, child, position); } diff --git a/gtk/tests/Makefile.am b/gtk/tests/Makefile.am index d257f2b316..f9a3a7a4f0 100644 --- a/gtk/tests/Makefile.am +++ b/gtk/tests/Makefile.am @@ -47,6 +47,10 @@ TEST_PROGS += recentmanager recentmanager_SOURCES = recentmanager.c recentmanager_LDADD = $(progs_ldadd) +TEST_PROGS += menuproxy +menuproxy_SOURCES = menuproxy.c +menuproxy_LDADD = $(progs_ldadd) + TEST_PROGS += floating floating_SOURCES = floating.c floating_LDADD = $(progs_ldadd) diff --git a/gtk/tests/menuproxy.c b/gtk/tests/menuproxy.c new file mode 100644 index 0000000000..cabfdbb6ab --- /dev/null +++ b/gtk/tests/menuproxy.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2009 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Authors: Cody Russell <bratsche@gnome.org> + */ + +#undef GTK_DISABLE_DEPRECATED +#include "../gtk/gtk.h" + +typedef struct _TestProxy TestProxy; +typedef struct _TestProxyClass TestProxyClass; + +//static GType test_proxy_type_id = 0; +//static TestProxyClass *test_proxy_parent_class = NULL; + +#define TEST_TYPE_PROXY (test_proxy_type_id) +#define TEST_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_PROXY, TestProxy)) +#define TEST_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TEST_TYPE_PROXY, TestProxyClass)) +#define TEST_IS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TEST_TYPE_PROXY)) + +struct _TestProxy +{ + GtkMenuProxy parent_object; +}; + +struct _TestProxyClass +{ + GtkMenuProxyClass parent_class; +}; + +static void test_proxy_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position); + +G_DEFINE_DYNAMIC_TYPE(TestProxy, test_proxy, GTK_TYPE_MENU_PROXY) + +static void +test_proxy_init (TestProxy *proxy) +{ +} + +static void +test_proxy_class_init (TestProxyClass *class) +{ + GtkMenuProxyClass *proxy_class = GTK_MENU_PROXY_CLASS (class); + + test_proxy_parent_class = g_type_class_peek_parent (class); + + proxy_class->insert = test_proxy_insert; +} + +static void +test_proxy_class_finalize (TestProxyClass *class) +{ +} + +static void +test_proxy_insert (GtkMenuProxy *proxy, + GtkWidget *child, + guint position) +{ +} + +/* ---------------------------------------------------- */ + +#define TEST_TYPE_MODULE (test_module_get_type ()) +#define TEST_MODULE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_MODULE, TestModule)) +#define TEST_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TEST_TYPE_MODULE, TestModuleClass)) +#define TEST_IS_MODULE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TEST_TYPE_MODULE)) +#define TEST_IS_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TEST_TYPE_MODULE)) +#define TEST_MODULE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TEST_TYPE_MODULE, TestModuleClass)) + + +typedef struct _TestModule TestModule; +typedef struct _TestModuleClass TestModuleClass; + +struct _TestModule +{ + GTypeModule parent_instance; +}; + +struct _TestModuleClass +{ + GTypeModuleClass parent_class; +}; + +static gboolean +test_module_load (GTypeModule *module) +{ + g_print ("registering type...\n"); + g_print (" type_id = %d\n", test_proxy_type_id); + + test_proxy_register_type (G_TYPE_MODULE (module)); + + //test_proxy_get_type (G_TYPE_MODULE (module)); + + g_print (" type_id = %d\n", test_proxy_type_id); + + return TRUE; +} + +static void +test_module_unload (GTypeModule *module) +{ +} + +static void +test_module_class_init (TestModuleClass *class) +{ + GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class); + + type_module_class->load = test_module_load; + type_module_class->unload = test_module_unload; +} + +static void +test_module_init (TestModule *module) +{ +} + +G_DEFINE_TYPE (TestModule, test_module, G_TYPE_TYPE_MODULE); + +TestModule * +test_module_new (void) +{ + TestModule *module = g_object_new (TEST_TYPE_MODULE, + NULL); + + g_print ("test_module_new(): %p\n", module); + + return module; +} + + +/* ---------------------------------------------------- */ + +static void +non_null_proxy_test (void) +{ + GtkMenuProxyModule *module; + + /* prevent the module loader from finding a proxy module */ + g_unsetenv ("GTK_MENUPROXY"); + + module = gtk_menu_proxy_module_get (); + test_proxy_register_type (G_TYPE_MODULE (module)); + //test_proxy_get_type (G_TYPE_MODULE (module)); + + GtkWidget *widget = g_object_new (GTK_TYPE_MENU_BAR, NULL); + g_object_ref_sink (widget); + + g_assert (GTK_IS_MENU_BAR (widget)); + //g_assert (GTK_MENU_SHELL (widget)->proxy != NULL); + + g_object_unref (widget); +} + +static void +null_proxy_test (void) +{ + GtkWidget *widget = g_object_new (GTK_TYPE_MENU_BAR, NULL); + g_object_ref_sink (widget); + + g_assert (GTK_IS_MENU_BAR (widget)); + + //g_assert (GTK_MENU_SHELL (widget)->proxy == NULL); + + g_object_unref (widget); +} + +static gboolean inserted_called = FALSE; + +static void +inserted_cb (GtkMenuProxy *proxy, + GtkWidget *child, + guint position, + gpointer data) +{ + g_return_if_fail (GTK_IS_MENU_PROXY (proxy)); + g_return_if_fail (GTK_IS_WIDGET (child)); + inserted_called = TRUE; +} + +static void +menubar_signals_proxy_test (void) +{ + GtkWidget *widget = NULL; + GtkWidget *menuitem = NULL; + GtkMenuProxy *proxy; + + //gtk_menu_proxy_register_type (test_proxy_get_type ()); + + widget = g_object_new (GTK_TYPE_MENU_BAR, NULL); + g_object_ref_sink (widget); + + g_assert (GTK_IS_MENU_BAR (widget)); + //g_assert (GTK_MENU_SHELL (widget)->proxy != NULL); + + /* + proxy = GTK_MENU_SHELL (widget)->proxy; + + g_signal_connect (proxy, + "inserted", G_CALLBACK (inserted_cb), + NULL); + */ + + // insert menuitem + menuitem = gtk_menu_item_new_with_label ("Test Item"); + gtk_menu_shell_append (GTK_MENU_SHELL (widget), + menuitem); + + g_assert (inserted_called == TRUE); + + g_object_unref (widget); +} + +static void +proxy_type_exists_test (void) +{ +#if 0 + GtkMenuProxyModule *module; + + g_unsetenv ("GTK_MENUPROXY"); + + module = gtk_menu_proxy_module_get (); + test_proxy_get_type (G_TYPE_MODULE (module)); +#endif + + g_assert (gtk_menu_proxy_get_type () != 0); +} + +static void +can_instantiate_test (void) +{ + TestModule *module = test_module_new (); + + g_type_module_use (G_TYPE_MODULE (module)); + + GtkMenuProxy *proxy = gtk_menu_proxy_get (); + + g_assert (proxy != NULL); + + g_object_ref_sink (proxy); + + g_assert (TEST_IS_PROXY (proxy)); + g_assert (GTK_IS_MENU_PROXY (proxy)); + + g_object_unref (proxy); +} + +int +main (int argc, char *argv[]) +{ + gtk_test_init (&argc, &argv); + + g_test_add_func ("/proxy/null-proxy", null_proxy_test); + g_test_add_func ("/proxy/type-exists", proxy_type_exists_test); + g_test_add_func ("/proxy/can-instantiate", can_instantiate_test); + g_test_add_func ("/proxy/non-null-proxy", non_null_proxy_test); + g_test_add_func ("/proxy/menubar-signals-proxy", menubar_signals_proxy_test); + + return g_test_run(); +} |