fix for using freed memory to exec stuff

This commit is contained in:
Dana Jansens 2003-08-28 17:15:10 +00:00
parent 5efc7236a6
commit 9e85e930da
4 changed files with 56 additions and 38 deletions

View file

@ -12,7 +12,9 @@
#include "misc.h"
#include "parser/parse.h"
GHashTable *menu_hash = NULL;
static GHashTable *menu_hash = NULL;
ObParseInst *menu_parse_inst;
typedef struct _ObMenuParseState ObMenuParseState;
@ -129,69 +131,80 @@ void menu_startup(ObParseInst *i)
{
menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
(GDestroyNotify)menu_destroy_hash_value);
menu_parse_inst = parse_startup();
}
void menu_shutdown()
{
parse_shutdown(menu_parse_inst);
menu_parse_inst = NULL;
menu_frame_hide_all();
g_hash_table_destroy(menu_hash);
menu_hash = NULL;
}
gboolean menu_open(gchar *file, xmlDocPtr *doc, xmlNodePtr *node)
{
gboolean loaded = TRUE;
gchar *p;
p = g_build_filename(g_get_home_dir(), ".openbox", file, NULL);
if (!parse_load(p, "openbox_menu", doc, node)) {
g_free(p);
p = g_build_filename(RCDIR, file, NULL);
if (!parse_load(p, "openbox_menu", doc, node)) {
g_free(p);
p = g_strdup(file);
if (!parse_load(p, "openbox_menu", doc, node)) {
g_warning("Failed to load menu from '%s'", file);
loaded = FALSE;
}
}
}
g_free(p);
return loaded;
}
void menu_parse()
{
ObParseInst *i;
ObMenuParseState parse_state;
xmlDocPtr doc;
xmlNodePtr node;
gchar *p;
gboolean loaded = FALSE;
GSList *it;
i = parse_startup();
for (it = config_menu_files; it; it = g_slist_next(it)) {
if (menu_open(it->data, &doc, &node))
loaded = TRUE;
if (config_menu_path)
if (!(loaded =
parse_load(config_menu_path, "openbox_menu", &doc, &node)))
g_warning("Failed to load menu from '%s'", config_menu_path);
if (!loaded) {
p = g_build_filename(g_get_home_dir(), ".openbox", "menu", NULL);
if (!(loaded =
parse_load(p, "openbox_menu", &doc, &node)))
g_warning("Failed to load menu from '%s'", p);
g_free(p);
}
if (!loaded) {
p = g_build_filename(RCDIR, "menu", NULL);
if (!(loaded =
parse_load(p, "openbox_menu", &doc, &node)))
g_warning("Failed to load menu from '%s'", p);
g_free(p);
}
if (!loaded)
loaded = menu_open("menu", &doc, &node);
if (loaded) {
parse_state.menus = NULL;
parse_register(i, "menu", parse_menu, &parse_state);
parse_register(i, "item", parse_menu_item, &parse_state);
parse_register(i, "separator", parse_menu_separator, &parse_state);
parse_tree(i, doc, node->xmlChildrenNode);
parse_register(menu_parse_inst, "menu", parse_menu, &parse_state);
parse_register(menu_parse_inst, "item", parse_menu_item, &parse_state);
parse_register(menu_parse_inst, "separator",
parse_menu_separator, &parse_state);
parse_tree(menu_parse_inst, doc, node->xmlChildrenNode);
}
parse_shutdown(i);
}
gboolean menu_new(gchar *name, gchar *title, gpointer data)
{
ObMenu *self;
if (g_hash_table_lookup(menu_hash, name)) return FALSE;
/*if (g_hash_table_lookup(menu_hash, name)) return FALSE;*/
self = g_new0(ObMenu, 1);
self->name = g_strdup(name);
self->title = g_strdup(title);
self->data = data;
g_hash_table_insert(menu_hash, self->name, self);
g_hash_table_replace(menu_hash, self->name, self);
return TRUE;
}

View file

@ -20,11 +20,10 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntryFrame *frame,
gpointer data);
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
extern GList *menu_visible;
extern ObParseInst *menu_parse_inst;
struct _ObMenu
{

View file

@ -572,16 +572,22 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
{
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
/* grab all this shizzle, cuz when the menu gets hidden, 'self'
gets freed */
ObMenuEntry *entry = self->entry;
ObMenuExecuteFunc func = self->frame->menu->execute_func;
gpointer data = self->frame->menu->data;
GSList *acts = self->entry->data.normal.actions;
/* release grabs before executing the shit */
menu_frame_hide_all();
if (self->frame->menu->execute_func)
self->frame->menu->execute_func(self, self->frame->menu->data);
if (func)
func(entry, data);
else {
GSList *it;
for (it = self->entry->data.normal.actions; it;
it = g_slist_next(it))
for (it = acts; it; it = g_slist_next(it))
{
ObAction *act = it->data;
act->data.any.c = self->frame->client;

View file

@ -60,11 +60,11 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
/* executes it without changing the client in the actions, since we set that
when we make the actions! */
static void desk_menu_execute(ObMenuEntryFrame *self, gpointer data)
static void desk_menu_execute(ObMenuEntry *self, gpointer data)
{
GSList *it;
for (it = self->entry->data.normal.actions; it; it = g_slist_next(it))
for (it = self->data.normal.actions; it; it = g_slist_next(it))
{
ObAction *act = it->data;
act->func(&act->data);