#include "e_mod_main.h" #include #define WINDOW_HEIGHT 250 #define TEXT_DIST 45 #define SIDE_OFFSET 30 static int _ngi_win_free(Ngi_Win *win); static Ngi_Win * _ngi_win_new(Ng *ng); static Eina_Bool _ngi_cb_container_resize(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_in(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_out(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_down(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_up(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_move(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_mouse_wheel(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_desk_show(void *data, int type, void *event); static Eina_Bool _ngi_win_cb_border_event(void *data, int type, void *event); static void _ngi_zoom_in(Ng *ng); static void _ngi_zoom_out(Ng *ng); static void _ngi_item_appear(Ng *ng, Ngi_Item *it); static void _ngi_item_disappear(Ng *ng, Ngi_Item *it); static void _ngi_zoom_function(Ng *ng, double d, double *disp); static Eina_Bool _ngi_animator(void *data); static void _ngi_redraw(Ng *ng); static int _ngi_autohide(Ng *ng, int hide); static Eina_Bool _ngi_win_border_intersects(Ng *ng); static int initialized = 0; E_Config_DD *ngi_conf_edd = NULL; E_Config_DD *ngi_conf_item_edd = NULL; E_Config_DD *ngi_conf_box_edd = NULL; E_Config_DD *ngi_conf_gadcon_edd = NULL; Config *ngi_config = NULL; E_Int_Menu_Augmentation *maug = NULL; static Evas_Smart *_e_smart = NULL; static void _ngi_bar_add(Evas_Object *obj){} static void _ngi_bar_del(Evas_Object *obj){} static void _ngi_bar_clip_set(Evas_Object *obj, Evas_Object * clip){} static void _ngi_bar_clip_unset(Evas_Object *obj){} static void _ngi_bar_color_set(Evas_Object *obj, int r, int g, int b, int a){} static Evas_Object * _ngi_bar_smart_add(Evas *evas) { if (!_e_smart) { static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION("ngi_bar"); if (!sc.add) { sc.add = _ngi_bar_add; sc.del = _ngi_bar_del; sc.move = NULL; sc.resize = NULL; sc.show = NULL; sc.hide = NULL; sc.color_set = _ngi_bar_color_set; sc.clip_set = _ngi_bar_clip_set; sc.clip_unset = _ngi_bar_clip_unset; } _e_smart = evas_smart_class_new(&sc); } return evas_object_smart_add(evas, _e_smart); } Ng * ngi_new(Config_Item *cfg) { Ng *ng; E_Zone *zone; Config_Box *cfg_box; Eina_List *l; int alpha; zone = (E_Zone *)e_util_container_zone_number_get(cfg->container, cfg->zone); if (!zone) return NULL; ng = E_NEW(Ng, 1); cfg->ng = ng; ng->cfg = cfg; ngi_config->instances = eina_list_append(ngi_config->instances, ng); ng->zone = zone; ng->win = _ngi_win_new(ng); ng->zoom = 1.0; ng->size = ng->cfg->size; ng->state = unzoomed; ng->hide_state = show; ng->hide = EINA_TRUE; ng->clip = evas_object_rectangle_add(ng->evas); evas_object_color_set(ng->clip, 255, 255, 255, 0); ng->bg_clip = evas_object_rectangle_add(ng->evas); alpha = cfg->alpha; evas_object_color_set(ng->bg_clip, alpha, alpha, alpha, alpha); ng->o_bg = edje_object_add(ng->evas); ng->o_frame = edje_object_add(ng->evas); ng->o_icons = _ngi_bar_smart_add(ng->evas); ng->o_label = edje_object_add(ng->evas); switch(cfg->orient) { case E_GADCON_ORIENT_BOTTOM: ngi_object_theme_set(ng->o_bg, "e/modules/engage/bg_bottom"); ngi_object_theme_set(ng->o_frame,"e/modules/engage/frame_bottom"); ngi_object_theme_set(ng->o_label,"e/modules/engage/label_bottom"); ng->o_proxy = evas_object_image_add(ng->evas); evas_object_image_source_set(ng->o_proxy, ng->o_icons); evas_object_map_enable_set(ng->o_proxy, 1); evas_object_show(ng->o_proxy); alpha = cfg->rflxn_alpha; evas_object_color_set(ng->o_proxy, alpha, alpha, alpha, alpha); break; case E_GADCON_ORIENT_TOP: ngi_object_theme_set(ng->o_bg, "e/modules/engage/bg_top"); ngi_object_theme_set(ng->o_frame,"e/modules/engage/frame_top"); ngi_object_theme_set(ng->o_label,"e/modules/engage/label_top"); break; case E_GADCON_ORIENT_LEFT: ngi_object_theme_set(ng->o_bg, "e/modules/engage/bg_left"); ngi_object_theme_set(ng->o_frame,"e/modules/engage/frame_left"); ngi_object_theme_set(ng->o_label,"e/modules/engage/label_left"); break; case E_GADCON_ORIENT_RIGHT: ngi_object_theme_set(ng->o_bg, "e/modules/engage/bg_right"); ngi_object_theme_set(ng->o_frame,"e/modules/engage/frame_right"); ngi_object_theme_set(ng->o_label,"e/modules/engage/label_right"); break; } const char *data = edje_object_data_get(ng->o_frame, "clip_separator"); if (data) ng->opt.clip_separator = atoi(data); data = edje_object_data_get(ng->o_frame, "icon_spacing"); if (data) ng->opt.item_spacing = atoi(data); data = edje_object_data_get(ng->o_frame, "edge_offset"); if (data) ng->opt.edge_offset = atoi(data); data = edje_object_data_get(ng->o_frame, "separator_width"); if (data) ng->opt.separator_width = atoi(data); data = edje_object_data_get(ng->o_frame, "bg_offset"); if (data) ng->opt.bg_offset = atoi(data); data = edje_object_data_get(ng->o_frame, "reflection_offset"); if (data) ng->opt.reflection_offset = atoi(data); data = edje_object_data_get(ng->o_frame, "keep_overlay_pos"); if (data) ng->opt.keep_overlay_pos = atof(data); ng->opt.fade_duration = 0.25; evas_object_show(ng->o_frame); evas_object_show(ng->o_bg); evas_object_show(ng->o_icons); evas_object_clip_set(ng->o_bg, ng->bg_clip); evas_object_show(ng->bg_clip); if (cfg->show_label) evas_object_show(ng->o_label); if (cfg->show_background) evas_object_show(ng->bg_clip); ngi_win_position_calc(ng->win); e_popup_show(ng->win->popup); EINA_LIST_FOREACH (cfg->boxes, l, cfg_box) { switch (cfg_box->type) { case launcher: ngi_launcher_new(ng, cfg_box); break; case taskbar: ngi_taskbar_new(ng, cfg_box); break; case gadcon: ngi_gadcon_new(ng, cfg_box); break; } } ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_X_EVENT_MOUSE_IN, _ngi_win_cb_mouse_in, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_X_EVENT_MOUSE_OUT, _ngi_win_cb_mouse_out, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_EVENT_MOUSE_BUTTON_DOWN, _ngi_win_cb_mouse_down, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_EVENT_MOUSE_BUTTON_UP, _ngi_win_cb_mouse_up, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_EVENT_MOUSE_WHEEL, _ngi_win_cb_mouse_wheel, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (ECORE_EVENT_MOUSE_MOVE, _ngi_win_cb_mouse_move, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_DESK_SHOW, _ngi_win_cb_desk_show, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_BORDER_PROPERTY, _ngi_win_cb_border_event, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_BORDER_MOVE, _ngi_win_cb_border_event, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_BORDER_RESIZE, _ngi_win_cb_border_event, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_BORDER_ADD, _ngi_win_cb_border_event, ng)); ng->handlers = eina_list_append (ng->handlers, ecore_event_handler_add (E_EVENT_BORDER_REMOVE, _ngi_win_cb_border_event, ng)); if (ng->cfg->autohide == AUTOHIDE_FULLSCREEN) { ng->hide = e_desk_current_get(ng->zone)->fullscreen_borders; } else if (ng->cfg->autohide == AUTOHIDE_OVERLAP) { ng->hide = _ngi_win_border_intersects(ng); } else if (ng->cfg->stacking == below_fullscreen) { int fullscreen = e_desk_current_get(ng->zone)->fullscreen_borders; if (fullscreen) e_popup_hide(ng->win->popup); else e_popup_show(ng->win->popup); } if (ng->cfg->autohide && ng->hide) { ng->hide = EINA_TRUE; ng->hide_step = ng->size + ng->opt.edge_offset + ng->opt.bg_offset; ng->hide_state = hidden; } ngi_thaw(ng); return ng; } void ngi_free(Ng *ng) { Ngi_Box *box; Ecore_Event_Handler *h; ngi_config->instances = eina_list_remove(ngi_config->instances, ng); while(ng->boxes) { box = ng->boxes->data; if (box->cfg->type == taskbar) ngi_taskbar_remove(box); else if (box->cfg->type == launcher) ngi_launcher_remove(box); else if (box->cfg->type == gadcon) ngi_gadcon_remove(box); } if (ng->animator) ecore_animator_del(ng->animator); if (ng->menu_wait_timer) ecore_timer_del(ng->menu_wait_timer); if (ng->mouse_in_timer) ecore_timer_del(ng->mouse_in_timer); if (ng->effect_timer) ecore_timer_del(ng->effect_timer); if (ng->o_bg) evas_object_del(ng->o_bg); if (ng->o_frame) evas_object_del(ng->o_frame); if (ng->clip) evas_object_del(ng->clip); if (ng->bg_clip) evas_object_del(ng->bg_clip); if (ng->o_icons) evas_object_del(ng->o_icons); if (ng->o_proxy) evas_object_del(ng->o_proxy); if (ng->win) _ngi_win_free(ng->win); EINA_LIST_FREE(ng->handlers, h) ecore_event_handler_del(h); free(ng); } Eina_Bool ngi_object_theme_set(Evas_Object *obj, const char *part) { if (e_theme_edje_object_set(obj, "base/theme/modules/engage", part)) return 1; else return edje_object_file_set(obj, ngi_config->theme_path, part); } static Ngi_Win * _ngi_win_new(Ng *ng) { Ngi_Win *win; win = E_NEW(Ngi_Win, 1); if (!win) return NULL; win->ng = ng; win->popup = e_popup_new(ng->zone, 0, 0, 0, 0); if (ngi_config->use_composite) { ecore_evas_alpha_set(win->popup->ecore_evas, 1); win->popup->evas_win = ecore_evas_software_x11_window_get(win->popup->ecore_evas); win->input = win->popup->evas_win; win->drop_win = E_OBJECT(win->popup); } else { ecore_evas_shaped_set(win->popup->ecore_evas, 1); win->input = ecore_x_window_input_new(ng->zone->container->win, 0, 0, 1, 1); ecore_x_window_show(win->input); win->fake_iwin = E_OBJECT_ALLOC(E_Win, E_WIN_TYPE, NULL); win->fake_iwin->evas_win = win->input; win->drop_win = E_OBJECT(win->fake_iwin); } ecore_x_netwm_window_type_set(win->popup->evas_win, ECORE_X_WINDOW_TYPE_DOCK); ng->evas = win->popup->evas; e_drop_xdnd_register_set(win->input, 1); e_container_window_raise(ng->zone->container, win->input, 999); return win; } static int _ngi_win_free(Ngi_Win *win) { e_drop_xdnd_register_set(win->input, 0); e_object_del(E_OBJECT(win->popup)); if (win->fake_iwin) { ecore_x_window_free(win->input); free(win->fake_iwin); } free(win); return 1; } static Eina_Bool _ngi_cb_container_resize(void *data, int ev_type, void *event_info) { Config_Item *ci; E_Zone *zone; Eina_List *l; Ng *ng; if (!initialized) return EINA_TRUE; EINA_LIST_FOREACH (ngi_config->items, l, ci) { if (!ci->ng) { ngi_new(ci); continue; } ng = ci->ng; zone = e_util_container_zone_number_get(ci->container, ci->zone); if (!zone) { ngi_free(ng); continue; } ngi_win_position_calc(ng->win); ngi_reposition(ng); ngi_input_extents_calc(ng); ngi_thaw(ng); } return EINA_TRUE; } static void _ngi_netwm_icon_geometry_set(E_Border *bd, int x, int y, int w, int h) { unsigned int sizes[4]; sizes[0] = x; sizes[1] = y; sizes[2] = w; sizes[3] = h; ecore_x_window_prop_card32_set (bd->win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, sizes, 4); } void ngi_input_extents_calc(Ng *ng) { int item_zoomed; Ngi_Win *win = ng->win; Ngi_Box *box; Eina_List *l; if (ng->mouse_in) item_zoomed = ng->size * ng->cfg->zoomfactor + ng->opt.bg_offset + ng->opt.edge_offset; else if (ng->hide_state == hidden) item_zoomed = 2; else item_zoomed = ng->size + ng->opt.bg_offset + ng->opt.edge_offset; switch (ng->cfg->orient) { case E_GADCON_ORIENT_BOTTOM: win->rect.x = ng->start; win->rect.y = ng->win->popup->h - item_zoomed; win->rect.width = ng->w; win->rect.height = item_zoomed; break; case E_GADCON_ORIENT_TOP: win->rect.x = ng->start; win->rect.y = 0; win->rect.width = ng->w; win->rect.height = item_zoomed; break; case E_GADCON_ORIENT_LEFT: win->rect.x = 0; win->rect.y = ng->start; win->rect.width = item_zoomed; win->rect.height = ng->w; break; case E_GADCON_ORIENT_RIGHT: win->rect.x = ng->win->popup->w - item_zoomed; win->rect.y = ng->start; win->rect.width = item_zoomed; win->rect.height = ng->w; break; } e_container_window_raise(ng->zone->container, win->input, 999); if (ngi_config->use_composite) { XShapeCombineRectangles((Display *)ecore_x_display_get(), win->input, ShapeInput, 0, 0, &win->rect, 1, ShapeSet, Unsorted); } else { ecore_x_window_move_resize(win->input, ng->zone->x + win->popup->x + win->rect.x, ng->zone->y + win->popup->y + win->rect.y, win->rect.width, win->rect.height); } EINA_LIST_FOREACH (ng->boxes, l, box) { if (!box->drop_handler) continue; int w = box->w; if (w < 10) w = 10; switch (ng->cfg->orient) { case E_GADCON_ORIENT_BOTTOM: e_drop_handler_geometry_set (box->drop_handler, box->pos, win->popup->h - item_zoomed, w, item_zoomed); break; case E_GADCON_ORIENT_TOP: e_drop_handler_geometry_set (box->drop_handler, box->pos, 0, w, item_zoomed); break; case E_GADCON_ORIENT_LEFT: e_drop_handler_geometry_set (box->drop_handler, 0, box->pos, item_zoomed, w); break; case E_GADCON_ORIENT_RIGHT: e_drop_handler_geometry_set (box->drop_handler, win->popup->w - item_zoomed, box->pos, item_zoomed, w); break; } } } static void _ngi_proxy_geometry_calc(Ng *ng) { int w = ng->win->popup->w; int h = ng->win->popup->h; evas_object_move(ng->o_icons, 0, h + ng->hide_step - ng->size - ng->opt.edge_offset); evas_object_resize(ng->o_icons, w, ng->cfg->size); if (ng->o_proxy) { evas_object_image_fill_set(ng->o_proxy, 0, 0, w, ng->opt.edge_offset); evas_object_move(ng->o_proxy, 0, h + ng->hide_step - ng->opt.edge_offset - ng->opt.reflection_offset); evas_object_resize(ng->o_proxy, w, ng->opt.edge_offset); Evas_Map *m = evas_map_new(4); evas_map_util_points_populate_from_object(m, ng->o_proxy); evas_map_point_image_uv_set(m, 0, 0, h); evas_map_point_image_uv_set(m, 1, w, h); evas_map_point_image_uv_set(m, 2, w, 0); evas_map_point_image_uv_set(m, 3, 0, 0); evas_map_util_3d_perspective(m, w/2, h/2, 1, 1000); evas_object_map_set(ng->o_proxy, m); evas_map_free(m); } } void ngi_win_position_calc(Ngi_Win *win) { Ng *ng = win->ng; E_Gadcon_Orient orient = (E_Gadcon_Orient)ng->cfg->orient; int size = WINDOW_HEIGHT; switch (orient) { case E_GADCON_ORIENT_LEFT: e_popup_move_resize(win->popup, 0, 0, size, ng->zone->h); ng->horizontal = 0; break; case E_GADCON_ORIENT_RIGHT: e_popup_move_resize(win->popup, ng->zone->w - size, 0, size, ng->zone->h); ng->horizontal = 0; break; case E_GADCON_ORIENT_TOP: e_popup_move_resize(win->popup, 0, 0, ng->zone->w, size); ng->horizontal = 1; break; case E_GADCON_ORIENT_BOTTOM: e_popup_move_resize(win->popup, 0, ng->zone->h - size, ng->zone->w, size); ng->horizontal = 1; break; default: break; } if (win->fake_iwin) { win->fake_iwin->x = win->popup->x; win->fake_iwin->y = win->popup->y; win->fake_iwin->w = win->popup->w; win->fake_iwin->h = win->popup->h; } evas_object_move(ng->clip, 0, 0); evas_object_resize(ng->clip, win->popup->w, win->popup->h - ng->opt.edge_offset); evas_object_move(ng->bg_clip, 0, 0); evas_object_resize(ng->bg_clip, win->popup->w, win->popup->h); _ngi_proxy_geometry_calc(ng); } static Eina_Bool _ngi_mouse_in_timer(void *data) { Ng *ng = data; ng->mouse_in_timer = NULL; ng->mouse_in = 1; ngi_input_extents_calc(ng); ngi_animate(ng); if (ng->item_active && ng->item_active->label && ng->item_active->label[0]) { evas_object_show(ng->o_label); edje_object_signal_emit(ng->o_label, "e,state,label,show", "e"); edje_object_part_text_set(ng->o_label, "e.text.label", ng->item_active->label); } return EINA_FALSE; } void ngi_mouse_in(Ng *ng) { if (ng->mouse_in_timer) ecore_timer_del(ng->mouse_in_timer); if (ng->hide_state == hidden) ng->mouse_in_timer = ecore_timer_add(0.15, _ngi_mouse_in_timer, ng); else _ngi_mouse_in_timer(ng); } static Eina_Bool _ngi_win_cb_mouse_in(void *data, int type, void *event) { Ecore_X_Event_Mouse_In *ev = event; Ng *ng = data; if (ev->win != ng->win->input) return EINA_TRUE; ng->pos = ng->horizontal ? (ev->root.x - ng->zone->x) : (ev->root.y - ng->zone->y); ngi_mouse_in(ng); if (!ngi_config->use_composite) evas_event_feed_mouse_in(ng->evas, ev->time, NULL); return EINA_TRUE; } void ngi_mouse_out(Ng *ng) { ng->mouse_in = 0; if (ng->mouse_in_timer) ecore_timer_del(ng->mouse_in_timer); ng->mouse_in_timer = NULL; ngi_item_mouse_out(ng->item_active); edje_object_signal_emit(ng->o_label, "e,state,label,hide", "e"); ngi_animate(ng); } static Eina_Bool _ngi_win_cb_mouse_out(void *data, int type, void *event) { Ecore_X_Event_Mouse_Out *ev = event; Ng *ng = data; if (ev->win != ng->win->input) return EINA_TRUE; ngi_mouse_out(ng); if (!ngi_config->use_composite) evas_event_feed_mouse_out(ng->evas, ev->time, NULL); return EINA_TRUE; } static Eina_Bool _ngi_menu_wait_after_timer_cb(void *data) { Ng *ng = data; ng->menu_wait_timer = NULL; ngi_animate(ng); return EINA_FALSE; } static Eina_Bool _ngi_menu_wait_timer_cb(void *data) { Ng *ng = data; if (e_menu_grab_window_get()) { edje_object_signal_emit(ng->o_label, "e,state,label,hide", "e"); return EINA_TRUE; } ng->menu_wait_timer = ecore_timer_add(1.0, _ngi_menu_wait_after_timer_cb, ng); return EINA_FALSE; } static Eina_Bool _ngi_win_cb_mouse_down(void *data, int type, void *event) { Ecore_Event_Mouse_Button *ev = event; Ng *ng = data; if (ev->event_window != ng->win->input) return EINA_TRUE; Ngi_Item *it = ng->item_active; if (ev->buttons == 2) { ngi_configure_module(ng->cfg); return EINA_TRUE; } else if (ng->item_active && ev->buttons == 1) { it->drag.x = ev->root.x; it->drag.y = ev->root.y; it->drag.start = 1; it->drag.dnd = 0; ng->item_drag = it; } ngi_item_mouse_down(it, ev); if (!ngi_config->use_composite) { Evas_Button_Flags flags = EVAS_BUTTON_NONE; if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; evas_event_feed_mouse_down(ng->evas, ev->buttons, flags, ev->timestamp, NULL); } /* if a grab window appears shortly after clicking the bar it probably is a menu that belongs to a item */ if (ng->menu_wait_timer) ecore_timer_del(ng->menu_wait_timer); ng->menu_wait_timer = ecore_timer_add(0.1, _ngi_menu_wait_timer_cb, ng); return EINA_TRUE; } static Eina_Bool _ngi_win_cb_mouse_up(void *data, int type, void *event) { Ecore_Event_Mouse_Button *ev = event; Ng *ng = data; if (ev->event_window != ng->win->input) return EINA_TRUE; if (ng->item_active) { ngi_item_mouse_up(ng->item_active, ev); evas_event_feed_mouse_up(ng->evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL); if (ng->item_drag) { ng->item_drag->drag.start = 0; ng->item_drag = NULL; } } return EINA_TRUE; } static Eina_Bool _ngi_win_cb_mouse_wheel(void *data, int type, void *event) { Ecore_Event_Mouse_Wheel *ev = event; Ng *ng = data; if (ev->event_window != ng->win->input) return EINA_TRUE; if (!ngi_config->use_composite) evas_event_feed_mouse_wheel(ng->evas, ev->direction, ev->z, ev->timestamp, NULL); return EINA_TRUE; } static Eina_Bool _ngi_win_cb_mouse_move(void *data, int type, void *event) { Ecore_Event_Mouse_Move *ev = event; Ng *ng = data; if (ev->event_window != ng->win->input) return EINA_TRUE; ng->pos = ng->horizontal ? ev->root.x : ev->root.y; ng->pos -= ng->horizontal ? ng->zone->x : ng->zone->y; if (!ng->mouse_in) return EINA_TRUE; ngi_item_activate(ng); if (!ngi_config->use_composite) evas_event_feed_mouse_move(ng->evas, ev->x + ng->win->rect.x, ev->y + ng->win->rect.y, ev->timestamp, NULL); if (ng->item_drag) { int dx = ev->root.x - ng->item_drag->drag.x; int dy = ev->root.y - ng->item_drag->drag.y; if (((dx * dx) + (dy * dy)) > (e_config->drag_resist * e_config->drag_resist)) { ng->item_drag->drag.dnd = 1; ng->item_drag->drag.start = 0; ITEM_DRAG_START(ng->item_drag); ngi_item_mouse_out(ng->item_active); ng->item_active = NULL; ng->item_drag = NULL; } } ngi_animate(ng); return EINA_TRUE; } /**************************************************************************/ Ngi_Item * ngi_item_at_position_get(Ng *ng) { Eina_List *l, *ll; Ngi_Item *it; Ngi_Box *box; int pos = ng->pos; EINA_LIST_FOREACH (ng->boxes, ll, box) { if (pos < box->pos) continue; EINA_LIST_FOREACH (box->items, l, it) { if (it->delete_me) continue; if (it->scale == 0.0) continue; if (pos <= it->pos + ng->size + ng->opt.item_spacing) { if (pos + ng->opt.item_spacing < it->pos - ng->size) return NULL; return it; } } } return NULL; } void ngi_item_activate(Ng *ng) { Ngi_Item *it; if (!ng->mouse_in) { ng->item_active = NULL; evas_object_hide(ng->o_label); return; } if ((it = ngi_item_at_position_get(ng)) && (it != ng->item_active)) { ngi_item_mouse_out(ng->item_active); ngi_item_mouse_in(it); ng->item_active = it; } else if (!it) { ngi_item_mouse_out(ng->item_active); ng->item_active = NULL; } if ((!ng->cfg->show_label) || (!ng->item_active) || (!ng->item_active->label)) { evas_object_hide(ng->o_label); return; } switch (ng->cfg->orient) { case E_GADCON_ORIENT_BOTTOM: evas_object_move(ng->o_label, ng->item_active->pos + ng->size/2, (ng->win->popup->h + ng->hide_step) - ((double)ng->size * ng->zoom + TEXT_DIST)); break; case E_GADCON_ORIENT_TOP: evas_object_move(ng->o_label, ng->item_active->pos + ng->size/2, ((double)ng->size * ng->zoom + TEXT_DIST) - ng->hide_step); break; } evas_object_show(ng->o_label); edje_object_signal_emit(ng->o_label, "e,state,label,show", "e"); edje_object_part_text_set(ng->o_label, "e.text.label", ng->item_active->label); } /**************************************************************************/ static void _ngi_item_appear(Ng *ng, Ngi_Item *it) { it->scale = (ecore_time_get() - it->start_time) / ng->opt.fade_duration; if (it->scale < 1.0) { ngi_reposition(ng); return; } it->scale = 1.0; ng->items_show = eina_list_remove(ng->items_show, it); ngi_reposition(ng); ngi_input_extents_calc(ng); ngi_item_activate(ng); } static void _ngi_item_disappear(Ng *ng, Ngi_Item *it) { it->scale = 1.0 - (ecore_time_get() - it->start_time) / ng->opt.fade_duration; if (it->scale > 0.0) { ngi_reposition(ng); return; } ng->items_remove = eina_list_remove(ng->items_remove, it); ngi_item_free(it); ng->size = ng->cfg->size; ngi_reposition(ng); ngi_input_extents_calc(ng); ngi_animate(ng); ngi_item_activate(ng); } static double _ngi_anim_advance_in(double start, double duration) { double z = (ecore_time_get() - start) / duration; if (z > 1.0) return 1.0; if (z < 0.0) return 0.0; z = log(10) * z; return 1.0 - (1.0 / exp(z*z)); } static double _ngi_anim_advance_out(double start, double duration) { double z = (ecore_time_get() - start) / duration; if (z > 1.0) return 0.0; if (z < 0.0) return 1.0; z = 1.0 - z; z = log(10) * z; return 1.0 - (1.0 / exp(z*z)); } static void _ngi_zoom_in(Ng *ng) { double z; if (ng->state != zooming) { double now = ecore_time_get(); if (ng->state == unzooming) ng->start_zoom = now - (ng->cfg->zoom_duration - (now - ng->start_zoom)); else ng->start_zoom = now; ng->state = zooming; } z = _ngi_anim_advance_in(ng->start_zoom, ng->cfg->zoom_duration); ng->zoom = 1.0 + (ng->cfg->zoomfactor - 1.0) * z; if (z == 1.0) { ng->zoom = ng->cfg->zoomfactor; ng->state = zoomed; } } static void _ngi_zoom_out(Ng *ng) { double z; if (ng->state != unzooming) { double now = ecore_time_get(); if (ng->state == zooming) ng->start_zoom = now - (ng->cfg->zoom_duration - (now - ng->start_zoom)); else ng->start_zoom = now; ng->state = unzooming; } z = _ngi_anim_advance_out(ng->start_zoom, ng->cfg->zoom_duration); ng->zoom = 1.0 + (ng->cfg->zoomfactor - 1.0) * z; if (z == 0.0) { ng->zoom = 1.0; ng->state = unzoomed; if (!ng->hide) ngi_input_extents_calc(ng); if (ng->item_active) { ngi_item_mouse_out(ng->item_active); ng->item_active = NULL; } } } static int _ngi_autohide(Ng *ng, int hide) { double duration = ng->cfg->zoom_duration; double step = ng->hide_step; double hide_max = ng->size + ng->opt.edge_offset + ng->opt.bg_offset; if (hide) { if (ng->hide_state != hiding) { double now = ecore_time_get(); if (ng->hide_state == showing) ng->start_hide = now - (step / hide_max) * duration; else ng->start_hide = now; if (ng->start_hide < now - duration) ng->start_hide = now - duration; ng->hide_state = hiding; } step = hide_max * (1.0 - _ngi_anim_advance_out(ng->start_hide, duration)); if (step >= hide_max) { ng->hide_state = hidden; ng->hide_step = hide_max; ngi_input_extents_calc(ng); return 0; } } else { if (ng->hide_state != showing) { double now = ecore_time_get(); if (ng->hide_state == hiding) ng->start_hide = now - (duration - (step / hide_max) * duration); else ng->start_hide = now; ng->hide_state = showing; } step = hide_max * (1.0 - _ngi_anim_advance_in(ng->start_hide, duration)); if (step <= 0) { ng->hide_state = show; ng->hide_step = 0; _ngi_proxy_geometry_calc(ng); ngi_input_extents_calc(ng); return 0; } } if (step > hide_max) step = hide_max; else if (step < 0) step = 0; ng->hide_step = step; return 1; } void ngi_animate(Ng *ng) { ng->changed = 1; if (ng->animator) return; ng->animator = ecore_animator_add(_ngi_animator, ng); } static Eina_Bool _ngi_animator(void *data) { Ng *ng = data; Eina_Bool cont = 0; Eina_List *l, *ll; Ngi_Item *it; if (ng->items_remove || ng->items_show) cont = 1; EINA_LIST_FOREACH_SAFE(ng->items_show, l, ll, it) _ngi_item_appear(ng, it); EINA_LIST_FOREACH_SAFE(ng->items_remove, l, ll, it) _ngi_item_disappear(ng, it); if (ng->cfg->zoomfactor > 1.0) { if (ng->mouse_in && (ng->state != zoomed)) { _ngi_zoom_in(ng); cont = 1; } else if (!ng->mouse_in && (ng->state != unzoomed)) { _ngi_zoom_out(ng); cont = 1; } } if (ng->cfg->autohide) { if (ng->mouse_in || ng->show_bar || ng->menu_wait_timer || (!ng->hide)) { if (ng->hide_state != show) { _ngi_autohide(ng, 0); cont = 1; } } else { if ((ng->hide_state != hidden) && ((ng->zoom - 1.0) <= (ng->cfg->zoomfactor - 1.0) / 2.0)) { _ngi_autohide(ng, 1); cont = 1; } } } if (cont || ng->changed) { _ngi_redraw(ng); return EINA_TRUE; } ng->animator = NULL; return EINA_FALSE; } void ngi_reposition(Ng *ng) { Ngi_Box *box; double pos, distance, range, disp; Eina_List *l, *ll; Ngi_Item *it; int size = ng->size; int cnt = 0, end; int width = ng->horizontal ? ng->win->popup->w : ng->win->popup->h; ng->w = 0; EINA_LIST_FOREACH (ng->boxes, l, box) { box->w = 0; EINA_LIST_FOREACH (box->items, ll, it) { if (it->scale == 0.0) continue; box->w += (size * it->scale) + ng->opt.item_spacing; } ng->w += box->w; if (cnt++ > 0) ng->w += ng->opt.separator_width; } ng->start = (width - ng->w) / 2; distance = ng->start - SIDE_OFFSET - width/2; range = ng->cfg->zoom_range * ng->size; disp = erf(distance / range) * range * (ng->cfg->zoomfactor - 1.0); end = ng->start - SIDE_OFFSET + disp; /* shrink bar when it becomes larger than screen height/width */ if (end < 0 && size > 1) { ng->size -= 1; ngi_reposition(ng); return; } cnt = 0; pos = ng->start; EINA_LIST_FOREACH (ng->boxes, l, box) { box->pos = pos; if (cnt++ > 0) pos += (ng->opt.separator_width); EINA_LIST_FOREACH (box->items, ll, it) { if (it->scale == 0.0) continue; it->pos = pos; pos += it->scale * size + ng->opt.item_spacing; } } if (!ng->cfg->ecomorph_features) return; if (ng->items_show || ng->items_remove) return; /* FIXME */ EINA_LIST_FOREACH (ng->boxes, l, box) { Ngi_Item_Taskbar *it; if (!(box->cfg->type == taskbar)) continue; switch(ng->cfg->orient) { case E_GADCON_ORIENT_BOTTOM: EINA_LIST_FOREACH(box->items, ll, it) _ngi_netwm_icon_geometry_set (it->border, it->base.pos, (ng->win->popup->y + ng->win->popup->h) - size, size, size); break; case E_GADCON_ORIENT_TOP: EINA_LIST_FOREACH(box->items, ll, it) _ngi_netwm_icon_geometry_set (it->border, it->base.pos, ng->hide_step, size, size); break; case E_GADCON_ORIENT_LEFT: EINA_LIST_FOREACH(box->items, ll, it) _ngi_netwm_icon_geometry_set (it->border, ng->hide_step, it->base.pos, size, size); break; case E_GADCON_ORIENT_RIGHT: EINA_LIST_FOREACH(box->items, ll, it) _ngi_netwm_icon_geometry_set (it->border, (ng->win->popup->x + ng->win->popup->w) - size, it->base.pos, size, size); break; } } } static void _ngi_zoom_function(Ng *ng, double d, double *disp) { float range = ng->cfg->zoom_range * ng->size; *disp = erf(d / range) * range * (ng->zoom - 1.0); } static void _ngi_redraw(Ng *ng) { Ngi_Item *it; Ngi_Box *box; Eina_List *l, *ll; double pos, pos2; int end1, end2, size_spacing, hide_step; int bw, bh, bx, by; Config_Item *cfg = ng->cfg; int edge_offset = ng->opt.edge_offset; int separator_width = ng->opt.separator_width; int cnt = 0; double disp = 0.0; int w = ng->win->popup->w; int h = ng->win->popup->h; if (cfg->autohide) hide_step = ng->hide_step; else hide_step = ng->hide_step = 0; size_spacing = ng->size + edge_offset; if (ng->o_proxy && ((ng->hide_state == hiding) || (ng->hide_state == showing))) _ngi_proxy_geometry_calc(ng); if (cfg->show_background) { _ngi_zoom_function(ng, ng->start - ng->pos, &disp); end1 = ng->start + disp; _ngi_zoom_function(ng, ng->start + ng->w - ng->pos, &disp); end2 = ng->start + ng->w + disp; switch (cfg->orient) { case E_GADCON_ORIENT_BOTTOM: bx = end1; by = h + hide_step - size_spacing; bw = end2 - end1; bh = size_spacing; break; case E_GADCON_ORIENT_TOP: bx = end1; by = - hide_step; bw = end2 - end1; bh = size_spacing; break; case E_GADCON_ORIENT_LEFT: bx = - hide_step; by = end1; bw = size_spacing; bh = end2 - end1; break; case E_GADCON_ORIENT_RIGHT: bx = w + hide_step - size_spacing; by = end1; bw = size_spacing; bh = end2 - end1; } evas_object_move(ng->o_bg, bx, by); evas_object_resize(ng->o_bg, bw, bh); evas_object_move(ng->o_frame, bx, by); evas_object_resize(ng->o_frame, bw, bh); } if (ng->item_active /* && ng->state != unzoomed */) { switch (cfg->orient) { case E_GADCON_ORIENT_BOTTOM: evas_object_move(ng->o_label, ng->item_active->pos + ng->size/2, (h + hide_step) - ((double)ng->size * ng->zoom + TEXT_DIST)); break; case E_GADCON_ORIENT_TOP: evas_object_move(ng->o_label, ng->item_active->pos + ng->size/2, ((double)ng->size * ng->zoom + TEXT_DIST) - hide_step); break; } } EINA_LIST_FOREACH (ng->boxes, ll, box) { if (cnt++ > 0) { _ngi_zoom_function(ng, box->pos - ng->pos, &disp); pos = (box->pos + disp); switch (cfg->orient) { case E_GADCON_ORIENT_BOTTOM: evas_object_move(box->separator, pos, h + hide_step - size_spacing); evas_object_resize(box->separator, separator_width, size_spacing); break; case E_GADCON_ORIENT_TOP: evas_object_move(box->separator, pos, -hide_step); evas_object_resize(box->separator, separator_width, size_spacing); break; case E_GADCON_ORIENT_LEFT: evas_object_move(box->separator, -hide_step, pos); evas_object_resize(box->separator, size_spacing, separator_width); break; case E_GADCON_ORIENT_RIGHT: evas_object_move(box->separator, w + hide_step - size_spacing, pos); evas_object_resize(box->separator, size_spacing, separator_width); } evas_object_show(box->separator); } else evas_object_hide(box->separator); pos = 0; EINA_LIST_FOREACH (box->items, l, it) { double size; if (it->scale == 0.0) continue; if (pos == 0) { _ngi_zoom_function(ng, it->pos - ng->pos, &pos); pos = (double)it->pos + pos; } else { pos = pos2 + (double)ng->opt.item_spacing; } _ngi_zoom_function(ng, it->pos + (ng->size * it->scale) - ng->pos, &pos2); pos2 = (double)it->pos + ((double)ng->size * it->scale) + pos2; if (pos2 > ng->pos) { /* pos2 += 0.5; */ size = (int)(pos2 - (pos - 0.5)); pos += 0.5; } else size = (int)(pos2 - pos); switch (cfg->orient) { case E_GADCON_ORIENT_BOTTOM: bx = pos; by = h + hide_step - (edge_offset + size); break; case E_GADCON_ORIENT_TOP: bx = pos; by = edge_offset - hide_step; break; case E_GADCON_ORIENT_LEFT: bx = edge_offset - hide_step; by = pos; break; case E_GADCON_ORIENT_RIGHT: bx = w + hide_step - (edge_offset + size); by = pos; break; } evas_object_move(it->obj, bx, by); evas_object_resize(it->obj, size, size); evas_object_move(it->over, bx, by); evas_object_resize(it->over, size, size); } } ng->changed = 0; } void ngi_bar_lock(Ng *ng, int show) { if (show) { ng->show_bar++; } else if (ng->show_bar > 0) { ng->show_bar--; } } void ngi_freeze(Ng *ng) { if (ng->animator) { ecore_animator_del(ng->animator); ng->animator = NULL; } } void ngi_thaw(Ng *ng) { ngi_reposition(ng); ngi_input_extents_calc(ng); ngi_animate(ng); } static Eina_Bool _ngi_win_border_intersects(Ng *ng) { Eina_List *l; E_Border *bd; E_Desk *desk; int x, y, w, h, size; desk = e_desk_current_get(ng->zone); size = ng->size + ng->opt.bg_offset + ng->opt.edge_offset; switch (ng->cfg->orient) { case E_GADCON_ORIENT_BOTTOM: x = ng->start; y = ng->win->popup->h - size; w = ng->w; h = size; break; case E_GADCON_ORIENT_TOP: x = ng->start; y = 0; w = ng->w; h = size; break; case E_GADCON_ORIENT_LEFT: x = 0; y = ng->start; w = size; h = ng->w; break; case E_GADCON_ORIENT_RIGHT: x = ng->win->popup->w - size; y = ng->start; w = size; h = ng->w; break; } x += ng->zone->x + ng->win->popup->x; y += ng->zone->y + ng->win->popup->y; EINA_LIST_FOREACH(e_border_client_list(), l, bd) { if (bd->delete_requested) continue; if (bd->zone != ng->zone) continue; if ((bd->desk != desk) && (!bd->sticky)) continue; if (E_INTERSECTS(x, y, w, h, bd->x, bd->y, bd->w, bd->h)) return EINA_TRUE; } return EINA_FALSE; } static Eina_Bool _ngi_win_cb_desk_show(void *data, int type, void *event) { E_Event_Desk_Show *ev = event; Ng *ng = data; int fullscreen; if (ng->cfg->stacking == below_fullscreen) { fullscreen = ev->desk->fullscreen_borders; if (fullscreen) e_popup_hide(ng->win->popup); else e_popup_show(ng->win->popup); } else if (ng->cfg->autohide == AUTOHIDE_FULLSCREEN) { fullscreen = ev->desk->fullscreen_borders; if (ng->hide != fullscreen) ngi_animate(ng); ng->hide = fullscreen; } return EINA_TRUE; } static Eina_Bool _ngi_win_cb_border_event(void *data, int type, void *event) { E_Event_Border_Property *ev = event; Ng *ng = data; E_Desk *desk; int hide; if (ng->cfg->stacking == below_fullscreen) { desk = e_desk_current_get(ng->zone); hide = desk->fullscreen_borders; if (hide) e_popup_hide(ng->win->popup); else e_popup_show(ng->win->popup); } if (ng->cfg->autohide == AUTOHIDE_FULLSCREEN) { desk = e_desk_current_get(ng->zone); hide = desk->fullscreen_borders; if (ng->hide != hide) ngi_animate(ng); ng->hide = hide; } else if (ng->cfg->autohide == AUTOHIDE_OVERLAP) { desk = e_desk_current_get(ng->zone); hide = _ngi_win_border_intersects(ng); if (ng->hide != hide) ngi_animate(ng); ng->hide = hide; } return EINA_TRUE; } /***************************************************************************/ EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "engage" }; static int _ngi_init_timer_cb(void *data) { Eina_List *l; Config_Item *ci; EINA_LIST_FOREACH (ngi_config->items, l, ci) ngi_new(ci); initialized = 1; return 0; } /* menu item callback(s) */ static void _e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi) { ngi_instances_config(e_util_zone_current_get(e_manager_current_get())->container, NULL); } /* menu item add hook */ static void _e_mod_menu_add(void *data, E_Menu *m) { E_Menu_Item *mi; mi = e_menu_item_new(m); e_menu_item_label_set(mi, D_("Engage")); e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf"); e_menu_item_callback_set(mi, _e_mod_run_cb, NULL); } static void _ngi_config_free() { Config_Item *ci; Config_Box *cfg_box; Config_Gadcon *cg; EINA_LIST_FREE(ngi_config->items, ci) { EINA_LIST_FREE(ci->boxes, cfg_box) { if (cfg_box->type == launcher && cfg_box->launcher_app_dir) eina_stringshare_del(cfg_box->launcher_app_dir); if (cfg_box->type == gadcon) { EINA_LIST_FREE(cfg_box->gadcon_items, cg) eina_stringshare_del(cg->name); } } free(ci); } if (ngi_config->theme_path) free(ngi_config->theme_path); free(ngi_config); ngi_config = NULL; } EAPI void * e_modapi_init(E_Module *m) { char buf[4096]; ngi_config = NULL; /* Location of message catalogs for localization */ snprintf(buf, sizeof(buf), "%s/locale", e_module_dir_get(m)); bindtextdomain(PACKAGE, buf); bind_textdomain_codeset(PACKAGE, "UTF-8"); ngi_conf_gadcon_edd = E_CONFIG_DD_NEW("Ngi_Config_Gadcon", Config_Gadcon); E_CONFIG_VAL(ngi_conf_gadcon_edd, Config_Gadcon, name, STR); ngi_conf_box_edd = E_CONFIG_DD_NEW("Ngi_Config_Item_Box", Config_Box); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, type, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, launcher_app_dir, STR); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, launcher_lock_dnd, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_skip_dialogs, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_adv_bordermenu, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_show_iconified, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_show_desktop, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_append_right, INT); E_CONFIG_VAL(ngi_conf_box_edd, Config_Box, taskbar_group_apps, INT); E_CONFIG_LIST(ngi_conf_box_edd, Config_Box, gadcon_items, ngi_conf_gadcon_edd); ngi_conf_item_edd = E_CONFIG_DD_NEW("Ngi_Config_Item", Config_Item); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, show_label, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, show_background, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, container, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, zone, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, orient, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, size, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, autohide, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, autohide_show_urgent, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, hide_timeout, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, zoom_duration, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, zoomfactor, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, zoom_range, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, hide_below_windows, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, alpha, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, stacking, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, mouse_over_anim, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, lock_deskswitch, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, ecomorph_features, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, rflxn_alpha, INT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, rflxn_foc, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, rflxn_dist, FLOAT); E_CONFIG_VAL(ngi_conf_item_edd, Config_Item, rflxn_rot, FLOAT); E_CONFIG_LIST(ngi_conf_item_edd, Config_Item, boxes, ngi_conf_box_edd); ngi_conf_edd = E_CONFIG_DD_NEW("Ngi_Config", Config); E_CONFIG_VAL(ngi_conf_edd, Config, version, INT); E_CONFIG_LIST(ngi_conf_edd, Config, items, ngi_conf_item_edd); ngi_config = (Config *)e_config_domain_load("module.engage", ngi_conf_edd); if (ngi_config && !e_util_module_config_check (D_("Engage"), ngi_config->version, MOD_CONFIG_FILE_EPOCH, MOD_CONFIG_FILE_VERSION)) _ngi_config_free(); if (!ngi_config) { ngi_config = E_NEW(Config, 1); ngi_config->version = (MOD_CONFIG_FILE_EPOCH << 16); } ngi_config->cfd = NULL; ngi_config->module = m; snprintf(buf, sizeof(buf), "%s/engage.edj", e_module_dir_get(m)); ngi_config->theme_path = strdup(buf); snprintf(buf, sizeof(buf), "%s/.e/e/applications/bar/", e_user_homedir_get()); if (!ecore_file_mkdir(buf) && !ecore_file_is_dir(buf)) { e_error_message_show("Error creating directory:\n %s\n",buf); return m; } e_configure_registry_item_add("extensions/engage", 40, D_("Engage"), NULL, "preferences-desktop-shelf", ngi_instances_config); ngi_config->handlers = eina_list_append (ngi_config->handlers, ecore_event_handler_add (E_EVENT_CONTAINER_RESIZE, _ngi_cb_container_resize, NULL)); ngi_taskbar_init(); ngi_gadcon_init(); if (ecore_x_screen_is_composited(0)) ngi_config->use_composite = 1; else ngi_config->use_composite = 0; e_module_delayed_set(m, 1); _ngi_init_timer_cb(NULL); maug = e_int_menus_menu_augmentation_add ("config/1", _e_mod_menu_add, NULL, NULL, NULL); return m; } EAPI int e_modapi_shutdown(E_Module *m) { Ecore_Event_Handler *h; Ng *ng; Eina_List *l, *ll; if (maug) { e_int_menus_menu_augmentation_del("config/1", maug); maug = NULL; } ngi_gadcon_shutdown(); EINA_LIST_FOREACH_SAFE(ngi_config->instances, l, ll, ng) { if (ng->cfg->config_dialog) e_object_del(E_OBJECT(ng->cfg->config_dialog)); ngi_free(ng); } EINA_LIST_FREE(ngi_config->handlers, h) ecore_event_handler_del(h); _ngi_config_free(); E_CONFIG_DD_FREE(ngi_conf_gadcon_edd); E_CONFIG_DD_FREE(ngi_conf_box_edd); E_CONFIG_DD_FREE(ngi_conf_item_edd); E_CONFIG_DD_FREE(ngi_conf_edd); e_configure_registry_item_del("extensions/engage"); return 1; } EAPI int e_modapi_save(E_Module *m) { e_config_domain_save("module.engage", ngi_conf_edd, ngi_config); return 1; }