From 25b6a1bd1d54f038383953e680492223eeb4478e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 2 Jul 2012 13:28:13 +0000 Subject: [PATCH] fix gadman to not crash with module load/unload, also dynamically update available gadgets list when new modules are loaded SVN revision: 73165 --- src/modules/gadman/e_mod_config.c | 17 +++++++++ src/modules/gadman/e_mod_config.h | 1 + src/modules/gadman/e_mod_gadman.c | 58 ++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/modules/gadman/e_mod_config.c b/src/modules/gadman/e_mod_config.c index 433322c87..62d39367d 100644 --- a/src/modules/gadman/e_mod_config.c +++ b/src/modules/gadman/e_mod_config.c @@ -31,6 +31,15 @@ static void _cb_fm_change(void *data, Evas_Object *obj, void *event_info static void _cb_fm_sel_change(void *data, Evas_Object *obj, void *event_info); static void _cb_button_up(void *data1, void *data2); +static E_Config_Dialog *_cfd = NULL; + +static int +_close_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__) +{ + _cfd = NULL; + return 1; +} + E_Config_Dialog * _config_gadman_module(E_Container *con, const char *params __UNUSED__) { @@ -48,6 +57,7 @@ _config_gadman_module(E_Container *con, const char *params __UNUSED__) v->free_cfdata = _free_data; v->basic.create_widgets = _basic_create_widgets; v->basic.apply_cfdata = _basic_apply_data; + v->close_cfdata = _close_cfdata; snprintf(buf, sizeof(buf), "%s/e-module-gadman.edj", Man->module->dir); cfd = e_config_dialog_new(con, _("Gadgets Manager"), @@ -55,6 +65,7 @@ _config_gadman_module(E_Container *con, const char *params __UNUSED__) buf, 0, v, Man); Man->config_dialog = cfd; + _cfd = cfd; return Man->config_dialog; } @@ -425,3 +436,9 @@ _cb_button_up(void *data1, void *data2 __UNUSED__) e_widget_scrollframe_child_pos_set(cfdata->o_sf, 0, 0); } +EAPI void +e_config_gadman_list_refresh(void) +{ + if (!_cfd) return; + _fill_gadgets_list(_cfd->cfdata->o_avail); +} diff --git a/src/modules/gadman/e_mod_config.h b/src/modules/gadman/e_mod_config.h index efa97a845..9c4ebed4d 100644 --- a/src/modules/gadman/e_mod_config.h +++ b/src/modules/gadman/e_mod_config.h @@ -4,6 +4,7 @@ #define E_MOD_CONFIG_H E_Config_Dialog *_config_gadman_module(E_Container *con, const char *params __UNUSED__); +EAPI void e_config_gadman_list_refresh(void); #endif #endif diff --git a/src/modules/gadman/e_mod_gadman.c b/src/modules/gadman/e_mod_gadman.c index 88eb7a362..e435c067e 100644 --- a/src/modules/gadman/e_mod_gadman.c +++ b/src/modules/gadman/e_mod_gadman.c @@ -39,6 +39,7 @@ static void on_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi); static void on_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi); static void on_menu_add(void *data, E_Menu *m, E_Menu_Item *mi); +static Eina_Bool _gadman_module_cb(void *d __UNUSED__, int type __UNUSED__, E_Event_Module_Update *ev); static int _e_gadman_client_add(void *data __UNUSED__, const E_Gadcon_Client_Class *cc); static void _e_gadman_client_remove(void *data __UNUSED__, E_Gadcon_Client *gcc); @@ -51,6 +52,7 @@ E_Gadcon_Client *current = NULL; Manager *Man = NULL; static E_Gadcon_Location *location = NULL; static Eina_List *_gadman_hdls = NULL; +static Eina_Hash *_gadman_gadgets = NULL; /* Implementation */ void @@ -97,6 +99,7 @@ gadman_init(E_Module *m) } } + _gadman_gadgets = eina_hash_string_superfast_new(NULL); _e_gadman_handlers_add(); } @@ -136,6 +139,12 @@ gadman_shutdown(void) e_canvas_del(Man->top_ee); //ecore_evas_free(Man->top_ee); } + if (_gadman_gadgets) + { + eina_hash_free_cb_set(_gadman_gadgets, EINA_FREE_CB(eina_list_free)); + eina_hash_free(_gadman_gadgets); + } + _gadman_gadgets = NULL; free(Man); Man = NULL; } @@ -227,7 +236,12 @@ gadman_gadget_place(E_Config_Gadcon_Client *cf, Gadman_Layer_Type layer, E_Zone if (gcc->gadcon->id == ID_GADMAN_LAYER_TOP) edje_object_signal_emit(gcc->o_frame, "e,state,visibility,hide", "e"); - + if (cc->name) + { + Eina_List *l; + l = eina_hash_find(_gadman_gadgets, cc->name); + eina_hash_set(_gadman_gadgets, cc->name, eina_list_append(l, gcc)); + } evas_object_show(gcc->o_frame); return gcc; @@ -297,10 +311,13 @@ void gadman_gadget_del(E_Gadcon_Client *gcc) { Gadman_Layer_Type layer = gcc->gadcon->id - ID_GADMAN_LAYER_BASE; + Eina_List *l; + Man->gadgets[layer] = eina_list_remove(Man->gadgets[layer], gcc); // edje_object_part_unswallow(gcc->o_frame, gcc->o_base); - + l = eina_hash_find(_gadman_gadgets, gcc->name); + eina_hash_set(_gadman_gadgets, gcc->name, eina_list_remove(l, gcc)); if (gcc->cf) e_gadcon_client_config_del(gcc->gadcon->cf, gcc->cf); gcc->cf = NULL; e_object_del(E_OBJECT(gcc)); @@ -1393,16 +1410,13 @@ _e_gadman_client_remove(void *data __UNUSED__, E_Gadcon_Client *gcc) static void _e_gadman_handlers_add(void) { - _gadman_hdls = - eina_list_append(_gadman_hdls, - ecore_event_handler_add(E_EVENT_ZONE_ADD, - _e_gadman_cb_zone_add, - NULL)); - _gadman_hdls = - eina_list_append(_gadman_hdls, - ecore_event_handler_add(E_EVENT_ZONE_DEL, - _e_gadman_cb_zone_del, - NULL)); + _gadman_hdls = eina_list_append(_gadman_hdls, + ecore_event_handler_add(E_EVENT_ZONE_ADD, _e_gadman_cb_zone_add, NULL)); + _gadman_hdls = eina_list_append(_gadman_hdls, + ecore_event_handler_add(E_EVENT_ZONE_DEL, _e_gadman_cb_zone_del, NULL)); + _gadman_hdls = eina_list_append(_gadman_hdls, + ecore_event_handler_add(E_EVENT_MODULE_UPDATE, (Ecore_Event_Handler_Cb)_gadman_module_cb, NULL)); + } static void @@ -1415,6 +1429,26 @@ _e_gadman_handler_del(void) ecore_event_handler_del(hdl); } +static Eina_Bool +_gadman_module_cb(void *d __UNUSED__, int type __UNUSED__, E_Event_Module_Update *ev) +{ + if (ev->enabled) + e_config_gadman_list_refresh(); + else + { + Eina_List *l; + E_Gadcon_Client *gcc; + l = eina_hash_set(_gadman_gadgets, ev->name, NULL); + if (!l) return ECORE_CALLBACK_RENEW; + EINA_LIST_FREE(l, gcc) + { + gcc->cf = NULL; + gadman_gadget_del(gcc); + } + } + return ECORE_CALLBACK_RENEW; +} + static Eina_Bool _e_gadman_cb_zone_add(void *data __UNUSED__, int type __UNUSED__, void *event) {