1 #include "e_mod_gadman.h"
2 
3 /* local protos */
4 static void             _attach_menu(void *data, E_Gadcon_Client *gcc, E_Menu *menu);
5 static void             _save_widget_position(E_Gadcon_Client *gcc);
6 static void             _apply_widget_position(E_Gadcon_Client *gcc);
7 static E_Gadcon_Client *_gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer, E_Config_Gadcon_Client *src_cf);
8 static Eina_Bool _gadman_module_init_end_cb(void *d EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
9 static Evas_Object     *_create_mover(E_Gadcon *gc);
10 static Evas_Object     *_get_mover(E_Gadcon_Client *gcc);
11 static E_Gadcon        *_gadman_gadcon_new(const char *name, Gadman_Layer_Type layer, E_Zone *zone, E_Gadcon_Location *loc);
12 static void _gadman_overlay_create(void);
13 static void             on_top(void *data, Evas_Object *o, const char *em, const char *src);
14 static void             on_right(void *data, Evas_Object *o, const char *em, const char *src);
15 static void             on_down(void *data, Evas_Object *o, const char *em, const char *src);
16 static void             on_left(void *data, Evas_Object *o, const char *em, const char *src);
17 static void             on_move(void *data, Evas_Object *o, const char *em, const char *src);
18 
19 static void             on_frame_click(void *data, Evas *e, Evas_Object *obj, void *event_info);
20 static void             on_bg_click(void *data, Evas_Object *o, const char *em, const char *src);
21 static void             on_hide_stop(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED,
22                                      const char *em EINA_UNUSED, const char *src EINA_UNUSED);
23 
24 static void             on_menu_style_plain(void *data, E_Menu *m, E_Menu_Item *mi);
25 static void             on_menu_style_inset(void *data, E_Menu *m, E_Menu_Item *mi);
26 static void             on_menu_style_float(void *data, E_Menu *m, E_Menu_Item *mi);
27 static void             on_menu_style_horiz(void *data, E_Menu *m, E_Menu_Item *mi);
28 static void             on_menu_style_vert(void *data, E_Menu *m, E_Menu_Item *mi);
29 static void             on_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi);
30 static void             on_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
31 static void             on_menu_add(void *data, E_Menu *m, E_Menu_Item *mi);
32 
33 static Eina_Bool       _gadman_module_cb(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Module_Update *ev);
34 static int              _e_gadman_client_add(void *data EINA_UNUSED, E_Gadcon_Client *, const E_Gadcon_Client_Class *cc);
35 static void             _e_gadman_client_remove(void *data EINA_UNUSED, E_Gadcon_Client *gcc);
36 
37 static void             _e_gadman_handlers_add(void);
38 static void             _e_gadman_handler_del(void);
39 static Eina_Bool        _e_gadman_cb_zone_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
40 static E_Gadcon_Client *gadman_gadget_place(E_Gadcon_Client *gcc, const E_Gadcon_Client_Class *cc, E_Config_Gadcon_Client *cf, Gadman_Layer_Type layer, E_Zone *zone);
41 
42 static E_Gadcon        *gadman_gadcon_get(const E_Zone *zone, Gadman_Layer_Type layer);
43 static Eina_Bool gadman_locked;
44 Manager *Man = NULL;
45 static Eina_List *_gadman_hdls = NULL;
46 static Eina_Hash *_gadman_gadgets = NULL;
47 static Ecore_Job *gadman_reset_job = NULL;
48 
49 /* for locking geometry during our own move/resize */
50 static Eina_Bool mover_lock = EINA_FALSE;
51 
52 /* Implementation */
53 void
gadman_reset(void * d EINA_UNUSED)54 gadman_reset(void *d EINA_UNUSED)
55 {
56    E_Gadcon *gc;
57    unsigned int layer;
58    const Eina_List *l;
59    E_Zone *zone;
60 
61    E_FREE_FUNC(gadman_reset_job, ecore_job_del);
62    if (gadman_locked) return;
63    evas_event_freeze(e_comp->evas);
64    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
65      {
66         E_FREE_LIST(Man->gadcons[layer], e_object_del);
67         Man->gadgets[layer] = eina_list_free(Man->gadgets[layer]);
68         E_FREE_FUNC(Man->movers[layer], evas_object_del);
69      }
70    evas_object_hide(Man->overlay);
71    E_FREE_FUNC(Man->overlay, evas_object_del);
72    E_FREE_FUNC(Man->full_bg, evas_object_del);
73    if (_gadman_gadgets)
74      {
75         eina_hash_free_cb_set(_gadman_gadgets, (void *)eina_list_free);
76         eina_hash_free(_gadman_gadgets);
77      }
78    /* iterating through zones - and making gadmans on each */
79    EINA_LIST_FOREACH(e_comp->zones, l, zone)
80      {
81         const char *layer_name[] = {"gadman", "gadman_top"};
82 
83         for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
84           {
85              gc = _gadman_gadcon_new(layer_name[layer], layer, zone, Man->location[layer]);
86              Man->gadcons[layer] = eina_list_append(Man->gadcons[layer], gc);
87           }
88      }
89    _gadman_overlay_create();
90 
91    _gadman_gadgets = eina_hash_string_superfast_new(NULL);
92    gadman_update_bg();
93    Man->visible = !Man->visible;
94    {
95       int prev = Man->conf->anim_bg;
96       Man->conf->anim_bg = 0;
97       gadman_gadgets_toggle();
98       Man->conf->anim_bg = prev;
99    }
100    edje_object_message_signal_process(Man->full_bg);
101    evas_event_thaw(e_comp->evas);
102 }
103 
104 void
gadman_init(E_Module * m)105 gadman_init(E_Module *m)
106 {
107    E_Gadcon_Location *location;
108 
109    /* Create Manager */
110    Man = calloc(1, sizeof(Manager));
111    if (!Man) return;
112 
113    Man->module = m;
114    gadman_locked = e_module_loading_get();
115    Man->width = e_comp->w;
116    Man->height = e_comp->h;
117 
118    /* create and register "desktop" location */
119    location = Man->location[GADMAN_LAYER_BG] = e_gadcon_location_new(_("Desktop"), E_GADCON_SITE_DESKTOP,
120                                     _e_gadman_client_add, (intptr_t*)(long)GADMAN_LAYER_BG,
121                                     _e_gadman_client_remove, NULL);
122    e_gadcon_location_set_icon_name(location, "preferences-desktop");
123    e_gadcon_location_register(location);
124 
125    /* create and register "desktop hover" location */
126    location = Man->location[GADMAN_LAYER_TOP] = e_gadcon_location_new(_("Desktop Overlay"), E_GADCON_SITE_DESKTOP,
127                                     _e_gadman_client_add, (intptr_t*)(long)GADMAN_LAYER_TOP,
128                                     _e_gadman_client_remove, NULL);
129    e_gadcon_location_set_icon_name(location, "preferences-desktop");
130    e_gadcon_location_register(location);
131 
132    _e_gadman_handlers_add();
133    if (!gadman_locked) gadman_reset_job = ecore_job_add(gadman_reset, NULL);
134 }
135 
136 void
gadman_shutdown(void)137 gadman_shutdown(void)
138 {
139    unsigned int layer;
140 
141    E_FREE_FUNC(gadman_reset_job, ecore_job_del);
142    _e_gadman_handler_del();
143 
144    gadman_gadget_edit_end(NULL, NULL, NULL, NULL);
145 
146    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
147      {
148         e_gadcon_location_unregister(Man->location[layer]);
149         E_FREE_LIST(Man->gadcons[layer], e_object_del);
150         evas_object_del(Man->movers[layer]);
151         Man->gadgets[layer] = eina_list_free(Man->gadgets[layer]);
152         e_gadcon_location_free(Man->location[layer]);
153      }
154 
155    eina_stringshare_del(Man->icon_name);
156 
157    /* free manager */
158    evas_object_hide(Man->overlay);
159    E_FREE_FUNC(Man->overlay, evas_object_del);
160    if (_gadman_gadgets)
161      {
162         eina_hash_free_cb_set(_gadman_gadgets, (void *)eina_list_free);
163         eina_hash_free(_gadman_gadgets);
164      }
165    _gadman_gadgets = NULL;
166    free(Man);
167 }
168 
169 void
gadman_populate_class(void * data,E_Gadcon * gc,const E_Gadcon_Client_Class * cc)170 gadman_populate_class(void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc)
171 {
172    Gadman_Layer_Type layer = (Gadman_Layer_Type)(long)data;
173    const Eina_List *l, *ll;
174    E_Config_Gadcon_Client *cf_gcc;
175    E_Gadcon_Client *gcc = NULL;
176 
177    EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
178      {
179         if ((!strcmp(cf_gcc->name, cc->name)) && (gc->cf->zone == gc->zone->num))
180           {
181              gcc = e_gadcon_client_find(gc, cf_gcc);
182              ll = eina_hash_find(_gadman_gadgets, cc->name);
183              if ((!gcc) || (ll && (!eina_list_data_find(ll, cf_gcc))))
184                gadman_gadget_place(gcc, cc, cf_gcc, layer, gc->zone);
185           }
186      }
187    gc->populated_classes = eina_list_append(gc->populated_classes, cc);
188 }
189 
190 static E_Gadcon *
gadman_gadcon_get(const E_Zone * zone,Gadman_Layer_Type layer)191 gadman_gadcon_get(const E_Zone *zone, Gadman_Layer_Type layer)
192 {
193    const Eina_List *l;
194    E_Gadcon *gc;
195 
196    EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
197      if (gc->zone == zone) return gc;
198    return NULL;
199 }
200 
201 static void
gadman_gadcon_place_job(E_Gadcon_Client * gcc)202 gadman_gadcon_place_job(E_Gadcon_Client *gcc)
203 {
204    _apply_widget_position(gcc);
205    if (gcc == gcc->gadcon->drag_gcc)
206      gadman_gadget_edit_start(gcc);
207    if (Man->visible || (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gcc->gadcon)))
208      e_gadcon_client_show(gcc);
209    else
210      e_gadcon_client_hide(gcc);
211 }
212 
213 static void
_gadman_gadget_free(void * data EINA_UNUSED,void * obj)214 _gadman_gadget_free(void *data EINA_UNUSED, void *obj)
215 {
216    E_Gadcon_Client *gcc = obj;
217    Eina_List *l;
218    int layer;
219    Eina_Bool edit;
220 
221    layer = gcc->gadcon->id - ID_GADMAN_LAYER_BASE;
222 //   edje_object_part_unswallow(gcc->o_frame, gcc->o_base);
223    if (gcc->cf)
224      {
225         Man->gadgets[layer] = eina_list_remove(Man->gadgets[layer], gcc->cf);
226         l = eina_hash_find(_gadman_gadgets, gcc->name);
227         if (l)
228           {
229              eina_hash_set(_gadman_gadgets, gcc->name, eina_list_remove(l, gcc->cf));
230           }
231         gcc->cf = NULL;
232      }
233    edit = (gcc == gcc->gadcon->drag_gcc) || (Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE] == gcc);
234    if (!edit) return;
235    gcc->gadcon->editing = 1; // may get unset from a dialog, force here to prevent crash
236    gadman_gadget_edit_end(NULL, NULL, NULL, NULL);
237 }
238 
239 static void
_gadman_gadget_size_hints_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)240 _gadman_gadget_size_hints_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
241 {
242    E_Gadcon_Client *gcc = data;
243    int w, h;
244 
245    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
246    /* size hints change for either min or aspect */
247    if (gcc->min.w || gcc->min.h)
248      {
249         w = MAX(w, gcc->min.w);
250         h = MAX(h, gcc->min.h);
251      }
252    if (gcc->aspect.w && gcc->aspect.h)
253      {
254         w = MAX(w, gcc->aspect.w);
255         h = MAX(h, gcc->aspect.h);
256      }
257    evas_object_resize(gcc->o_frame, w, h);
258    _save_widget_position(gcc);
259 }
260 
261 static E_Gadcon_Client *
gadman_gadget_place(E_Gadcon_Client * gcc,const E_Gadcon_Client_Class * cc,E_Config_Gadcon_Client * cf,Gadman_Layer_Type layer,E_Zone * zone)262 gadman_gadget_place(E_Gadcon_Client *gcc, const E_Gadcon_Client_Class *cc, E_Config_Gadcon_Client *cf, Gadman_Layer_Type layer, E_Zone *zone)
263 {
264    E_Gadcon *gc;
265    Eina_List *l;
266 
267    if (!cf->name) return NULL;
268 
269    gc = gadman_gadcon_get(zone, layer);
270    if (!cc)
271      {
272         EINA_LIST_FOREACH(gc->populated_classes, l, cc)
273           {
274              if (!strcmp(cc->name, cf->name))
275                break;
276              else
277                cc = NULL;
278           }
279      }
280 
281    /* Find provider */
282    if (!cc)
283      {
284         e_gadcon_client_queue(gc, cf);
285         e_gadcon_custom_populate_request(gc);
286         return NULL;
287      }
288 
289    /* init Gadcon_Client */
290    if (!gcc)
291      {
292         gcc = cc->func.init(gc, cf->name, cf->id, cc->default_style);
293         if (!gcc) return NULL;
294         e_object_delfn_add(E_OBJECT(gcc), _gadman_gadget_free, NULL);
295         gcc->cf = cf;
296         gcc->client_class = cc;
297 
298         /* Call the client orientation function */
299         if (cc->func.orient)
300           cc->func.orient(gcc, gcc->cf->orient);
301      }
302 
303    Man->gadgets[layer] = eina_list_append(Man->gadgets[layer], cf);
304 
305    //printf("Place Gadget %s (style: %s id: %s) (gadcon: %s)\n", gcc->name, cf->style, cf->id, gc->name);
306 
307    /* create frame */
308    gcc->o_frame = edje_object_add(gc->evas);
309    e_theme_edje_object_set(gcc->o_frame, "base/theme/gadman", "e/gadman/frame");
310 
311    if ((cf->style) && (!strcmp(cf->style, E_GADCON_CLIENT_STYLE_INSET)))
312      edje_object_signal_emit(gcc->o_frame, "e,state,visibility,inset", "e");
313    else
314      edje_object_signal_emit(gcc->o_frame, "e,state,visibility,plain", "e");
315 
316    /* swallow the client inside the frame */
317    edje_object_part_swallow(gcc->o_frame, "e.swallow.content", gcc->o_base);
318    evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_DOWN,
319                                   on_frame_click, gcc);
320    evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
321                                   _gadman_gadget_size_hints_cb, gcc);
322 
323    gcc->hidden = 1;
324    if (gcc->gadcon->id == ID_GADMAN_LAYER_TOP)
325      {
326         edje_object_signal_emit(gcc->o_frame, "e,state,visibility,hide", "e");
327         evas_object_layer_set(gcc->o_frame, E_LAYER_POPUP);
328      }
329    else
330      evas_object_layer_set(gcc->o_frame, E_LAYER_DESKTOP);
331    if (cc->name)
332      {
333         l = eina_hash_find(_gadman_gadgets, cc->name);
334         eina_hash_set(_gadman_gadgets, cc->name, eina_list_append(l, gcc->cf));
335      }
336    ecore_job_add((Ecore_Cb)gadman_gadcon_place_job, gcc);
337 
338    return gcc;
339 }
340 
341 E_Gadcon_Client *
gadman_gadget_add(const E_Gadcon_Client_Class * cc,E_Gadcon_Client * gcc,Gadman_Layer_Type layer)342 gadman_gadget_add(const E_Gadcon_Client_Class *cc, E_Gadcon_Client *gcc, Gadman_Layer_Type layer)
343 {
344    return _gadman_gadget_add(cc, layer, gcc->cf);
345 }
346 
347 static E_Gadcon_Client *
_gadman_gadget_add(const E_Gadcon_Client_Class * cc,Gadman_Layer_Type layer,E_Config_Gadcon_Client * src_cf)348 _gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer, E_Config_Gadcon_Client *src_cf)
349 {
350    E_Config_Gadcon_Client *cf = NULL;
351    E_Gadcon_Client *gcc = NULL;
352    E_Gadcon *gc;
353    int w, h;
354 
355    gc = gadman_gadcon_get(e_zone_current_get(),
356                           layer);
357 
358    /* Create Config_Gadcon_Client */
359    cf = e_gadcon_client_config_new(gc, cc->name);
360    if (cf)
361      {
362         if (!src_cf)
363           {
364              cf->style = eina_stringshare_add(cc->default_style);
365              cf->geom.pos_x = DEFAULT_POS_X;
366              cf->geom.pos_y = DEFAULT_POS_Y;
367              cf->geom.size_w = DEFAULT_SIZE_W;
368              cf->geom.size_h = DEFAULT_SIZE_H;
369           }
370         else
371           {
372              cf->style = eina_stringshare_add(src_cf->style);
373              cf->geom.pos_x = src_cf->geom.pos_x;
374              cf->geom.pos_y = src_cf->geom.pos_y;
375              cf->geom.size_w = src_cf->geom.size_w;
376              cf->geom.size_h = src_cf->geom.size_h;
377           }
378      }
379 
380    /* Place the new gadget */
381    if (cf)
382      gcc = gadman_gadget_place(NULL, cc, cf, layer, gc->zone);
383    if (!gcc) return NULL;
384 
385    /* Respect Aspect */
386    evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
387    if (gcc->aspect.w && gcc->aspect.h)
388      {
389         if (gcc->aspect.w > gcc->aspect.h)
390           w = ((float)h / (float)gcc->aspect.h) * (gcc->aspect.w);
391         else
392           h = ((float)w / (float)gcc->aspect.w) * (gcc->aspect.h);
393         if (h < gcc->min.h) h = gcc->min.h;
394         if (w < gcc->min.w) w = gcc->min.w;
395         evas_object_resize(gcc->o_frame, w, h);
396      }
397 
398    return gcc;
399 }
400 
401 static void
gadman_edit(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)402 gadman_edit(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
403 {
404    _apply_widget_position(data);
405 }
406 
407 static void
_gadman_gadget_edit_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)408 _gadman_gadget_edit_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
409 {
410    int w, h;
411    if (mover_lock) return;
412    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
413    evas_object_resize(_get_mover(data), w, h);
414 }
415 
416 static void
_gadman_gadget_edit_move_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)417 _gadman_gadget_edit_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
418 {
419    int x, y;
420    if (mover_lock) return;
421    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
422    evas_object_move(_get_mover(data), x, y);
423 }
424 
425 void
gadman_gadget_edit_start(E_Gadcon_Client * gcc)426 gadman_gadget_edit_start(E_Gadcon_Client *gcc)
427 {
428    E_Gadcon *gc;
429    Evas_Object *mover;
430    Eina_List *l;
431    int x, y, w, h;
432 
433    if (Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE] == gcc) return;
434    else if (Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE])
435      e_object_unref(E_OBJECT(Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE]));
436 
437    if (gcc->gadcon->id - ID_GADMAN_LAYER_BASE == 1)
438      {
439         /* don't set edit if overlay isn't visible */
440         if (!Man->visible) return;
441      }
442    EINA_LIST_FOREACH(Man->gadcons[gcc->gadcon->id - ID_GADMAN_LAYER_BASE], l, gc)
443      gc->editing = 1;
444    gc = gcc->gadcon;
445 
446    e_object_ref(E_OBJECT(gcc));
447    //INF("START: %u", e_object_ref_get((void*)gcc));
448 
449    /* Move/resize the correct mover */
450    mover = _get_mover(gcc);
451    if (!mover) return;
452    evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
453    evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_RESIZE, _gadman_gadget_edit_resize_cb, gcc);
454    evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOVE, _gadman_gadget_edit_move_cb, gcc);
455    Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE] = gcc;
456 
457    evas_object_move(mover, x, y);
458    evas_object_resize(mover, w, h);
459    evas_object_raise(mover);
460    if (Man->visible || (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
461      evas_object_show(mover);
462    evas_object_event_callback_del(mover, EVAS_CALLBACK_HIDE, gadman_edit);
463    evas_object_event_callback_add(mover, EVAS_CALLBACK_HIDE, gadman_edit, gcc);
464 }
465 
466 void
gadman_gadget_edit_end(void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)467 gadman_gadget_edit_end(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
468 {
469    unsigned int layer;
470    E_Gadcon_Client *drag_gcc = NULL;
471 
472    for (layer = GADMAN_LAYER_COUNT - 1; layer < GADMAN_LAYER_COUNT; layer--)
473      {
474         const Eina_List *l;
475         E_Gadcon *gc;
476 
477         gc = eina_list_data_get(Man->gadcons[layer]);
478         if (!gc) continue;
479         if (!gc->editing) continue;
480 
481         evas_object_event_callback_del(Man->movers[layer], EVAS_CALLBACK_HIDE, gadman_edit);
482         evas_object_hide(Man->movers[layer]);
483 
484         EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
485           gc->editing = 0;
486         drag_gcc = Man->drag_gcc[layer];
487         if (drag_gcc)
488           {
489              evas_object_event_callback_del_full(drag_gcc->o_frame, EVAS_CALLBACK_RESIZE, _gadman_gadget_edit_resize_cb, drag_gcc);
490              evas_object_event_callback_del_full(drag_gcc->o_frame, EVAS_CALLBACK_MOVE, _gadman_gadget_edit_move_cb, drag_gcc);
491           }
492         Man->drag_gcc[layer] = NULL;
493         break;
494      }
495    if (!drag_gcc) return;
496    drag_gcc->gadcon->drag_gcc = NULL;
497    _save_widget_position(drag_gcc);
498    if (!e_object_is_del(E_OBJECT(drag_gcc)))
499      e_object_unref(E_OBJECT(drag_gcc));
500    //INF("END: %d:%u", e_object_is_del(E_OBJECT(drag_gcc)), e_object_ref_get((void*)drag_gcc));
501 }
502 
503 void
gadman_gadgets_show(void)504 gadman_gadgets_show(void)
505 {
506    Eina_List *l, *ll;
507    E_Gadcon *gc;
508    E_Gadcon_Client *gcc;
509    Eina_Bool editing = EINA_FALSE;
510 
511    Man->visible = 1;
512    evas_object_show(Man->overlay);
513 
514    if (Man->conf->bg_type == BG_STD)
515      {
516         if (Man->conf->anim_bg)
517           edje_object_signal_emit(Man->full_bg,
518                                   "e,state,visibility,show", "e");
519         else
520           edje_object_signal_emit(Man->full_bg,
521                                   "e,state,visibility,show,now", "e");
522      }
523    else
524      {
525         if (Man->conf->anim_bg)
526           edje_object_signal_emit(Man->full_bg,
527                                   "e,state,visibility,show,custom", "e");
528         else
529           edje_object_signal_emit(Man->full_bg,
530                                   "e,state,visibility,show,custom,now", "e");
531      }
532 
533    /* Showing top gadgets */
534    EINA_LIST_FOREACH(Man->gadcons[GADMAN_LAYER_TOP], l, gc)
535      {
536         EINA_LIST_FOREACH(gc->clients, ll, gcc)
537           {
538              if (Man->conf->anim_gad)
539                edje_object_signal_emit(gcc->o_frame,
540                                        "e,state,visibility,show", "e");
541              else
542                edje_object_signal_emit(gcc->o_frame,
543                                        "e,state,visibility,show,now", "e");
544              e_gadcon_client_show(gcc);
545           }
546         gc->drop_handler->hidden = 0;
547         editing = gc->editing;
548      }
549    if (editing && gcc) evas_object_show(_get_mover(gcc));
550 }
551 
552 void
gadman_gadgets_hide(void)553 gadman_gadgets_hide(void)
554 {
555    Eina_List *l, *ll;
556    E_Gadcon *gc;
557    E_Gadcon_Client *gcc;
558    Eina_Bool editing = EINA_FALSE;
559 
560    Man->visible = 0;
561 
562    if (Man->conf->bg_type == BG_STD)
563      {
564         if (Man->conf->anim_bg)
565           edje_object_signal_emit(Man->full_bg,
566                                   "e,state,visibility,hide", "e");
567         else
568           edje_object_signal_emit(Man->full_bg,
569                                   "e,state,visibility,hide,now", "e");
570      }
571    else
572      {
573         if (Man->conf->anim_bg)
574           edje_object_signal_emit(Man->full_bg,
575                                   "e,state,visibility,hide,custom", "e");
576         else
577           edje_object_signal_emit(Man->full_bg,
578                                   "e,state,visibility,hide,custom,now", "e");
579      }
580 
581    /* Hiding top gadgets */
582    EINA_LIST_FOREACH(Man->gadcons[GADMAN_LAYER_TOP], l, gc)
583      {
584         gc->drop_handler->hidden = 1;
585         editing = gc->editing;
586         EINA_LIST_FOREACH(gc->clients, ll, gcc)
587           {
588              if (Man->conf->anim_gad)
589                edje_object_signal_emit(gcc->o_frame,
590                                        "e,state,visibility,hide", "e");
591              else
592                edje_object_signal_emit(gcc->o_frame,
593                                        "e,state,visibility,hide,now", "e");
594              e_gadcon_client_hide(gcc);
595           }
596      }
597    if (editing)
598      gadman_gadget_edit_end(NULL, NULL, NULL, NULL);
599 }
600 
601 void
gadman_gadgets_toggle(void)602 gadman_gadgets_toggle(void)
603 {
604    if (Man->visible)
605      gadman_gadgets_hide();
606    else
607      gadman_gadgets_show();
608 }
609 
610 void
gadman_update_bg(void)611 gadman_update_bg(void)
612 {
613    Evas_Object *obj;
614 
615    if (!Man->gadcons[GADMAN_LAYER_TOP]) return;
616    if (!Man->conf) return;
617    obj = edje_object_part_swallow_get(Man->full_bg, "e.swallow.bg");
618    if (obj)
619      {
620         edje_object_part_unswallow(Man->full_bg, obj);
621         evas_object_del(obj);
622      }
623 
624    switch (Man->conf->bg_type)
625      {
626       case BG_STD:
627       case BG_TRANS:
628         break;
629 
630       case BG_COLOR:
631         {
632            double r, g, b;
633 
634            r = (double)Man->conf->color_r * (200. / 255.);
635            g = (double)Man->conf->color_g * (200. / 255.);
636            b = (double)Man->conf->color_b * (200. / 255.);
637            obj = evas_object_rectangle_add(e_comp->evas);
638            evas_object_color_set(obj, lround(r), lround(g), lround(b), 200);
639            edje_object_part_swallow(Man->full_bg, "e.swallow.bg", obj);
640         }
641         break;
642 
643       case BG_CUSTOM:
644         if (eina_str_has_extension(Man->conf->custom_bg, ".edj"))
645           {
646              //THIS IS FOR E backgrounds
647              obj = edje_object_add(e_comp->evas);
648              edje_object_file_set(obj, Man->conf->custom_bg,
649                                   "e/desktop/background");
650           }
651         else
652           {
653              //THIS IS FOR A NORMAL IMAGE
654              obj = evas_object_image_add(e_comp->evas);
655              evas_object_image_file_set(obj, Man->conf->custom_bg, NULL);
656              evas_object_image_fill_set(obj, 0, 0, e_comp->w, e_comp->h);
657           }
658         edje_object_part_swallow(Man->full_bg, "e.swallow.bg", obj);
659         break;
660 
661       default:
662         break;
663      }
664 }
665 
666 static void
_gadman_gadcon_free(E_Gadcon * gc)667 _gadman_gadcon_free(E_Gadcon *gc)
668 {
669    e_gadcon_unpopulate(gc);
670    e_gadcon_custom_del(gc);
671 
672    /* free gadcons */
673    e_config->gadcons = eina_list_remove(e_config->gadcons, gc);
674    eina_stringshare_del(gc->name);
675 
676    if (gc->config_dialog) e_object_del(E_OBJECT(gc->config_dialog));
677    eina_list_free(gc->populated_classes);
678    if (gc->drop_handler) e_drop_handler_del(gc->drop_handler);
679    free(gc);
680 }
681 
682 static void
_gadman_gadcon_dnd_enter_cb(E_Gadcon * gc,E_Gadcon_Client * gcc)683 _gadman_gadcon_dnd_enter_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
684 {
685 
686    /* only use this for dragging gadcons around the desktop */
687    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
688        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
689      return;
690    if (gc != gcc->gadcon) return;
691    //INF("ENTER: %u", e_object_ref_get((void*)gcc));
692    gadman_gadget_edit_start(gcc);
693 }
694 
695 static void
_gadman_gadcon_dnd_leave_cb(E_Gadcon * gc,E_Gadcon_Client * gcc)696 _gadman_gadcon_dnd_leave_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
697 {
698    unsigned int layer;
699    E_Gadcon_Client *drag_gcc = NULL;
700 
701    /* only use this for dragging gadcons around the desktop */
702    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
703        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
704      return;
705    if (gc != gcc->gadcon) return;
706    //INF("LEAVE: %u", e_object_ref_get((void*)gcc));
707    Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE] = NULL;
708    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
709      {
710         const Eina_List *l;
711 
712         evas_object_event_callback_del(Man->movers[layer], EVAS_CALLBACK_HIDE, gadman_edit);
713         evas_object_hide(Man->movers[layer]);
714 
715         EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
716           {
717              gc->editing = 0;
718              drag_gcc = gc->drag_gcc;
719           }
720      }
721    /* this is slightly different from edit_end because we don't save the position or unset the drag gcc */
722    if (!drag_gcc) return;
723    e_object_unref(E_OBJECT(drag_gcc));
724 }
725 
726 static void
_gadman_gadcon_dnd_move_cb(E_Gadcon * gc,E_Gadcon_Client * gcc)727 _gadman_gadcon_dnd_move_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
728 {
729    Evas_Object *mover;
730    E_Zone *zone;
731    int x, y, mx, my;
732    int ox, oy, ow, oh;
733 
734    if (gc != gcc->gadcon) return;
735    /* only use this for dragging gadcons around the desktop */
736    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
737        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
738      return;
739 
740    mover = _get_mover(gcc);
741    evas_object_geometry_get(gcc->o_frame, &x, &y, NULL, NULL);
742    evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
743 
744    /* don't go out of the screen */
745    x = MAX(x, gcc->dx), y = MAX(y, gcc->dy);
746 
747    /* adjust in case one screen is larger than another */
748    zone = e_gadcon_zone_get(gc);
749    mx = MIN(Man->width, zone->x + zone->w), my = MIN(Man->height, zone->y + zone->h);
750    x = MIN(x, mx - ow + gcc->dx), y = MIN(y, my - oh + gcc->dy);
751 
752    evas_object_move(gcc->o_frame, x - gcc->dx, y - gcc->dy);
753    evas_object_move(mover, x - gcc->dx, y - gcc->dy);
754    evas_object_raise(gcc->o_frame);
755    evas_object_raise(mover);
756    _save_widget_position(gcc);
757 }
758 
759 static void
_gadman_gadcon_dnd_drop_cb(E_Gadcon * gc,E_Gadcon_Client * gcc)760 _gadman_gadcon_dnd_drop_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
761 {
762    E_Config_Gadcon_Client *cf;
763    E_Zone *dst_zone = NULL;
764    E_Gadcon *dst_gadcon;
765    Evas_Object *mover;
766    int gx, gy;
767 
768    if (gc != gcc->gadcon) return;
769    /* only use this for dragging gadcons around the desktop */
770    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
771        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
772      return;
773 
774    gcc->moving = 0;
775    gcc->dx = gcc->dy = 0;
776 
777    /* checking if zone was changed for dragged gadget */
778    mover = _get_mover(gcc);
779    evas_object_geometry_get(mover, &gx, &gy, NULL, NULL);
780    dst_zone = e_comp_zone_xy_get(gx, gy);
781    if (dst_zone && (gcc->gadcon->zone != dst_zone))
782      {
783         unsigned int layer = gcc->gadcon->id - ID_GADMAN_LAYER_BASE;
784         cf = gcc->cf;
785         gcc->gadcon->cf->clients = eina_list_remove(gcc->gadcon->cf->clients, cf);
786         dst_gadcon = gadman_gadcon_get(dst_zone, layer);
787         if (dst_gadcon)
788           {
789              dst_gadcon->cf->clients = eina_list_append(dst_gadcon->cf->clients, cf);
790           }
791      }
792    _save_widget_position(gcc);
793    e_config_save_queue();
794 }
795 
796 static void
_gadman_overlay_create(void)797 _gadman_overlay_create(void)
798 {
799    Eina_List *l;
800    E_Gadcon *gc;
801 
802    /* create full background object */
803    Man->full_bg = edje_object_add(e_comp->evas);
804    evas_object_geometry_set(Man->full_bg, 0, 0, e_comp->w, e_comp->h);
805    e_theme_edje_object_set(Man->full_bg, "base/theme/gadman",
806                            "e/gadman/full_bg");
807    edje_object_signal_callback_add(Man->full_bg, "mouse,down,*",
808                                    "grabber", on_bg_click, NULL);
809    edje_object_signal_callback_add(Man->full_bg, "e,action,hide,stop",
810                                    "", on_hide_stop, NULL);
811 
812    Man->overlay = e_comp_object_util_add(Man->full_bg, E_COMP_OBJECT_TYPE_NONE);
813    evas_object_layer_set(Man->overlay, E_LAYER_CLIENT_FULLSCREEN);
814 
815    /* create placeholder rect to maintain our dnd stacking layer */
816    EINA_LIST_FOREACH(Man->gadcons[GADMAN_LAYER_TOP], l, gc)
817      {
818         gc->drop_handler->base = Man->overlay;
819         gc->drop_handler->hidden = 1;
820      }
821 }
822 
823 static E_Gadcon *
_gadman_gadcon_new(const char * name,Gadman_Layer_Type layer,E_Zone * zone,E_Gadcon_Location * loc)824 _gadman_gadcon_new(const char *name, Gadman_Layer_Type layer, E_Zone *zone, E_Gadcon_Location *loc)
825 {
826    const Eina_List *l;
827    E_Gadcon *gc;
828    E_Config_Gadcon *cg;
829 
830    /* Create Gadcon */
831    gc = E_OBJECT_ALLOC(E_Gadcon, E_GADCON_TYPE, _gadman_gadcon_free);
832    if (!gc) return NULL;
833 
834    gc->name = eina_stringshare_add(name);
835    gc->layout_policy = E_GADCON_LAYOUT_POLICY_PANEL;
836    gc->orient = E_GADCON_ORIENT_FLOAT;
837    gc->location = loc;
838 
839    gc->evas = e_comp->evas;
840    e_gadcon_ecore_evas_set(gc, e_comp->ee);
841    e_gadcon_xdnd_window_set(gc, e_comp->ee_win);
842    e_gadcon_dnd_window_set(gc, e_comp->ee_win);
843 
844    e_gadcon_drop_handler_add(gc, _gadman_gadcon_dnd_enter_cb, _gadman_gadcon_dnd_leave_cb,
845                              _gadman_gadcon_dnd_move_cb, _gadman_gadcon_dnd_drop_cb,
846                              zone->x, zone->y, zone->w, zone->h);
847    e_gadcon_zone_set(gc, zone);
848    e_gadcon_util_menu_attach_func_set(gc, _attach_menu, NULL);
849    e_gadcon_populate_callback_set(gc, gadman_populate_class, (void *)layer);
850 
851    gc->id = ID_GADMAN_LAYER_BASE + layer;
852    gc->edje.o_parent = NULL;
853    gc->edje.swallow_name = NULL;
854    gc->shelf = NULL;
855    gc->toolbar = NULL;
856    gc->editing = 0;
857    gc->o_container = NULL;
858    gc->frame_request.func = NULL;
859    gc->resize_request.func = NULL;
860    gc->min_size_request.func = NULL;
861 
862    /* Search for existing gadcon config */
863    gc->cf = NULL;
864    EINA_LIST_FOREACH(e_config->gadcons, l, cg)
865      {
866         if ((!strcmp(cg->name, name)) && (cg->zone == zone->num))
867           {
868              gc->cf = cg;
869              break;
870           }
871      }
872 
873    /* ... or create a new one */
874    if (!gc->cf)
875      {
876         gc->cf = E_NEW(E_Config_Gadcon, 1);
877         gc->cf->name = eina_stringshare_add(name);
878         gc->cf->id = gc->id;
879         gc->cf->zone = zone->num;
880         gc->cf->clients = NULL;
881         e_config->gadcons = eina_list_append(e_config->gadcons, gc->cf);
882         e_config_save_queue();
883      }
884 
885    e_gadcon_custom_new(gc);
886    e_gadcon_custom_populate_request(gc);
887 
888    if (!Man->movers[layer])
889      Man->movers[layer] = _create_mover(gc);
890 
891    return gc;
892 }
893 
894 static void
_mover_del(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)895 _mover_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
896 {
897    unsigned int layer;
898 
899    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
900      {
901         if (Man->movers[layer] != obj) continue;
902         Man->movers[layer] = NULL;
903         return;
904      }
905 }
906 
907 static Evas_Object *
_create_mover(E_Gadcon * gc)908 _create_mover(E_Gadcon *gc)
909 {
910    Evas_Object *mover;
911 
912    /* create mover object */
913    mover = edje_object_add(gc->evas);
914    if (gc->id == ID_GADMAN_LAYER_BG)
915      {
916         evas_object_layer_set(mover, E_LAYER_DESKTOP);
917         evas_object_event_callback_add(mover, EVAS_CALLBACK_DEL, _mover_del, NULL);
918      }
919    else
920      evas_object_layer_set(mover, E_LAYER_MENU);
921    e_theme_edje_object_set(mover, "base/theme/gadman", "e/gadman/control");
922 
923    edje_object_signal_callback_add(mover, "e,action,move,start", "",
924                                    on_move, (void *)DRAG_START);
925    edje_object_signal_callback_add(mover, "mouse,down,3", "*",
926                                    gadman_gadget_edit_end, NULL);
927 
928    edje_object_signal_callback_add(mover, "e,action,resize,left,start", "",
929                                    on_left, (void *)DRAG_START);
930    edje_object_signal_callback_add(mover, "e,action,resize,left,stop", "",
931                                    on_left, (void *)DRAG_STOP);
932    edje_object_signal_callback_add(mover, "e,action,resize,left,go", "",
933                                    on_left, (void *)DRAG_MOVE);
934    edje_object_signal_callback_add(mover, "e,action,resize,down,start", "",
935                                    on_down, (void *)DRAG_START);
936    edje_object_signal_callback_add(mover, "e,action,resize,down,stop", "",
937                                    on_down, (void *)DRAG_STOP);
938    edje_object_signal_callback_add(mover, "e,action,resize,down,go", "",
939                                    on_down, (void *)DRAG_MOVE);
940    edje_object_signal_callback_add(mover, "e,action,resize,right,start", "",
941                                    on_right, (void *)DRAG_START);
942    edje_object_signal_callback_add(mover, "e,action,resize,right,stop", "",
943                                    on_right, (void *)DRAG_STOP);
944    edje_object_signal_callback_add(mover, "e,action,resize,right,go", "",
945                                    on_right, (void *)DRAG_MOVE);
946    edje_object_signal_callback_add(mover, "e,action,resize,up,start", "",
947                                    on_top, (void *)DRAG_START);
948    edje_object_signal_callback_add(mover, "e,action,resize,up,stop", "",
949                                    on_top, (void *)DRAG_STOP);
950    edje_object_signal_callback_add(mover, "e,action,resize,up,go", "",
951                                    on_top, (void *)DRAG_MOVE);
952 
953    return mover;
954 }
955 
956 static Evas_Object *
_get_mover(E_Gadcon_Client * gcc)957 _get_mover(E_Gadcon_Client *gcc)
958 {
959    return Man->movers[gcc->gadcon->id - ID_GADMAN_LAYER_BASE];
960 }
961 
962 static void
_save_widget_position(E_Gadcon_Client * gcc)963 _save_widget_position(E_Gadcon_Client *gcc)
964 {
965    int x, y, w, h;
966 
967    evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
968    x -= gcc->gadcon->zone->x, y -= gcc->gadcon->zone->y;
969    gcc->config.pos_x = (double)x / (double)gcc->gadcon->zone->w;
970    gcc->config.pos_y = (double)y / (double)gcc->gadcon->zone->h;
971    gcc->config.size_w = (double)w / (double)gcc->gadcon->zone->w;
972    gcc->config.size_h = (double)h / (double)gcc->gadcon->zone->h;
973    if (gcc->cf)
974      {
975         gcc->cf->geom.pos_x = gcc->config.pos_x;
976         gcc->cf->geom.pos_y = gcc->config.pos_y;
977         gcc->cf->geom.size_w = gcc->config.size_w;
978         gcc->cf->geom.size_h = gcc->config.size_h;
979         e_config_save_queue();
980      }
981 }
982 
983 static void
_apply_widget_position(E_Gadcon_Client * gcc)984 _apply_widget_position(E_Gadcon_Client *gcc)
985 {
986    int x, y, w, h;
987    E_Zone *zone;
988    Evas_Object *mover;
989 
990    /* Obtain zone from parent gadcon */
991    zone = gcc->gadcon->zone;
992 
993    x = gcc->cf->geom.pos_x * zone->w + zone->x;
994    y = gcc->cf->geom.pos_y * zone->h + zone->y;
995    w = gcc->cf->geom.size_w * zone->w;
996    h = gcc->cf->geom.size_h * zone->h;
997 
998    /* something broke the config's geom, make it visible so it can be
999     * resized/deleted
1000     */
1001    if ((gcc->cf->geom.pos_x < 0) || (gcc->cf->geom.pos_y < 0) ||
1002        (!EINA_DBL_NONZERO(gcc->cf->geom.size_w)) || (!EINA_DBL_NONZERO(gcc->cf->geom.size_h)))
1003      {
1004         gcc->cf->style = eina_stringshare_add(gcc->client_class->default_style ?: E_GADCON_CLIENT_STYLE_INSET);
1005         gcc->style = eina_stringshare_ref(gcc->cf->style);
1006         gcc->cf->geom.pos_x = DEFAULT_POS_X;
1007         gcc->cf->geom.pos_y = DEFAULT_POS_Y;
1008         gcc->cf->geom.size_w = DEFAULT_SIZE_W;
1009         gcc->cf->geom.size_h = DEFAULT_SIZE_H;
1010         if (!strcmp(gcc->style, E_GADCON_CLIENT_STYLE_INSET))
1011           edje_object_signal_emit(gcc->o_frame, "e,state,visibility,inset", "e");
1012         else
1013           edje_object_signal_emit(gcc->o_frame, "e,state,visibility,plain", "e");
1014         _apply_widget_position(gcc);
1015         gadman_gadget_edit_start(gcc);
1016         return;
1017      }
1018 
1019    /* Respect min sizes */
1020    if (h < gcc->min.h) h = gcc->min.h;
1021    if (w < gcc->min.w) w = gcc->min.w;
1022    if (h < 1) h = 100;
1023    if (w < 1) w = 100;
1024 
1025    /* Respect zone marigin */
1026    if (x < zone->x) x = zone->x;
1027    if (y < zone->y) y = zone->y;
1028    if (x > (zone->x + zone->w)) x = zone->x;
1029    if (y > (zone->y + zone->h)) y = zone->y;
1030 
1031    if ((y + h) > (zone->y + zone->h + MIN_VISIBLE_MARIGIN))
1032      h = ((zone->y + zone->h + MIN_VISIBLE_MARIGIN) - y);
1033    if ((x + w) > (zone->x + zone->w + MIN_VISIBLE_MARIGIN))
1034      w = ((zone->x + zone->w + MIN_VISIBLE_MARIGIN) - x);
1035 
1036    evas_object_move(gcc->o_frame, x, y);
1037    evas_object_resize(gcc->o_frame, w, h);
1038 
1039    if (Man->drag_gcc[gcc->gadcon->id - ID_GADMAN_LAYER_BASE] != gcc) return;
1040    /* Move/resize the correct mover */
1041    mover = _get_mover(gcc);
1042    if (!mover) return;
1043    evas_object_move(mover, x, y);
1044    evas_object_resize(mover, w, h);
1045 }
1046 
1047 static void
_attach_menu(void * data EINA_UNUSED,E_Gadcon_Client * gcc,E_Menu * menu)1048 _attach_menu(void *data EINA_UNUSED, E_Gadcon_Client *gcc, E_Menu *menu)
1049 {
1050    E_Menu *mn;
1051    E_Menu_Item *mi;
1052 
1053    //printf("Attach menu (gcc: %x id: %s) [%s]\n", gcc, gcc->cf->id, gcc->cf->style);
1054    if (!gcc) return;
1055 
1056    if (e_menu_item_nth(menu, 0))
1057      {
1058         mi = e_menu_item_new(menu);
1059         e_menu_item_separator_set(mi, 1);
1060      }
1061 
1062    /* Move / resize*/
1063    mi = e_menu_item_new(menu);
1064    e_menu_item_label_set(mi, _("Begin move/resize"));
1065    e_util_menu_item_theme_icon_set(mi, "transform-scale");
1066    e_menu_item_callback_set(mi, on_menu_edit, gcc);
1067 
1068    /* plain / inset */
1069    if (gcc->cf)
1070      {
1071         if (!gcc->cf->style)
1072           gcc->cf->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_INSET);
1073 
1074         mn = e_menu_new();
1075         mi = e_menu_item_new(mn);
1076         e_menu_item_label_set(mi, _("Plain"));
1077         e_menu_item_radio_set(mi, 1);
1078         e_menu_item_radio_group_set(mi, 1);
1079         if (!strcmp(gcc->cf->style, E_GADCON_CLIENT_STYLE_PLAIN))
1080           e_menu_item_toggle_set(mi, 1);
1081         e_menu_item_callback_set(mi, on_menu_style_plain, gcc);
1082 
1083         mi = e_menu_item_new(mn);
1084         e_menu_item_label_set(mi, _("Inset"));
1085         e_menu_item_radio_set(mi, 1);
1086         e_menu_item_radio_group_set(mi, 1);
1087         if (!strcmp(gcc->cf->style, E_GADCON_CLIENT_STYLE_INSET))
1088           e_menu_item_toggle_set(mi, 1);
1089         e_menu_item_callback_set(mi, on_menu_style_inset, gcc);
1090 
1091         mi = e_menu_item_new(mn);
1092         e_menu_item_separator_set(mi, 1);
1093 
1094         /* orient */
1095         mi = e_menu_item_new(mn);
1096         e_menu_item_label_set(mi, _("Free"));
1097         e_menu_item_radio_set(mi, 1);
1098         e_menu_item_radio_group_set(mi, 2);
1099         if (gcc->cf->orient == E_GADCON_ORIENT_FLOAT)
1100           e_menu_item_toggle_set(mi, 1);
1101         if (!mi->toggle)
1102           e_menu_item_callback_set(mi, on_menu_style_float, gcc);
1103 
1104         mi = e_menu_item_new(mn);
1105         e_menu_item_label_set(mi, _("Horizontal"));
1106         e_menu_item_radio_set(mi, 1);
1107         e_menu_item_radio_group_set(mi, 2);
1108         if (gcc->cf->orient == E_GADCON_ORIENT_HORIZ)
1109           e_menu_item_toggle_set(mi, 1);
1110         if (!mi->toggle)
1111           e_menu_item_callback_set(mi, on_menu_style_horiz, gcc);
1112 
1113         mi = e_menu_item_new(mn);
1114         e_menu_item_label_set(mi, _("Vertical"));
1115         e_menu_item_radio_set(mi, 1);
1116         e_menu_item_radio_group_set(mi, 2);
1117         if (gcc->cf->orient == E_GADCON_ORIENT_VERT)
1118           e_menu_item_toggle_set(mi, 1);
1119         if (!mi->toggle)
1120           e_menu_item_callback_set(mi, on_menu_style_vert, gcc);
1121 
1122         mi = e_menu_item_new(menu);
1123         e_menu_item_label_set(mi, _("Appearance"));
1124         e_util_menu_item_theme_icon_set(mi, "preferences-look");
1125         e_menu_item_submenu_set(mi, mn);
1126         e_object_unref(E_OBJECT(mn));
1127 
1128         mi = e_menu_item_new(menu);
1129         e_menu_item_separator_set(mi, 1);
1130 
1131         e_gadcon_client_add_location_menu(gcc, menu);
1132      }
1133 
1134    /* Remove this gadgets */
1135    mi = e_menu_item_new(menu);
1136    e_menu_item_label_set(mi, _("Remove"));
1137    e_util_menu_item_theme_icon_set(mi, "list-remove");
1138    e_menu_item_callback_set(mi, on_menu_delete, gcc);
1139 
1140    /* Add other gadgets */
1141    mi = e_menu_item_new(menu);
1142    e_menu_item_separator_set(mi, 1);
1143 
1144    mi = e_menu_item_new(menu);
1145    e_menu_item_label_set(mi, _("Add other gadgets"));
1146    e_util_menu_item_theme_icon_set(mi, "list-add");
1147    e_menu_item_callback_set(mi, on_menu_add, gcc);
1148 }
1149 
1150 static void
on_menu_style_plain(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1151 on_menu_style_plain(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1152 {
1153    E_Gadcon_Client *gcc = data;
1154 
1155    eina_stringshare_replace(&gcc->style, E_GADCON_CLIENT_STYLE_PLAIN);
1156    eina_stringshare_replace(&gcc->cf->style, E_GADCON_CLIENT_STYLE_PLAIN);
1157 
1158    edje_object_signal_emit(gcc->o_frame, "e,state,visibility,plain", "e");
1159 
1160    e_config_save_queue();
1161 }
1162 
1163 static void
on_menu_style_inset(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1164 on_menu_style_inset(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1165 {
1166    E_Gadcon_Client *gcc = data;
1167 
1168    eina_stringshare_replace(&gcc->style, E_GADCON_CLIENT_STYLE_INSET);
1169    eina_stringshare_replace(&gcc->cf->style, E_GADCON_CLIENT_STYLE_INSET);
1170 
1171    edje_object_signal_emit(gcc->o_frame, "e,state,visibility,inset", "e");
1172 
1173    e_config_save_queue();
1174 }
1175 
1176 static void
_menu_style_orient(E_Gadcon_Client * gcc,E_Gadcon_Orient orient)1177 _menu_style_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient)
1178 {
1179    int ow, oh, w, h;
1180    Eina_Bool same;
1181 
1182    same = (((orient == E_GADCON_ORIENT_LEFT) && (gcc->cf->orient == E_GADCON_ORIENT_FLOAT)) ||
1183        ((orient == E_GADCON_ORIENT_FLOAT) && (gcc->cf->orient == E_GADCON_ORIENT_LEFT)));
1184    gcc->cf->orient = orient;
1185    evas_object_geometry_get(gcc->o_frame, NULL, NULL, &ow, &oh);
1186 
1187    if (gcc->client_class->func.orient)
1188      gcc->client_class->func.orient(gcc, orient);
1189 
1190    if (same)
1191      {
1192         w = ow, h = oh;
1193      }
1194    else
1195      {
1196         /* just flip aspect */
1197         w = oh;
1198         h = ow;
1199      }
1200 
1201    gcc->max.w = w;
1202    gcc->max.h = h;
1203    evas_object_resize(gcc->o_frame, w, h);
1204    _save_widget_position(gcc);
1205 }
1206 
1207 static void
on_menu_style_float(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1208 on_menu_style_float(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1209 {
1210    _menu_style_orient(data, E_GADCON_ORIENT_FLOAT);
1211 }
1212 
1213 static void
on_menu_style_horiz(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1214 on_menu_style_horiz(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1215 {
1216    _menu_style_orient(data, E_GADCON_ORIENT_HORIZ);
1217 }
1218 
1219 static void
on_menu_style_vert(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1220 on_menu_style_vert(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1221 {
1222    _menu_style_orient(data, E_GADCON_ORIENT_VERT);
1223 }
1224 
1225 static void
on_menu_edit(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1226 on_menu_edit(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1227 {
1228    gadman_gadget_edit_start(data);
1229 }
1230 
1231 static void
on_menu_add(void * data EINA_UNUSED,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1232 on_menu_add(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1233 {
1234    if (Man->visible)
1235      gadman_gadgets_hide();
1236    e_configure_registry_call("extensions/gadman", NULL, NULL);
1237 }
1238 
1239 static void
on_menu_delete(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)1240 on_menu_delete(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
1241 {
1242    E_Gadcon_Client *gcc = data;
1243    e_gadcon_client_config_del(gcc->gadcon->cf, gcc->cf);
1244    e_object_del(data);
1245    e_config_save_queue();
1246 }
1247 
1248 static void
on_frame_click(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1249 on_frame_click(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1250 {
1251    Evas_Event_Mouse_Down *ev;
1252    E_Gadcon_Client *gcc;
1253 
1254    ev = event_info;
1255 
1256    gcc = data;
1257 
1258    if (ev->button == 5)
1259      {
1260         E_Menu *m;
1261         int cx, cy, cw, ch;
1262 
1263         m = e_menu_new();
1264         m = e_gadcon_client_util_menu_items_append(gcc, m, 0);
1265         gcc->menu = m;
1266         e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, &cw, &ch);
1267         e_menu_activate_mouse(m,
1268                               e_zone_current_get(),
1269                               cx + ev->output.x, cy + ev->output.y, 1, 1,
1270                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
1271         evas_event_feed_mouse_up(gcc->gadcon->evas, ev->button,
1272                                  EVAS_BUTTON_NONE, ev->timestamp, NULL);
1273      }
1274 }
1275 
1276 static void
on_top(void * data,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1277 on_top(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1278 {
1279    static int ox, oy, ow, oh; //Object coord
1280    int mx, my; //Mouse coord
1281    int action = (int)(long)data;
1282    Evas_Object *mover;
1283    E_Gadcon_Client *drag_gcc;
1284    int layer = Man->visible;
1285 
1286    drag_gcc = Man->drag_gcc[layer];
1287    if (!drag_gcc) return;
1288 
1289    mover = _get_mover(drag_gcc);
1290    if (!mover) return;
1291    mover_lock = EINA_TRUE;
1292 
1293    if (action == DRAG_START)
1294      {
1295         drag_gcc->resizing = 1;
1296         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1297         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1298         drag_gcc->dy = my - oy;
1299      }
1300    else if (action == DRAG_STOP)
1301      {
1302         drag_gcc->resizing = 0;
1303         drag_gcc->dy = 0;
1304         _save_widget_position(drag_gcc);
1305      }
1306    else if ((action == DRAG_MOVE) && drag_gcc->resizing)
1307      {
1308         int h;
1309 
1310         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1311 
1312         h = oy + oh + drag_gcc->dy - my;
1313 
1314         if (h < drag_gcc->min.h)
1315           {
1316              my -= drag_gcc->min.h - h;
1317              h = drag_gcc->min.h;
1318           }
1319         /* don't go out of the screen */
1320         if (my < drag_gcc->dy)
1321           {
1322              h += my - drag_gcc->dy;
1323              my = drag_gcc->dy;
1324           }
1325 
1326         if (drag_gcc->aspect.w && drag_gcc->aspect.h)
1327           {
1328              ow = h * drag_gcc->aspect.w / drag_gcc->aspect.h;
1329           }
1330 
1331         evas_object_resize(mover, ow, h);
1332         evas_object_move(mover, ox, my - drag_gcc->dy);
1333 
1334         drag_gcc->max.w = ow, drag_gcc->max.h = h;
1335         evas_object_resize(drag_gcc->o_frame, ow, h);
1336         evas_object_move(drag_gcc->o_frame, ox, my - drag_gcc->dy);
1337         _save_widget_position(drag_gcc);
1338      }
1339    mover_lock = EINA_FALSE;
1340 }
1341 
1342 static void
on_right(void * data,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1343 on_right(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1344 {
1345    Evas_Object *mover;
1346    static int ox, oy, ow, oh; //Object coord
1347    int mx, my; //Mouse coord
1348    int action;
1349    E_Gadcon_Client *drag_gcc;
1350    int layer = Man->visible;
1351 
1352    drag_gcc = Man->drag_gcc[layer];
1353    if (!drag_gcc) return;
1354 
1355    mover = _get_mover(drag_gcc);
1356    if (!mover) return;
1357    mover_lock = EINA_TRUE;
1358 
1359    action = (int)(long)data;
1360    if (action == DRAG_START)
1361      {
1362         drag_gcc->resizing = 1;
1363         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1364         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1365         drag_gcc->dx = mx - ow;
1366      }
1367    else if (action == DRAG_STOP)
1368      {
1369         drag_gcc->resizing = 0;
1370         drag_gcc->dx = 0;
1371         _save_widget_position(drag_gcc);
1372      }
1373    else if ((action == DRAG_MOVE) && drag_gcc->resizing)
1374      {
1375         int w;
1376 
1377         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1378         w = mx - drag_gcc->dx;
1379 
1380         if (w < drag_gcc->min.w) w = drag_gcc->min.w;
1381         /* don't go out of the screen */
1382         if (w > (Man->width - ox)) w = Man->width - ox;
1383 
1384         if (drag_gcc->aspect.w && drag_gcc->aspect.h)
1385           {
1386              oh = w * drag_gcc->aspect.h / drag_gcc->aspect.w;
1387           }
1388         drag_gcc->max.w = w, drag_gcc->max.h = oh;
1389         evas_object_resize(mover, w, oh);
1390         evas_object_resize(drag_gcc->o_frame, w, oh);
1391         _save_widget_position(drag_gcc);
1392      }
1393    mover_lock = EINA_FALSE;
1394 }
1395 
1396 static void
on_down(void * data,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1397 on_down(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1398 {
1399    Evas_Object *mover;
1400    static int ox, oy, ow, oh; //Object coord
1401    int mx, my; //Mouse coord
1402    int action = (int)(long)data;
1403    E_Gadcon_Client *drag_gcc;
1404    int layer = Man->visible;
1405 
1406    drag_gcc = Man->drag_gcc[layer];
1407    if (!drag_gcc) return;
1408 
1409    mover = _get_mover(drag_gcc);
1410    if (!mover) return;
1411    mover_lock = EINA_TRUE;
1412 
1413    if (action == DRAG_START)
1414      {
1415         drag_gcc->resizing = 1;
1416         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1417         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1418         drag_gcc->dy = my - oh;
1419      }
1420    else if (action == DRAG_STOP)
1421      {
1422         drag_gcc->resizing = 0;
1423         drag_gcc->dy = 0;
1424         _save_widget_position(drag_gcc);
1425      }
1426    else if ((action == DRAG_MOVE) && drag_gcc->resizing)
1427      {
1428         int h;
1429 
1430         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1431         h = my - drag_gcc->dy;
1432 
1433         if (h < drag_gcc->min.h) h = drag_gcc->min.h;
1434         /* don't go out of the screen */
1435         if (h > (Man->height - oy)) h = Man->height - oy;
1436         if (drag_gcc->aspect.w && drag_gcc->aspect.h)
1437           {
1438              ow = h * drag_gcc->aspect.w / drag_gcc->aspect.h;
1439           }
1440         evas_object_resize(mover, ow, h);
1441         drag_gcc->max.w = ow, drag_gcc->max.h = h;
1442         evas_object_resize(drag_gcc->o_frame, ow, h);
1443         _save_widget_position(drag_gcc);
1444      }
1445    mover_lock = EINA_FALSE;
1446 }
1447 
1448 static void
on_left(void * data,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1449 on_left(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1450 {
1451    Evas_Object *mover;
1452    static int ox, oy, ow, oh; //Object coord
1453    int mx, my; //Mouse coord
1454    int action = (int)(long)data;
1455    E_Gadcon_Client *drag_gcc;
1456    int layer = Man->visible;
1457 
1458    drag_gcc = Man->drag_gcc[layer];
1459    if (!drag_gcc) return;
1460 
1461    mover = _get_mover(drag_gcc);
1462    if (!mover) return;
1463    mover_lock = EINA_TRUE;
1464    if (action == DRAG_START)
1465      {
1466         drag_gcc->resizing = 1;
1467         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1468         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1469         drag_gcc->dx = mx - ox;
1470      }
1471    else if (action == DRAG_STOP)
1472      {
1473         drag_gcc->resizing = 0;
1474         drag_gcc->dx = 0;
1475         _save_widget_position(drag_gcc);
1476      }
1477    else if ((action == DRAG_MOVE) && drag_gcc->resizing)
1478      {
1479         int w;
1480 
1481         evas_pointer_output_xy_get(drag_gcc->gadcon->evas, &mx, &my);
1482 
1483         w = ox + ow + drag_gcc->dx - mx;
1484 
1485         if (w < drag_gcc->min.w)
1486           {
1487              mx -= drag_gcc->min.w - w;
1488              w = drag_gcc->min.w;
1489           }
1490         /* don't go out of the screen */
1491         if (mx < drag_gcc->dx)
1492           {
1493              w += mx - drag_gcc->dx;
1494              mx = drag_gcc->dx;
1495           }
1496         if (drag_gcc->aspect.w && drag_gcc->aspect.h)
1497           {
1498              oh = w * drag_gcc->aspect.h / drag_gcc->aspect.w;
1499           }
1500         evas_object_resize(mover, w, oh);
1501         evas_object_move(mover, mx - drag_gcc->dx, oy);
1502 
1503         drag_gcc->max.w = w, drag_gcc->max.h = oh;
1504         evas_object_resize(drag_gcc->o_frame, w, oh);
1505         evas_object_move(drag_gcc->o_frame, mx - drag_gcc->dx, oy);
1506         _save_widget_position(drag_gcc);
1507      }
1508    mover_lock = EINA_FALSE;
1509 }
1510 
1511 static void
on_move(void * data,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1512 on_move(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1513 {
1514    Evas_Object *mover;
1515    static int ox, oy;  //Starting object position
1516    static int ow, oh;  //Starting object size
1517    int mx, my; //Mouse coord
1518    int action = (int)(long)data;
1519    E_Gadcon *gc;
1520    E_Gadcon_Client *drag_gcc;
1521    E_Drag *drag;
1522    const char *drag_types[] = { "enlightenment/gadcon_client" };
1523 
1524    /* DRAG_START */
1525    if (action != DRAG_START) return;
1526    drag_gcc = Man->drag_gcc[Man->visible];
1527    if (!drag_gcc) return;
1528    gc = drag_gcc->gadcon;
1529    mover = _get_mover(drag_gcc);
1530 
1531    drag_gcc->moving = 1;
1532    gc->cf->clients = eina_list_remove(gc->cf->clients, drag_gcc->cf);
1533    e_gadcon_client_drag_set(drag_gcc);
1534    e_object_ref(E_OBJECT(drag_gcc));
1535    evas_pointer_output_xy_get(gc->evas, &mx, &my);
1536    evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1537 
1538    drag_gcc->dx = mx - ox;
1539    drag_gcc->dy = my - oy;
1540 
1541    drag_gcc->drag.drag = drag = e_drag_new(mx, my,
1542                      drag_types, 1, drag_gcc, -1, NULL,
1543                      e_gadcon_drag_finished_cb);
1544    if (!drag) return;
1545    drag->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
1546 
1547    o = drag_gcc->client_class->func.icon((E_Gadcon_Client_Class *)drag_gcc->client_class,
1548                                     e_drag_evas_get(drag));
1549    if (!o)
1550      {
1551         /* FIXME: fallback icon for drag */
1552         o = evas_object_rectangle_add(e_drag_evas_get(drag));
1553         evas_object_color_set(o, 255, 255, 255, 100);
1554      }
1555 
1556    e_drag_object_set(drag, o);
1557    e_drag_resize(drag, ow, oh);
1558    e_drag_start(drag, mx, my);
1559    e_drag_hide(drag);
1560 }
1561 
1562 static void
on_bg_click(void * data EINA_UNUSED,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1563 on_bg_click(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1564 {
1565    gadman_gadgets_hide();
1566 }
1567 
1568 static void
on_hide_stop(void * data EINA_UNUSED,Evas_Object * o EINA_UNUSED,const char * em EINA_UNUSED,const char * src EINA_UNUSED)1569 on_hide_stop(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const char *src EINA_UNUSED)
1570 {
1571    evas_object_hide(Man->overlay);
1572 }
1573 
1574 static int
_e_gadman_client_add(void * data,E_Gadcon_Client * gcc,const E_Gadcon_Client_Class * cc)1575 _e_gadman_client_add(void *data, E_Gadcon_Client *gcc, const E_Gadcon_Client_Class *cc)
1576 {
1577    return !!gadman_gadget_add(cc, gcc, (intptr_t)data);
1578 }
1579 
1580 static void
_e_gadman_client_remove(void * data EINA_UNUSED,E_Gadcon_Client * gcc)1581 _e_gadman_client_remove(void *data EINA_UNUSED, E_Gadcon_Client *gcc)
1582 {
1583    if (gcc->cf)
1584      gcc->gadcon->cf->clients = eina_list_remove(gcc->gadcon->cf->clients, gcc->cf);
1585    e_object_del(E_OBJECT(gcc));
1586 }
1587 
1588 static void
_e_gadman_handlers_add(void)1589 _e_gadman_handlers_add(void)
1590 {
1591    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_ZONE_ADD, _e_gadman_cb_zone_change, NULL);
1592    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_ZONE_MOVE_RESIZE, _e_gadman_cb_zone_change, NULL);
1593    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED, _e_gadman_cb_zone_change, NULL);
1594    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_ZONE_DEL, _e_gadman_cb_zone_change, NULL);
1595    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_MODULE_UPDATE, _gadman_module_cb, NULL);
1596    E_LIST_HANDLER_APPEND(_gadman_hdls, E_EVENT_MODULE_INIT_END, _gadman_module_init_end_cb, NULL);
1597 }
1598 
1599 static void
_e_gadman_handler_del(void)1600 _e_gadman_handler_del(void)
1601 {
1602    E_FREE_LIST(_gadman_hdls, ecore_event_handler_del);
1603 }
1604 
1605 static Eina_Bool
_gadman_module_init_end_cb(void * d EINA_UNUSED,int type EINA_UNUSED,void * event EINA_UNUSED)1606 _gadman_module_init_end_cb(void *d EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1607 {
1608    gadman_locked = EINA_FALSE;
1609    gadman_reset(NULL);
1610    return ECORE_CALLBACK_RENEW;
1611 }
1612 
1613 static Eina_Bool
_gadman_module_cb(void * d EINA_UNUSED,int type EINA_UNUSED,E_Event_Module_Update * ev)1614 _gadman_module_cb(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Module_Update *ev)
1615 {
1616    if (!ev->enabled)
1617      {
1618         Eina_List *l;
1619         E_Config_Gadcon_Client *cf_gcc;
1620         E_Gadcon_Client *gcc;
1621         l = eina_hash_set(_gadman_gadgets, ev->name, NULL);
1622         if (!l) return ECORE_CALLBACK_RENEW;
1623         EINA_LIST_FREE(l, cf_gcc)
1624           {
1625              gcc = e_gadcon_client_find(NULL, cf_gcc);
1626              if (!gcc) continue;
1627              gcc->cf = NULL;
1628              e_object_del(E_OBJECT(gcc));
1629           }
1630      }
1631    return ECORE_CALLBACK_RENEW;
1632 }
1633 
1634 static Eina_Bool
_e_gadman_cb_zone_change(void * data EINA_UNUSED,int type,void * event)1635 _e_gadman_cb_zone_change(void *data EINA_UNUSED, int type, void *event)
1636 {
1637    E_Gadcon *gc;
1638    Eina_List *l, *ll;
1639    E_Event_Zone_Move_Resize *ev = event;
1640    const char *layer_name[] = {"gadman", "gadman_top"};
1641    int layer;
1642    E_Gadcon_Client *gcc;
1643 
1644    if (!Man) return ECORE_CALLBACK_RENEW;
1645    if (gadman_locked) return ECORE_CALLBACK_RENEW;
1646    if ((type == E_EVENT_ZONE_MOVE_RESIZE) || (type == E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED))
1647      {
1648         /* probably zone dirty being set */
1649         EINA_LIST_FOREACH(Man->gadcons[GADMAN_LAYER_BG], l, gc)
1650           {
1651              if (e_gadcon_zone_get(gc) != ev->zone) continue;
1652              EINA_LIST_FOREACH(gc->clients, ll, gcc)
1653                _apply_widget_position(gcc);
1654              return ECORE_CALLBACK_RENEW;
1655           }
1656      }
1657    if (type == E_EVENT_ZONE_DEL)
1658      {
1659         for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
1660           {
1661              EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
1662                {
1663                   if (e_gadcon_zone_get(gc) != ev->zone) continue;
1664                   e_object_del(E_OBJECT(gc));
1665                   Man->gadcons[layer] = eina_list_remove_list(Man->gadcons[layer], l);
1666                   E_FREE_FUNC(Man->movers[layer], evas_object_del);
1667                   break;
1668                }
1669           }
1670         evas_object_hide(Man->overlay);
1671         E_FREE_FUNC(Man->overlay, evas_object_del);
1672         _gadman_overlay_create();
1673         return ECORE_CALLBACK_RENEW;
1674      }
1675 
1676    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
1677      {
1678         Eina_Bool found = EINA_FALSE;
1679         EINA_LIST_FOREACH(Man->gadcons[GADMAN_LAYER_BG], l, gc)
1680           if (e_gadcon_zone_get(gc) == ev->zone)
1681             {
1682                found = EINA_TRUE;
1683                break;
1684             }
1685         if (found) continue;
1686         gc = _gadman_gadcon_new(layer_name[layer], layer, ev->zone, Man->location[layer]);
1687         Man->gadcons[layer] = eina_list_append(Man->gadcons[layer], gc);
1688         gc->drop_handler->base = Man->overlay;
1689         gc->drop_handler->hidden = 1;
1690      }
1691    return ECORE_CALLBACK_PASS_ON;
1692 }
1693