+static GHashTable *menu_hash = NULL;
+GHashTable *menu_map = NULL;
+
+#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask | \
+ LeaveWindowMask)
+#define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask)
+#define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+ ButtonPressMask | ButtonReleaseMask)
+
+void menu_control_show(Menu *self, int x, int y, Client *client);
+
+void menu_destroy_hash_key(gpointer data)
+{
+ g_free(data);
+}
+
+void menu_destroy_hash_value(Menu *self)
+{
+ GList *it;
+
+ for (it = self->entries; it; it = it->next)
+ menu_entry_free(it->data);
+ g_list_free(self->entries);
+
+ g_free(self->label);
+ g_free(self->name);
+
+ g_hash_table_remove(menu_map, &self->title);
+ g_hash_table_remove(menu_map, &self->frame);
+ g_hash_table_remove(menu_map, &self->items);
+
+ stacking_remove(self);
+
+ appearance_free(self->a_title);
+ XDestroyWindow(ob_display, self->title);
+ XDestroyWindow(ob_display, self->frame);
+ XDestroyWindow(ob_display, self->items);
+
+ g_free(self);
+}
+
+void menu_entry_free(MenuEntry *self)
+{
+ g_free(self->label);
+ action_free(self->action);
+
+ g_hash_table_remove(menu_map, &self->item);
+
+ appearance_free(self->a_item);
+ appearance_free(self->a_disabled);
+ appearance_free(self->a_hilite);
+ XDestroyWindow(ob_display, self->item);
+
+ g_free(self);
+}
+
+void menu_startup()
+{
+ Menu *m;
+ Menu *s;
+ Menu *t;
+ Action *a;
+
+ menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ menu_destroy_hash_key,
+ (GDestroyNotify)menu_destroy_hash_value);
+ menu_map = g_hash_table_new(g_int_hash, g_int_equal);
+
+ m = menu_new(NULL, "root", NULL);
+
+ a = action_from_string("execute");
+ a->data.execute.path = g_strdup("xterm");
+ menu_add_entry(m, menu_entry_new("xterm", a));
+ a = action_from_string("restart");
+ menu_add_entry(m, menu_entry_new("restart", a));
+ menu_add_entry(m, menu_entry_new_separator("--"));
+ a = action_from_string("exit");
+ menu_add_entry(m, menu_entry_new("exit", a));
+ s = menu_new("subsex menu", "submenu", m);
+ a = action_from_string("execute");
+ a->data.execute.path = g_strdup("xclock");
+ menu_add_entry(s, menu_entry_new("xclock", a));
+
+ menu_add_entry(m, menu_entry_new_submenu("subz", s));
+
+ /*
+ t = (Menu *)plugin_create("timed_menu");
+ a = action_from_string("execute");
+ a->data.execute.path = g_strdup("xeyes");
+ menu_add_entry(t, menu_entry_new("xeyes", a));
+ menu_add_entry(m, menu_entry_new_submenu("timed", t));
+ */
+
+ s = menu_new("empty", "chub", m);
+ menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+ s = menu_new("", "s-club", m);
+ menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+ s = menu_new(NULL, "h-club", m);
+ menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+ s = menu_new(NULL, "g-club", m);
+
+ a = action_from_string("execute");
+ a->data.execute.path = g_strdup("xterm");
+ menu_add_entry(s, menu_entry_new("xterm", a));
+ a = action_from_string("restart");
+ menu_add_entry(s, menu_entry_new("restart", a));
+ menu_add_entry(s, menu_entry_new_separator("--"));
+ a = action_from_string("exit");
+ menu_add_entry(s, menu_entry_new("exit", a));
+
+ menu_add_entry(m, menu_entry_new_submenu("long", s));
+
+ m = menu_new(NULL, "client", NULL);
+ a = action_from_string("iconify");
+ menu_add_entry(m, menu_entry_new("iconify", a));
+ a = action_from_string("toggleshade");
+ menu_add_entry(m, menu_entry_new("(un)shade", a));
+ a = action_from_string("togglemaximizefull");
+ menu_add_entry(m, menu_entry_new("(un)maximize", a));
+ a = action_from_string("close");
+ menu_add_entry(m, menu_entry_new("close", a));
+
+}
+
+void menu_shutdown()
+{
+ g_hash_table_destroy(menu_hash);
+ g_hash_table_destroy(menu_map);
+}
+
+static Window createWindow(Window parent, unsigned long mask,
+ XSetWindowAttributes *attrib)