[gtk+/menuproxy] Abstract GtkMenuProxy type module work in progress.



commit dd70103f39aab0509760406fe2ccc6f1bce6f755
Author: Cody Russell <bratsche gnome org>
Date:   Thu May 6 12:38:23 2010 +0200

    Abstract GtkMenuProxy type module work in progress.

 gtk/Makefile.am          |    4 +
 gtk/gtk.h                |    2 +
 gtk/gtkmenuproxy.c       |  133 ++++++++++++++++++++++
 gtk/gtkmenuproxy.h       |   69 ++++++++++++
 gtk/gtkmenuproxymodule.c |  239 +++++++++++++++++++++++++++++++++++++++
 gtk/gtkmenuproxymodule.h |   69 ++++++++++++
 gtk/gtkmenushell.c       |   15 +++
 gtk/tests/Makefile.am    |    4 +
 gtk/tests/menuproxy.c    |  278 ++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 813 insertions(+), 0 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ce39a1c..92b6bac 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	\
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 63e96d5..86ae7cc 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -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 0000000..72ff2e1
--- /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 0000000..b8fb93d
--- /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 0000000..5aaf6c0
--- /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 0000000..83898ea
--- /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 c3e107f..def6aa2 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 d257f2b..f9a3a7a 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 0000000..cabfdbb
--- /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();
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]