fix for using freed memory to exec stuff
This commit is contained in:
parent
5efc7236a6
commit
9e85e930da
4 changed files with 56 additions and 38 deletions
|
@ -12,7 +12,9 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "parser/parse.h"
|
#include "parser/parse.h"
|
||||||
|
|
||||||
GHashTable *menu_hash = NULL;
|
static GHashTable *menu_hash = NULL;
|
||||||
|
|
||||||
|
ObParseInst *menu_parse_inst;
|
||||||
|
|
||||||
typedef struct _ObMenuParseState ObMenuParseState;
|
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,
|
menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
|
||||||
(GDestroyNotify)menu_destroy_hash_value);
|
(GDestroyNotify)menu_destroy_hash_value);
|
||||||
|
menu_parse_inst = parse_startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_shutdown()
|
void menu_shutdown()
|
||||||
{
|
{
|
||||||
|
parse_shutdown(menu_parse_inst);
|
||||||
|
menu_parse_inst = NULL;
|
||||||
|
|
||||||
menu_frame_hide_all();
|
menu_frame_hide_all();
|
||||||
g_hash_table_destroy(menu_hash);
|
g_hash_table_destroy(menu_hash);
|
||||||
menu_hash = NULL;
|
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()
|
void menu_parse()
|
||||||
{
|
{
|
||||||
ObParseInst *i;
|
|
||||||
ObMenuParseState parse_state;
|
ObMenuParseState parse_state;
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
gchar *p;
|
|
||||||
gboolean loaded = FALSE;
|
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) {
|
if (loaded) {
|
||||||
parse_state.menus = NULL;
|
parse_state.menus = NULL;
|
||||||
|
|
||||||
parse_register(i, "menu", parse_menu, &parse_state);
|
parse_register(menu_parse_inst, "menu", parse_menu, &parse_state);
|
||||||
parse_register(i, "item", parse_menu_item, &parse_state);
|
parse_register(menu_parse_inst, "item", parse_menu_item, &parse_state);
|
||||||
parse_register(i, "separator", parse_menu_separator, &parse_state);
|
parse_register(menu_parse_inst, "separator",
|
||||||
parse_tree(i, doc, node->xmlChildrenNode);
|
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)
|
gboolean menu_new(gchar *name, gchar *title, gpointer data)
|
||||||
{
|
{
|
||||||
ObMenu *self;
|
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 = g_new0(ObMenu, 1);
|
||||||
self->name = g_strdup(name);
|
self->name = g_strdup(name);
|
||||||
self->title = g_strdup(title);
|
self->title = g_strdup(title);
|
||||||
self->data = data;
|
self->data = data;
|
||||||
|
|
||||||
g_hash_table_insert(menu_hash, self->name, self);
|
g_hash_table_replace(menu_hash, self->name, self);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
|
||||||
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
|
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
|
||||||
|
|
||||||
typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
|
typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
|
||||||
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntryFrame *frame,
|
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
|
||||||
gpointer data);
|
|
||||||
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
||||||
|
|
||||||
extern GList *menu_visible;
|
extern ObParseInst *menu_parse_inst;
|
||||||
|
|
||||||
struct _ObMenu
|
struct _ObMenu
|
||||||
{
|
{
|
||||||
|
|
|
@ -572,16 +572,22 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
|
||||||
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
|
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
|
||||||
{
|
{
|
||||||
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
|
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 */
|
/* release grabs before executing the shit */
|
||||||
menu_frame_hide_all();
|
menu_frame_hide_all();
|
||||||
|
|
||||||
if (self->frame->menu->execute_func)
|
if (func)
|
||||||
self->frame->menu->execute_func(self, self->frame->menu->data);
|
func(entry, data);
|
||||||
else {
|
else {
|
||||||
GSList *it;
|
GSList *it;
|
||||||
|
|
||||||
for (it = self->entry->data.normal.actions; it;
|
for (it = acts; it; it = g_slist_next(it))
|
||||||
it = g_slist_next(it))
|
|
||||||
{
|
{
|
||||||
ObAction *act = it->data;
|
ObAction *act = it->data;
|
||||||
act->data.any.c = self->frame->client;
|
act->data.any.c = self->frame->client;
|
||||||
|
|
|
@ -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
|
/* executes it without changing the client in the actions, since we set that
|
||||||
when we make the actions! */
|
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;
|
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;
|
ObAction *act = it->data;
|
||||||
act->func(&act->data);
|
act->func(&act->data);
|
||||||
|
|
Loading…
Reference in a new issue