Fixed reliance on sizeof (gulong) <= sizeof (gpointer) in unix/menu.c.

This commit is contained in:
Pietro Gagliardi 2015-04-30 19:13:36 -04:00
parent 358ae23d34
commit 3673ac7d2e
1 changed files with 28 additions and 20 deletions

View File

@ -22,9 +22,12 @@ struct menuItem {
void (*onClicked)(uiMenuItem *, uiWindow *, void *); void (*onClicked)(uiMenuItem *, uiWindow *, void *);
void *onClickedData; void *onClickedData;
GtkWidget *baseItem; // template for new instances; kept in sync with everything else GtkWidget *baseItem; // template for new instances; kept in sync with everything else
GHashTable *uiWindows; // map[GtkMenuItem]uiWindow GHashTable *windows; // map[GtkMenuItem]*menuItemWindow
// TODO this assumes that a gulong can fit in a gpointer };
GHashTable *signals; // map[GtkMenuItem]gulong
struct menuItemWindow {
uiWindow *w;
gulong signal;
}; };
enum { enum {
@ -36,8 +39,6 @@ enum {
typeSeparator, typeSeparator,
}; };
#define NEWHASH() g_hash_table_new(g_direct_hash, g_direct_equal)
// we do NOT want programmatic updates to raise an ::activated signal // we do NOT want programmatic updates to raise an ::activated signal
static void singleSetChecked(GtkCheckMenuItem *menuitem, gboolean checked, gulong signal) static void singleSetChecked(GtkCheckMenuItem *menuitem, gboolean checked, gulong signal)
{ {
@ -50,25 +51,29 @@ static void setChecked(struct menuItem *item, gboolean checked)
{ {
GHashTableIter iter; GHashTableIter iter;
gpointer widget; gpointer widget;
gpointer ww;
struct menuItemWindow *w;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item->baseItem), checked); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item->baseItem), checked);
g_hash_table_iter_init(&iter, item->uiWindows); g_hash_table_iter_init(&iter, item->windows);
while (g_hash_table_iter_next(&iter, &widget, NULL)) while (g_hash_table_iter_next(&iter, &widget, &ww)) {
singleSetChecked(GTK_CHECK_MENU_ITEM(widget), checked, (gulong) g_hash_table_lookup(item->signals, widget)); w = (struct menuItemWindow *) ww;
singleSetChecked(GTK_CHECK_MENU_ITEM(widget), checked, w->signal);
}
} }
static void onClicked(GtkMenuItem *menuitem, gpointer data) static void onClicked(GtkMenuItem *menuitem, gpointer data)
{ {
struct menuItem *item = (struct menuItem *) data; struct menuItem *item = (struct menuItem *) data;
uiWindow *w; struct menuItemWindow *w;
// we need to manually update the checked states of all menu items if one changes // we need to manually update the checked states of all menu items if one changes
// notice that this is getting the checked state of the menu item that this signal is sent from // notice that this is getting the checked state of the menu item that this signal is sent from
if (item->type == typeCheckbox) if (item->type == typeCheckbox)
setChecked(item, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))); setChecked(item, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)));
w = uiWindow(g_hash_table_lookup(item->uiWindows, menuitem)); w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, menuitem);
(*(item->onClicked))(uiMenuItem(item), w, item->onClickedData); (*(item->onClicked))(uiMenuItem(item), w->w, item->onClickedData);
} }
static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data) static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data)
@ -82,7 +87,7 @@ static void menuItemEnableDisable(struct menuItem *item, gboolean enabled)
gpointer widget; gpointer widget;
gtk_widget_set_sensitive(item->baseItem, enabled); gtk_widget_set_sensitive(item->baseItem, enabled);
g_hash_table_iter_init(&iter, item->uiWindows); g_hash_table_iter_init(&iter, item->windows);
while (g_hash_table_iter_next(&iter, &widget, NULL)) while (g_hash_table_iter_next(&iter, &widget, NULL))
gtk_widget_set_sensitive(GTK_WIDGET(widget), enabled); gtk_widget_set_sensitive(GTK_WIDGET(widget), enabled);
} }
@ -170,8 +175,7 @@ static uiMenuItem *newItem(struct menu *m, int type, const char *name)
break; break;
} }
item->uiWindows = NEWHASH(); item->windows = g_hash_table_new(g_direct_hash, g_direct_equal);
item->signals = NEWHASH();
uiMenuItem(item)->Enable = menuItemEnable; uiMenuItem(item)->Enable = menuItemEnable;
uiMenuItem(item)->Disable = menuItemDisable; uiMenuItem(item)->Disable = menuItemDisable;
@ -253,6 +257,7 @@ static void appendMenuItem(GtkMenuShell *submenu, struct menuItem *item, uiWindo
{ {
GtkWidget *menuitem; GtkWidget *menuitem;
gulong signal; gulong signal;
struct menuItemWindow *ww;
menuitem = g_object_new(G_OBJECT_TYPE(item->baseItem), NULL); menuitem = g_object_new(G_OBJECT_TYPE(item->baseItem), NULL);
if (item->name != NULL) if (item->name != NULL)
@ -264,8 +269,10 @@ static void appendMenuItem(GtkMenuShell *submenu, struct menuItem *item, uiWindo
singleSetChecked(GTK_CHECK_MENU_ITEM(menuitem), gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item->baseItem)), signal); singleSetChecked(GTK_CHECK_MENU_ITEM(menuitem), gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item->baseItem)), signal);
} }
gtk_menu_shell_append(submenu, menuitem); gtk_menu_shell_append(submenu, menuitem);
g_hash_table_insert(item->uiWindows, menuitem, w); ww = uiNew(struct menuItemWindow);
g_hash_table_insert(item->signals, menuitem, (gpointer) signal); ww->w = w;
ww->signal = signal;
g_hash_table_insert(item->windows, menuitem, ww);
} }
// TODO should this return a zero-height widget (or NULL) if there are no menus defined? // TODO should this return a zero-height widget (or NULL) if there are no menus defined?
@ -305,12 +312,13 @@ static void freeMenuItem(GtkWidget *widget, gpointer data)
{ {
struct freeMenuItemData *fmi = (struct freeMenuItemData *) data; struct freeMenuItemData *fmi = (struct freeMenuItemData *) data;
struct menuItem *item; struct menuItem *item;
struct menuItemWindow *w;
item = g_array_index(fmi->items, struct menuItem *, fmi->i); item = g_array_index(fmi->items, struct menuItem *, fmi->i);
if (g_hash_table_remove(item->uiWindows, widget) == FALSE) w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, widget);
complain("GtkMenuItem %p not in menu items uiWindows map", widget); if (g_hash_table_remove(item->windows, widget) == FALSE)
if (g_hash_table_remove(item->signals, widget) == FALSE) complain("GtkMenuItem %p not in menu item's item/window map", widget);
complain("GtkMenuItem %p not in menu items signals map", widget); uiFree(w);
fmi->i++; fmi->i++;
} }