tUse our GtkItemFactory even on non-Win32 systems - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 407fd240b1d9ecce669deaa14fac7c82c0490799
(DIR) parent 2182939206935c97309c8656cfdd140a1cf696da
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Thu, 19 Nov 2020 22:23:01 -0800
Use our GtkItemFactory even on non-Win32 systems
GtkItemFactory has been removed from GTK+3, but we
already have an implementation in gtkport for Win32
systems. Adapt this to work on Unix too, so we don't
have to rework the setup of our menus for GTK+3.
Diffstat:
M src/gtkport/Makefile.am | 3 ++-
M src/gtkport/gtkport.c | 224 -------------------------------
M src/gtkport/gtkport.h | 41 ++-----------------------------
A src/gtkport/itemfactory.c | 290 +++++++++++++++++++++++++++++++
A src/gtkport/itemfactory.h | 93 +++++++++++++++++++++++++++++++
M src/gui_client/gtk_client.c | 66 ++++++++++++++++----------------
6 files changed, 420 insertions(+), 297 deletions(-)
---
(DIR) diff --git a/src/gtkport/Makefile.am b/src/gtkport/Makefile.am
t@@ -1,5 +1,6 @@
noinst_LIBRARIES = libgtkport.a
libgtkport_a_SOURCES = gtkport.c gtkport.h clist.c clist.h gtkenums.h \
- unicodewrap.c unicodewrap.h treeview.h treeview.c
+ unicodewrap.c unicodewrap.h treeview.h treeview.c \
+ itemfactory.c itemfactory.h
AM_CPPFLAGS= -I../../intl -I${srcdir} -I${srcdir}/.. -I../.. @GTK_CFLAGS@ @GLIB_CFLAGS@
DEFS = @DEFS@
(DIR) diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c
t@@ -254,13 +254,6 @@ struct _OurSource {
};
typedef struct _OurSource OurSource;
-typedef struct _GtkItemFactoryChild GtkItemFactoryChild;
-
-struct _GtkItemFactoryChild {
- gchar *path;
- GtkWidget *widget;
-};
-
static GtkSignalType GtkObjectSignals[] = {
{"create", gtk_marshal_VOID__VOID, NULL},
{"", NULL, NULL}
t@@ -274,10 +267,6 @@ static GtkClass GtkAdjustmentClass = {
"adjustment", &GtkObjectClass, sizeof(GtkAdjustment), NULL, NULL
};
-static GtkClass GtkItemFactoryClass = {
- "itemfactory", &GtkObjectClass, sizeof(GtkItemFactory), NULL, NULL
-};
-
static GtkSignalType GtkWidgetSignals[] = {
{"create", gtk_marshal_VOID__VOID, gtk_widget_create},
{"size_request", gtk_marshal_VOID__GPOIN, NULL},
t@@ -3641,210 +3630,6 @@ guint gtk_signal_connect_object(GtkObject *object, const gchar *name,
return 0;
}
-GtkItemFactory *gtk_item_factory_new(GtkType container_type,
- const gchar *path,
- GtkAccelGroup *accel_group)
-{
- GtkItemFactory *new_fac;
-
- new_fac = (GtkItemFactory *)GtkNewObject(&GtkItemFactoryClass);
- new_fac->path = g_strdup(path);
- new_fac->accel_group = accel_group;
- new_fac->top_widget = gtk_menu_bar_new();
- new_fac->translate_func = NULL;
- return new_fac;
-}
-
-static gint PathCmp(const gchar *path1, const gchar *path2)
-{
- gint Match = 1;
-
- if (!path1 || !path2)
- return 0;
-
- while (*path1 && *path2 && Match) {
- while (*path1 == '_')
- path1++;
- while (*path2 == '_')
- path2++;
- if (*path1 == *path2) {
- path1++;
- path2++;
- } else
- Match = 0;
- }
- if (*path1 || *path2)
- Match = 0;
- return Match;
-}
-
-static gchar *TransPath(GtkItemFactory *ifactory, gchar *path)
-{
- gchar *transpath = NULL;
-
- if (ifactory->translate_func) {
- transpath =
- (*ifactory->translate_func) (path, ifactory->translate_data);
- }
-
- return transpath ? transpath : path;
-}
-
-static void gtk_item_factory_parse_path(GtkItemFactory *ifactory,
- gchar *path,
- GtkItemFactoryChild **parent,
- GString *menu_title)
-{
- GSList *list;
- GtkItemFactoryChild *child;
- gchar *root, *pt, *transpath;
-
- transpath = TransPath(ifactory, path);
- pt = strrchr(transpath, '/');
- if (pt)
- g_string_assign(menu_title, pt + 1);
-
- pt = strrchr(path, '/');
- if (!pt)
- return;
- root = g_strdup(path);
- root[pt - path] = '\0';
-
- for (list = ifactory->children; list; list = g_slist_next(list)) {
- child = (GtkItemFactoryChild *)list->data;
- if (PathCmp(child->path, root) == 1) {
- *parent = child;
- break;
- }
- }
- g_free(root);
-}
-
-static gboolean gtk_item_factory_parse_accel(GtkItemFactory *ifactory,
- gchar *accelerator,
- GString *menu_title,
- ACCEL *accel)
-{
- gchar *apt;
-
- if (!accelerator)
- return FALSE;
-
- apt = accelerator;
- accel->fVirt = 0;
- accel->key = 0;
- accel->cmd = 0;
-
- g_string_append(menu_title, "\t");
-
- if (strncmp(apt, "<control>", 9) == 0) {
- accel->fVirt |= FCONTROL;
- g_string_append(menu_title, "Ctrl+");
- apt += 9;
- }
-
- if (strlen(apt) == 1) {
- g_string_append_c(menu_title, *apt);
- accel->key = *apt;
- accel->fVirt |= FVIRTKEY;
- } else if (strcmp(apt, "F1") == 0) {
- g_string_append(menu_title, apt);
- accel->fVirt |= FVIRTKEY;
- accel->key = VK_F1;
- }
- return (accel->key != 0);
-}
-
-void gtk_item_factory_create_item(GtkItemFactory *ifactory,
- GtkItemFactoryEntry *entry,
- gpointer callback_data,
- guint callback_type)
-{
- GtkItemFactoryChild *new_child, *parent = NULL;
- GString *menu_title;
- GtkWidget *menu_item, *menu;
- ACCEL accel;
- gboolean haveaccel;
-
- new_child = g_new0(GtkItemFactoryChild, 1);
-
- new_child->path = g_strdup(entry->path);
-
- menu_title = g_string_new("");
-
- gtk_item_factory_parse_path(ifactory, new_child->path, &parent,
- menu_title);
- haveaccel =
- gtk_item_factory_parse_accel(ifactory, entry->accelerator,
- menu_title, &accel);
-
- menu_item = gtk_menu_item_new_with_label(menu_title->str);
- if (entry->item_type && strcmp(entry->item_type, "<CheckItem>") == 0) {
- GTK_CHECK_MENU_ITEM(menu_item)->check = 1;
- }
- new_child->widget = menu_item;
- if (entry->callback) {
- gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
- entry->callback, callback_data);
- }
-
- if (parent) {
- menu = GTK_WIDGET(GTK_MENU_ITEM(parent->widget)->submenu);
- if (!menu) {
- menu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent->widget), menu);
- }
- gtk_menu_append(GTK_MENU(menu), menu_item);
- } else {
- gtk_menu_bar_append(GTK_MENU_BAR(ifactory->top_widget), menu_item);
- }
-
- if (haveaccel && ifactory->accel_group) {
- GTK_MENU_ITEM(menu_item)->accelind =
- gtk_accel_group_add(ifactory->accel_group, &accel);
- }
-
- g_string_free(menu_title, TRUE);
-
- ifactory->children = g_slist_append(ifactory->children, new_child);
-}
-
-void gtk_item_factory_create_items(GtkItemFactory *ifactory,
- guint n_entries,
- GtkItemFactoryEntry *entries,
- gpointer callback_data)
-{
- gint i;
-
- for (i = 0; i < n_entries; i++) {
- gtk_item_factory_create_item(ifactory, &entries[i], callback_data, 0);
- }
-}
-
-GtkWidget *gtk_item_factory_get_widget(GtkItemFactory *ifactory,
- const gchar *path)
-{
- gint root_len;
- GSList *list;
- GtkItemFactoryChild *child;
-
- root_len = strlen(ifactory->path);
- if (!path || strlen(path) < root_len)
- return NULL;
-
- if (strncmp(ifactory->path, path, root_len) != 0)
- return NULL;
- if (strlen(path) == root_len)
- return ifactory->top_widget;
-
- for (list = ifactory->children; list; list = g_slist_next(list)) {
- child = (GtkItemFactoryChild *)list->data;
- if (PathCmp(child->path, &path[root_len]) == 1)
- return child->widget;
- }
- return NULL;
-}
-
void gtk_menu_shell_insert(GtkMenuShell *menu_shell, GtkWidget *child,
gint position)
{
t@@ -4534,15 +4319,6 @@ void gtk_accel_group_destroy(GtkAccelGroup *accel_group)
g_free(accel_group);
}
-void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory,
- GtkTranslateFunc func,
- gpointer data,
- GtkDestroyNotify notify)
-{
- ifactory->translate_func = func;
- ifactory->translate_data = data;
-}
-
void gtk_widget_grab_default(GtkWidget *widget)
{
GTK_WIDGET_SET_FLAGS(widget, GTK_IS_DEFAULT);
(DIR) diff --git a/src/gtkport/gtkport.h b/src/gtkport/gtkport.h
t@@ -27,6 +27,8 @@
#include <config.h>
#endif
+#include "itemfactory.h"
+
#ifdef CYGWIN
/* GTK+ emulation prototypes etc. for Win32 platform */
t@@ -60,7 +62,6 @@ extern HICON mainIcon;
#define GDK_KP_9 0xFFB9
typedef gint (*GtkFunction) (gpointer data);
-typedef gchar *(*GtkTranslateFunc) (const gchar *path, gpointer func_data);
typedef void (*GtkDestroyNotify) (gpointer data);
#define GTK_VISIBLE 1
t@@ -75,7 +76,6 @@ typedef struct _GtkSignalType GtkSignalType;
typedef struct _GtkContainer GtkContainer;
typedef void (*GtkSignalFunc) ();
-typedef void (*GtkItemFactoryCallback) ();
typedef void (*GtkSignalMarshaller) (GtkObject *object, GSList *actions,
GtkSignalFunc default_action,
va_list args);
t@@ -298,26 +298,6 @@ typedef struct _GtkHBox GtkHBox;
typedef struct _GtkVBox GtkVBox;
typedef struct _GtkNotebookChild GtkNotebookChild;
typedef struct _GtkNotebook GtkNotebook;
-typedef struct _GtkItemFactoryEntry GtkItemFactoryEntry;
-typedef struct _GtkItemFactory GtkItemFactory;
-
-struct _GtkItemFactoryEntry {
- gchar *path;
- gchar *accelerator;
- GtkItemFactoryCallback callback;
- guint callback_action;
- gchar *item_type;
-};
-
-struct _GtkItemFactory {
- GtkObject object;
- GSList *children;
- gchar *path;
- GtkAccelGroup *accel_group;
- GtkWidget *top_widget;
- GtkTranslateFunc translate_func;
- gpointer translate_data;
-};
struct _GtkBoxChild {
GtkWidget *widget;
t@@ -525,19 +505,6 @@ GtkWidget *gtk_entry_new();
void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible);
GtkWidget *gtk_table_new(guint rows, guint cols, gboolean homogeneous);
void gtk_table_resize(GtkTable *table, guint rows, guint cols);
-GtkItemFactory *gtk_item_factory_new(GtkType container_type,
- const gchar *path,
- GtkAccelGroup *accel_group);
-void gtk_item_factory_create_item(GtkItemFactory *ifactory,
- GtkItemFactoryEntry *entry,
- gpointer callback_data,
- guint callback_type);
-void gtk_item_factory_create_items(GtkItemFactory *ifactory,
- guint n_entries,
- GtkItemFactoryEntry *entries,
- gpointer callback_data);
-GtkWidget *gtk_item_factory_get_widget(GtkItemFactory *ifactory,
- const gchar *path);
GSList *gtk_radio_button_group(GtkRadioButton *radio_button);
void gtk_editable_insert_text(GtkEditable *editable, const gchar *new_text,
gint new_text_length, gint *position);
t@@ -631,10 +598,6 @@ void gtk_object_set_data(GtkObject *object, const gchar *key,
gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
GtkAccelGroup *gtk_accel_group_new();
void gtk_accel_group_destroy(GtkAccelGroup *accel_group);
-void gtk_item_factory_set_translate_func(GtkItemFactory *ifactory,
- GtkTranslateFunc func,
- gpointer data,
- GtkDestroyNotify notify);
void gtk_widget_grab_default(GtkWidget *widget);
void gtk_widget_grab_focus(GtkWidget *widget);
void gtk_window_set_modal(GtkWindow *window, gboolean modal);
(DIR) diff --git a/src/gtkport/itemfactory.c b/src/gtkport/itemfactory.c
t@@ -0,0 +1,290 @@
+/************************************************************************
+ * itemfactory.c GtkItemFactory and friends for Unix/Win32 *
+ * Copyright (C) 1998-2020 Ben Webb *
+ * Email: benwebb@users.sf.net *
+ * WWW: https://dopewars.sourceforge.io/ *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program 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 General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
+ * MA 02111-1307, USA. *
+ ************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gtkport.h"
+
+/* No need to reimplement functions if we have GTK+2 */
+#if defined(CYGWIN) || GTK_MAJOR_VERSION > 2
+
+#ifdef CYGWIN
+
+#define OurAccel ACCEL
+
+#else
+typedef struct _OurAccel OurAccel;
+struct _OurAccel {
+ guint key;
+ GdkModifierType mods;
+ GtkAccelFlags flags;
+};
+#endif
+
+typedef struct _DPGtkItemFactoryChild DPGtkItemFactoryChild;
+
+struct _DPGtkItemFactoryChild {
+ gchar *path;
+ GtkWidget *widget;
+};
+
+DPGtkItemFactory *dp_gtk_item_factory_new(GtkType container_type,
+ const gchar *path,
+ GtkAccelGroup *accel_group)
+{
+ DPGtkItemFactory *new_fac;
+
+ new_fac = g_new0(DPGtkItemFactory, 1);
+ new_fac->path = g_strdup(path);
+ new_fac->accel_group = accel_group;
+ new_fac->top_widget = gtk_menu_bar_new();
+ new_fac->translate_func = NULL;
+ return new_fac;
+}
+
+static gint PathCmp(const gchar *path1, const gchar *path2)
+{
+ gint Match = 1;
+
+ if (!path1 || !path2)
+ return 0;
+
+ while (*path1 && *path2 && Match) {
+ while (*path1 == '_')
+ path1++;
+ while (*path2 == '_')
+ path2++;
+ if (*path1 == *path2) {
+ path1++;
+ path2++;
+ } else
+ Match = 0;
+ }
+ if (*path1 || *path2)
+ Match = 0;
+ return Match;
+}
+
+static gchar *TransPath(DPGtkItemFactory *ifactory, gchar *path)
+{
+ gchar *transpath = NULL;
+
+ if (ifactory->translate_func) {
+ transpath =
+ (*ifactory->translate_func) (path, ifactory->translate_data);
+ }
+
+ return transpath ? transpath : path;
+}
+
+static void gtk_item_factory_parse_path(DPGtkItemFactory *ifactory,
+ gchar *path,
+ DPGtkItemFactoryChild **parent,
+ GString *menu_title)
+{
+ GSList *list;
+ DPGtkItemFactoryChild *child;
+ gchar *root, *pt, *transpath;
+
+ transpath = TransPath(ifactory, path);
+ pt = strrchr(transpath, '/');
+ if (pt)
+ g_string_assign(menu_title, pt + 1);
+
+ pt = strrchr(path, '/');
+ if (!pt)
+ return;
+ root = g_strdup(path);
+ root[pt - path] = '\0';
+
+ for (list = ifactory->children; list; list = g_slist_next(list)) {
+ child = (DPGtkItemFactoryChild *)list->data;
+ if (PathCmp(child->path, root) == 1) {
+ *parent = child;
+ break;
+ }
+ }
+ g_free(root);
+}
+
+static gboolean gtk_item_factory_parse_accel(DPGtkItemFactory *ifactory,
+ gchar *accelerator,
+ GString *menu_title,
+ OurAccel *accel)
+{
+ gchar *apt;
+
+ if (!accelerator)
+ return FALSE;
+
+ apt = accelerator;
+#ifdef CYGWIN
+ accel->fVirt = 0;
+ accel->key = 0;
+ accel->cmd = 0;
+ g_string_append(menu_title, "\t");
+#else
+ accel->key = 0;
+ accel->mods = 0;
+ accel->flags = GTK_ACCEL_VISIBLE;
+#endif
+
+ if (strncmp(apt, "<control>", 9) == 0) {
+#ifdef CYGWIN
+ accel->fVirt |= FCONTROL;
+ g_string_append(menu_title, "Ctrl+");
+#else
+ accel->mods |= GDK_CONTROL_MASK;
+#endif
+ apt += 9;
+ }
+
+ if (strlen(apt) == 1) {
+ accel->key = *apt;
+#ifdef CYGWIN
+ g_string_append_c(menu_title, *apt);
+ accel->fVirt |= FVIRTKEY;
+#endif
+ } else if (strcmp(apt, "F1") == 0) {
+#ifdef CYGWIN
+ g_string_append(menu_title, apt);
+ accel->fVirt |= FVIRTKEY;
+ accel->key = VK_F1;
+#else
+ accel->key = GDK_KEY_F1;
+#endif
+ }
+ return (accel->key != 0);
+}
+
+void dp_gtk_item_factory_create_item(DPGtkItemFactory *ifactory,
+ DPGtkItemFactoryEntry *entry,
+ gpointer callback_data,
+ guint callback_type)
+{
+ DPGtkItemFactoryChild *new_child, *parent = NULL;
+ GString *menu_title;
+ GtkWidget *menu_item, *menu;
+ OurAccel accel;
+ gboolean haveaccel;
+
+ new_child = g_new0(DPGtkItemFactoryChild, 1);
+
+ new_child->path = g_strdup(entry->path);
+
+ menu_title = g_string_new("");
+
+ gtk_item_factory_parse_path(ifactory, new_child->path, &parent,
+ menu_title);
+ haveaccel =
+ gtk_item_factory_parse_accel(ifactory, entry->accelerator,
+ menu_title, &accel);
+
+ if (entry->item_type && strcmp(entry->item_type, "<CheckItem>") == 0) {
+ menu_item = gtk_check_menu_item_new_with_mnemonic(menu_title->str);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), TRUE);
+ } else {
+ menu_item = gtk_menu_item_new_with_mnemonic(menu_title->str);
+ if (entry->item_type && strcmp(entry->item_type, "<LastBranch>") == 0) {
+ gtk_menu_item_set_right_justified(GTK_MENU_ITEM(menu_item), TRUE);
+ }
+ }
+ new_child->widget = menu_item;
+ if (entry->callback) {
+ gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
+ entry->callback, callback_data);
+ }
+
+ if (parent) {
+ menu = GTK_WIDGET(GTK_MENU_ITEM(parent->widget)->submenu);
+ if (!menu) {
+ menu = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent->widget), menu);
+ }
+ gtk_menu_append(GTK_MENU(menu), menu_item);
+ } else {
+ gtk_menu_bar_append(GTK_MENU_BAR(ifactory->top_widget), menu_item);
+ }
+
+ if (haveaccel && ifactory->accel_group) {
+#ifdef CYGWIN
+ GTK_MENU_ITEM(menu_item)->accelind =
+ gtk_accel_group_add(ifactory->accel_group, &accel);
+#else
+ gtk_widget_add_accelerator(menu_item, "activate", ifactory->accel_group,
+ accel.key, accel.mods, accel.flags);
+#endif
+ }
+
+ g_string_free(menu_title, TRUE);
+
+ ifactory->children = g_slist_append(ifactory->children, new_child);
+}
+
+void dp_gtk_item_factory_create_items(DPGtkItemFactory *ifactory,
+ guint n_entries,
+ DPGtkItemFactoryEntry *entries,
+ gpointer callback_data)
+{
+ gint i;
+
+ for (i = 0; i < n_entries; i++) {
+ dp_gtk_item_factory_create_item(ifactory, &entries[i], callback_data, 0);
+ }
+}
+
+GtkWidget *dp_gtk_item_factory_get_widget(DPGtkItemFactory *ifactory,
+ const gchar *path)
+{
+ gint root_len;
+ GSList *list;
+ DPGtkItemFactoryChild *child;
+
+ root_len = strlen(ifactory->path);
+ if (!path || strlen(path) < root_len)
+ return NULL;
+
+ if (strncmp(ifactory->path, path, root_len) != 0)
+ return NULL;
+ if (strlen(path) == root_len)
+ return ifactory->top_widget;
+
+ for (list = ifactory->children; list; list = g_slist_next(list)) {
+ child = (DPGtkItemFactoryChild *)list->data;
+ if (PathCmp(child->path, &path[root_len]) == 1)
+ return child->widget;
+ }
+ return NULL;
+}
+
+void dp_gtk_item_factory_set_translate_func(DPGtkItemFactory *ifactory,
+ DPGtkTranslateFunc func,
+ gpointer data,
+ GtkDestroyNotify notify)
+{
+ ifactory->translate_func = func;
+ ifactory->translate_data = data;
+}
+
+#endif /* defined(CYGWIN) || GTK_MAJOR_VERSION > 2 */
(DIR) diff --git a/src/gtkport/itemfactory.h b/src/gtkport/itemfactory.h
t@@ -0,0 +1,93 @@
+/************************************************************************
+ * itemfactory.h GtkItemFactory and friends for Unix/Win32 *
+ * Copyright (C) 1998-2020 Ben Webb *
+ * Email: benwebb@users.sf.net *
+ * WWW: https://dopewars.sourceforge.io/ *
+ * *
+ * When using GTK+3, which has removed GtkItemFactory, or Win32, *
+ * provide our own implementation; on GTK+2, use the implementation in *
+ * GTK+ itself. *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program 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 General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
+ * MA 02111-1307, USA. *
+ ************************************************************************/
+
+#ifndef __ITEM_FACTORY_H__
+#define __ITEM_FACTORY_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+/* Use GTK+2's own implementation of these functions */
+#if GTK_MAJOR_VERSION == 2
+#define DPGtkTranslateFunc GtkTranslateFunc
+#define DPGtkItemFactoryCallback GtkItemFactoryCallback
+#define DPGtkItemFactoryEntry GtkItemFactoryEntry
+#define DPGtkItemFactory GtkItemFactory
+#define dp_gtk_item_factory_new gtk_item_factory_new
+#define dp_gtk_item_factory_create_items gtk_item_factory_create_items
+#define dp_gtk_item_factory_create_item gtk_item_factory_create_item
+#define dp_gtk_item_factory_get_widget gtk_item_factory_get_widget
+#define dp_gtk_item_factory_set_translate_func gtk_item_factory_set_translate_func
+#else
+
+typedef gchar *(*DPGtkTranslateFunc) (const gchar *path, gpointer func_data);
+
+typedef void (*DPGtkItemFactoryCallback) ();
+
+typedef struct _DPGtkItemFactoryEntry DPGtkItemFactoryEntry;
+typedef struct _DPGtkItemFactory DPGtkItemFactory;
+
+struct _DPGtkItemFactoryEntry {
+ gchar *path;
+ gchar *accelerator;
+ DPGtkItemFactoryCallback callback;
+ guint callback_action;
+ gchar *item_type;
+};
+
+struct _DPGtkItemFactory {
+ GSList *children;
+ gchar *path;
+ GtkAccelGroup *accel_group;
+ GtkWidget *top_widget;
+ DPGtkTranslateFunc translate_func;
+ gpointer translate_data;
+};
+
+DPGtkItemFactory *dp_gtk_item_factory_new(GtkType container_type,
+ const gchar *path,
+ GtkAccelGroup *accel_group);
+void dp_gtk_item_factory_create_item(DPGtkItemFactory *ifactory,
+ DPGtkItemFactoryEntry *entry,
+ gpointer callback_data,
+ guint callback_type);
+void dp_gtk_item_factory_create_items(DPGtkItemFactory *ifactory,
+ guint n_entries,
+ DPGtkItemFactoryEntry *entries,
+ gpointer callback_data);
+GtkWidget *dp_gtk_item_factory_get_widget(DPGtkItemFactory *ifactory,
+ const gchar *path);
+void dp_gtk_item_factory_set_translate_func(DPGtkItemFactory *ifactory,
+ DPGtkTranslateFunc func,
+ gpointer data,
+ GtkDestroyNotify notify);
+#endif /* GTK+2 */
+
+#endif /* __ITEM_FACTORY_H__ */
(DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
t@@ -67,7 +67,7 @@ struct StatusWidgets {
struct ClientDataStruct {
GtkWidget *window, *messages;
Player *Play;
- GtkItemFactory *Menu;
+ DPGtkItemFactory *Menu;
struct StatusWidgets Status;
struct InventoryWidgets Drug, Gun, InvenDrug, InvenGun;
GtkWidget *JetButton, *vbox, *PlayerList, *TalkList;
t@@ -157,7 +157,7 @@ static void CreateInventory(GtkWidget *hbox, gchar *Objects,
static void GetSpyReports(GtkWidget *widget, gpointer data);
static void DisplaySpyReports(Player *Play);
-static GtkItemFactoryEntry menu_items[] = {
+static DPGtkItemFactoryEntry menu_items[] = {
/* The names of the the menus and their items in the GTK+ client */
{N_("/_Game"), NULL, NULL, 0, "<Branch>"},
{N_("/Game/_New..."), "<control>N", NewGame, 0, NULL},
t@@ -287,8 +287,8 @@ void ToggleSound(GtkWidget *widget, gpointer data)
{
gboolean enable;
- widget = gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Game/Enable sound");
+ widget = dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Game/Enable sound");
if (widget) {
enable = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
SoundEnable(enable);
t@@ -539,8 +539,8 @@ void HandleClientMessage(char *pt, Player *Play)
SoundPlay(Sounds.Jet);
break;
case C_ENDLIST:
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Errands/Sack Bitch...");
+ MenuItem = dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Errands/Sack Bitch...");
/* Text for the Errands/Sack Bitch menu item */
text = dpg_strdup_printf(_("%/Sack Bitch menu item/S_ack %Tde..."),
t@@ -548,8 +548,8 @@ void HandleClientMessage(char *pt, Player *Play)
SetAccelerator(MenuItem, text, NULL, NULL, NULL, FALSE);
g_free(text);
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Errands/Spy...");
+ MenuItem = dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Errands/Spy...");
/* Text to update the Errands/Spy menu item with the price for spying */
text = dpg_strdup_printf(_("_Spy (%P)"), Prices.Spy);
t@@ -559,8 +559,8 @@ void HandleClientMessage(char *pt, Player *Play)
/* Text to update the Errands/Tipoff menu item with the price for a
tipoff */
text = dpg_strdup_printf(_("_Tipoff (%P)"), Prices.Tipoff);
- MenuItem = gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Errands/Tipoff...");
+ MenuItem = dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Errands/Tipoff...");
SetAccelerator(MenuItem, text, NULL, NULL, NULL, FALSE);
g_free(text);
if (FirstClient->next)
t@@ -2032,33 +2032,33 @@ void UpdateMenus(void)
MultiPlayer = (FirstClient && FirstClient->next != NULL);
Bitches = InGame && ClientData.Play ? ClientData.Play->Bitches.Carried : 0;
- gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Talk"),
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Talk"),
InGame && Network);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/Game/Options..."),
!InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/Game/Abandon..."),
InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/List/Inventory..."),
InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/List/Players..."),
InGame && Network);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/Errands"), InGame);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/Errands/Spy..."),
InGame && MultiPlayer);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu, "<main>/Errands/Tipoff..."),
InGame && MultiPlayer);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu,
"<main>/Errands/Sack Bitch..."), Bitches > 0);
- gtk_widget_set_sensitive(gtk_item_factory_get_widget
+ gtk_widget_set_sensitive(dp_gtk_item_factory_get_widget
(ClientData.Menu,
"<main>/Errands/Get spy reports..."), InGame
&& MultiPlayer);
t@@ -2191,7 +2191,7 @@ gboolean GtkLoop(int *argc, char **argv[],
GtkWidget *window, *vbox, *vbox2, *hbox, *frame, *table, *menubar, *text,
*vpaned, *button, *clist, *widget;
GtkAccelGroup *accel_group;
- GtkItemFactory *item_factory;
+ DPGtkItemFactory *item_factory;
gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
#ifdef CYGWIN
t@@ -2256,24 +2256,24 @@ gboolean GtkLoop(int *argc, char **argv[],
accel_group = gtk_accel_group_new();
gtk_object_set_data(GTK_OBJECT(window), "accel_group", accel_group);
- item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR,
- "<main>",
- accel_group);
- gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL,
- NULL);
-
- gtk_item_factory_create_items(item_factory, nmenu_items, menu_items,
- NULL);
+ item_factory = ClientData.Menu = dp_gtk_item_factory_new(GTK_TYPE_MENU_BAR,
+ "<main>",
+ accel_group);
+ dp_gtk_item_factory_set_translate_func(item_factory, MenuTranslate, NULL,
+ NULL);
+
+ dp_gtk_item_factory_create_items(item_factory, nmenu_items, menu_items,
+ NULL);
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
- menubar = gtk_item_factory_get_widget(item_factory, "<main>");
+ menubar = dp_gtk_item_factory_get_widget(item_factory, "<main>");
vbox2 = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox2), menubar, FALSE, FALSE, 0);
gtk_widget_show_all(menubar);
UpdateMenus();
SoundEnable(UseSounds);
- widget = gtk_item_factory_get_widget(ClientData.Menu,
- "<main>/Game/Enable sound");
+ widget = dp_gtk_item_factory_get_widget(ClientData.Menu,
+ "<main>/Game/Enable sound");
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), UseSounds);
vbox = ClientData.vbox = gtk_vbox_new(FALSE, 5);