b44ac507f441358b9ed0822358bb233dfa0e451a
[framework/uifw/e17.git] / src / modules / ibox / e_mod_main.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 /* gadcon requirements */
5 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
6 static void _gc_shutdown(E_Gadcon_Client *gcc);
7 static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
8 static char *_gc_label(E_Gadcon_Client_Class *client_class);
9 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class, Evas *evas);
10 static const char *_gc_id_new(E_Gadcon_Client_Class *client_class);
11 static void _gc_id_del(E_Gadcon_Client_Class *client_class, const char *id);
12 /* and actually define the gadcon class that this module provides (just 1) */
13 static const E_Gadcon_Client_Class _gadcon_class =
14 {
15    GADCON_CLIENT_CLASS_VERSION,
16      "ibox",
17      {
18         _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, _gc_id_del,
19         e_gadcon_site_is_not_toolbar
20      },
21    E_GADCON_CLIENT_STYLE_INSET
22 };
23
24 /* actual module specifics */
25
26 typedef struct _Instance  Instance;
27
28 typedef struct _IBox      IBox;
29 typedef struct _IBox_Icon IBox_Icon;
30
31 struct _Instance
32 {
33    E_Gadcon_Client *gcc;
34    Evas_Object     *o_ibox;
35    IBox            *ibox;
36    E_Drop_Handler  *drop_handler;
37    Config_Item     *ci;
38    E_Gadcon_Orient orient;
39 };
40
41 struct _IBox
42 {
43    Instance       *inst;
44    Evas_Object    *o_box;
45    Evas_Object    *o_drop;
46    Evas_Object    *o_drop_over;
47    Evas_Object    *o_empty;
48    IBox_Icon      *ic_drop_before;
49    int             drop_before;
50    Eina_List      *icons;
51    E_Zone          *zone;
52    Evas_Coord      dnd_x, dnd_y;
53 };
54
55 struct _IBox_Icon
56 {
57    IBox        *ibox;
58    Evas_Object *o_holder;
59    Evas_Object *o_icon;
60    Evas_Object *o_holder2;
61    Evas_Object *o_icon2;
62    E_Border    *border;
63    struct 
64      {
65         unsigned char  start : 1;
66         unsigned char  dnd : 1;
67         int            x, y;
68         int            dx, dy;
69      } drag;
70 };
71
72 static IBox *_ibox_new(Evas *evas, E_Zone *zone);
73 static void _ibox_free(IBox *b);
74 static void _ibox_cb_empty_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
75 static void _ibox_empty_handle(IBox *b);
76 static void _ibox_fill(IBox *b);
77 static void _ibox_empty(IBox *b);
78 static void _ibox_orient_set(IBox *b, int horizontal);
79 static void _ibox_resize_handle(IBox *b);
80 static void _ibox_instance_drop_zone_recalc(Instance *inst);
81 static IBox_Icon *_ibox_icon_find(IBox *b, E_Border *bd);
82 static IBox_Icon *_ibox_icon_at_coord(IBox *b, Evas_Coord x, Evas_Coord y);
83 static IBox_Icon *_ibox_icon_new(IBox *b, E_Border *bd);
84 static void _ibox_icon_free(IBox_Icon *ic);
85 static void _ibox_icon_fill(IBox_Icon *ic);
86 static void _ibox_icon_fill_label(IBox_Icon *ic);
87 static void _ibox_icon_empty(IBox_Icon *ic);
88 static void _ibox_icon_signal_emit(IBox_Icon *ic, char *sig, char *src);
89 static Eina_List *_ibox_zone_find(E_Zone *zone);
90 static void _ibox_cb_obj_moveresize(void *data, Evas *e, Evas_Object *obj, void *event_info);
91 static void _ibox_cb_menu_post(void *data, E_Menu *m);
92 static void _ibox_cb_menu_configuration(void *data, E_Menu *m, E_Menu_Item *mi);
93 static void _ibox_cb_icon_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info);
94 static void _ibox_cb_icon_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info);
95 static void _ibox_cb_icon_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
96 static void _ibox_cb_icon_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
97 static void _ibox_cb_icon_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
98 static void _ibox_cb_icon_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
99 static void _ibox_cb_icon_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
100 static void _ibox_cb_drag_finished(E_Drag *drag, int dropped);
101 static void _ibox_inst_cb_enter(void *data, const char *type, void *event_info);
102 static void _ibox_inst_cb_move(void *data, const char *type, void *event_info);
103 static void _ibox_inst_cb_leave(void *data, const char *type, void *event_info);
104 static void _ibox_inst_cb_drop(void *data, const char *type, void *event_info);
105 static void _ibox_drop_position_update(Instance *inst, Evas_Coord x, Evas_Coord y);
106 static void _ibox_inst_cb_scroll(void *data);
107 static Eina_Bool _ibox_cb_event_border_add(void *data, int type, void *event);
108 static Eina_Bool _ibox_cb_event_border_remove(void *data, int type, void *event);
109 static Eina_Bool _ibox_cb_event_border_iconify(void *data, int type, void *event);
110 static Eina_Bool _ibox_cb_event_border_uniconify(void *data, int type, void *event);
111 static Eina_Bool _ibox_cb_event_border_icon_change(void *data, int type, void *event);
112 static Eina_Bool _ibox_cb_event_border_urgent_change(void *data, int type, void *event);
113 static Eina_Bool _ibox_cb_event_border_zone_set(void *data, int type, void *event);
114 static Eina_Bool _ibox_cb_event_desk_show(void *data, int type, void *event);
115 static Config_Item *_ibox_config_item_get(const char *id);
116
117 static E_Config_DD *conf_edd = NULL;
118 static E_Config_DD *conf_item_edd = NULL;
119
120 static int uuid = 0;
121
122 Config *ibox_config = NULL;
123
124 static E_Gadcon_Client *
125 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
126 {
127    IBox *b;
128    Evas_Object *o;
129    E_Gadcon_Client *gcc;
130    Instance *inst;
131    Evas_Coord x, y, w, h;
132    const char *drop[] = { "enlightenment/border" };
133    Config_Item *ci;
134
135    inst = E_NEW(Instance, 1);
136
137    ci = _ibox_config_item_get(id);
138    inst->ci = ci;
139
140    b = _ibox_new(gc->evas, gc->zone);
141    b->inst = inst;
142    inst->ibox = b;
143    _ibox_fill(b);
144    o = b->o_box;
145    gcc = e_gadcon_client_new(gc, name, id, style, o);
146    gcc->data = inst;
147
148    inst->gcc = gcc;
149    inst->o_ibox = o;
150    inst->orient = E_GADCON_ORIENT_HORIZ;
151
152    evas_object_geometry_get(o, &x, &y, &w, &h);
153    inst->drop_handler =
154      e_drop_handler_add(E_OBJECT(inst->gcc), inst,
155                         _ibox_inst_cb_enter, _ibox_inst_cb_move,
156                         _ibox_inst_cb_leave, _ibox_inst_cb_drop,
157                         drop, 1, x, y, w, h);
158    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE,
159                                   _ibox_cb_obj_moveresize, inst);
160    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
161                                   _ibox_cb_obj_moveresize, inst);
162    ibox_config->instances = eina_list_append(ibox_config->instances, inst);
163    return gcc;
164 }
165
166 static void
167 _gc_shutdown(E_Gadcon_Client *gcc)
168 {
169    Instance *inst;
170
171    inst = gcc->data;
172    ibox_config->instances = eina_list_remove(ibox_config->instances, inst);
173    e_drop_handler_del(inst->drop_handler);
174    _ibox_free(inst->ibox);
175    free(inst);
176 }
177
178 static void
179 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient)
180 {
181    Instance *inst;
182
183    inst = gcc->data;
184    if ((int)orient != -1) inst->orient = orient;
185
186    switch (inst->orient)
187      {
188       case E_GADCON_ORIENT_FLOAT:
189       case E_GADCON_ORIENT_HORIZ:
190       case E_GADCON_ORIENT_TOP:
191       case E_GADCON_ORIENT_BOTTOM:
192       case E_GADCON_ORIENT_CORNER_TL:
193       case E_GADCON_ORIENT_CORNER_TR:
194       case E_GADCON_ORIENT_CORNER_BL:
195       case E_GADCON_ORIENT_CORNER_BR:
196         _ibox_orient_set(inst->ibox, 1);
197         e_gadcon_client_aspect_set(gcc, eina_list_count(inst->ibox->icons) * 16, 16);
198         break;
199       case E_GADCON_ORIENT_VERT:
200       case E_GADCON_ORIENT_LEFT:
201       case E_GADCON_ORIENT_RIGHT:
202       case E_GADCON_ORIENT_CORNER_LT:
203       case E_GADCON_ORIENT_CORNER_RT:
204       case E_GADCON_ORIENT_CORNER_LB:
205       case E_GADCON_ORIENT_CORNER_RB:
206         _ibox_orient_set(inst->ibox, 0);
207         e_gadcon_client_aspect_set(gcc, 16, eina_list_count(inst->ibox->icons) * 16);
208         break;
209       default:
210         break;
211      }
212    e_gadcon_client_min_size_set(gcc, 16, 16);
213 }
214
215 static char *
216 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
217 {
218    return _("IBox");
219 }
220
221 static Evas_Object *
222 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
223 {
224    Evas_Object *o;
225    char buf[PATH_MAX];
226
227    o = edje_object_add(evas);
228    snprintf(buf, sizeof(buf), "%s/e-module-ibox.edj",
229             e_module_dir_get(ibox_config->module));
230    edje_object_file_set(o, buf, "icon");
231    return o;
232 }
233
234 static const char *
235 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
236 {
237    Config_Item *ci;
238
239    ci = _ibox_config_item_get(NULL);
240    return ci->id;
241 }
242
243 static void
244 _gc_id_del(E_Gadcon_Client_Class *client_class __UNUSED__, const char *id __UNUSED__)
245 {
246 /* yes - don't do this. on shutdown gadgets are deleted and this means config
247  * for them is deleted - that means empty config is saved. keep them around
248  * as if u add a gadget back it can pick up its old config again
249    Config_Item *ci;
250
251    ci = _ibox_config_item_get(id);
252    if (ci)
253      {
254         if (ci->id) eina_stringshare_del(ci->id);
255         ibox_config->items = eina_list_remove(ibox_config->items, ci);
256      }
257  */
258 }
259
260 static IBox *
261 _ibox_new(Evas *evas, E_Zone *zone)
262 {
263    IBox *b;
264
265    b = E_NEW(IBox, 1);
266    b->o_box = e_box_add(evas);
267    e_box_homogenous_set(b->o_box, 1);
268    e_box_orientation_set(b->o_box, 1);
269    e_box_align_set(b->o_box, 0.5, 0.5);
270    b->zone = zone;
271    return b;
272 }
273
274 static void
275 _ibox_free(IBox *b)
276 {
277    _ibox_empty(b);
278    evas_object_del(b->o_box);
279    if (b->o_drop) evas_object_del(b->o_drop);
280    if (b->o_drop_over) evas_object_del(b->o_drop_over);
281    if (b->o_empty) evas_object_del(b->o_empty);
282    free(b);
283 }
284
285 static void
286 _ibox_cb_empty_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
287 {
288    Evas_Event_Mouse_Down *ev;
289    IBox *b;
290
291    ev = event_info;
292    b = data;
293    if (!ibox_config->menu)
294      {
295         E_Menu *m;
296         E_Menu_Item *mi;
297         int cx, cy;
298
299         m = e_menu_new();
300         mi = e_menu_item_new(m);
301         e_menu_item_label_set(mi, _("Settings"));
302         e_util_menu_item_theme_icon_set(mi, "configure");
303         e_menu_item_callback_set(mi, _ibox_cb_menu_configuration, b);
304
305         m = e_gadcon_client_util_menu_items_append(b->inst->gcc, m, 0);
306         e_menu_post_deactivate_callback_set(m, _ibox_cb_menu_post, NULL);
307         ibox_config->menu = m;
308
309         
310         e_gadcon_canvas_zone_geometry_get(b->inst->gcc->gadcon,
311                                           &cx, &cy, NULL, NULL);
312         e_menu_activate_mouse(m,
313                               e_util_zone_current_get(e_manager_current_get()),
314                               cx + ev->output.x, cy + ev->output.y, 1, 1,
315                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
316      }
317 }
318
319 static void
320 _ibox_empty_handle(IBox *b)
321 {
322    if (!b->icons)
323      {
324         if (!b->o_empty)
325           {
326              Evas_Coord w, h;
327         
328              b->o_empty = evas_object_rectangle_add(evas_object_evas_get(b->o_box));
329              evas_object_event_callback_add(b->o_empty, EVAS_CALLBACK_MOUSE_DOWN, _ibox_cb_empty_mouse_down, b);
330              evas_object_color_set(b->o_empty, 0, 0, 0, 0);
331              evas_object_show(b->o_empty);
332              e_box_pack_end(b->o_box, b->o_empty);
333              evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
334              if (e_box_orientation_get(b->o_box))
335                w = h;
336              else
337                h = w;
338              e_box_pack_options_set(b->o_empty,
339                                     1, 1, /* fill */
340                                     1, 1, /* expand */
341                                     0.5, 0.5, /* align */
342                                     w, h, /* min */
343                                     9999, 9999 /* max */
344                                     );
345           }
346      }
347    else if (b->o_empty)
348      {
349         evas_object_del(b->o_empty);
350         b->o_empty = NULL;
351      }
352 }
353
354 static void
355 _ibox_fill(IBox *b)
356 {
357    IBox_Icon *ic;
358    E_Border_List *bl;
359    E_Border *bd;
360    int ok;
361
362    bl = e_container_border_list_first(b->zone->container);
363    while ((bd = e_container_border_list_next(bl)))
364      {
365         ok = 0;
366         if ((b->inst->ci->show_zone == 0) && (bd->iconic))
367           {
368              ok = 1;
369           }
370         else if((b->inst->ci->show_zone == 1) && (bd->iconic))
371           {
372              if (bd->sticky)
373                {
374                   ok = 1;
375                }
376              else if ((b->inst->ci->show_desk == 0) && (bd->zone == b->zone))
377                {
378                   ok = 1;
379                }
380              else if((b->inst->ci->show_desk == 1) && (bd->zone == b->zone) &&
381                      (bd->desk == e_desk_current_get(b->zone)))
382                {
383                   ok = 1;
384                }
385           }
386
387         if (ok)
388           {
389              ic = _ibox_icon_new(b, bd);
390              b->icons = eina_list_append(b->icons, ic);
391              e_box_pack_end(b->o_box, ic->o_holder);
392           }
393      }
394    e_container_border_list_free(bl);
395
396    _ibox_empty_handle(b);
397    _ibox_resize_handle(b);
398 }
399
400 static void
401 _ibox_empty(IBox *b)
402 {
403    while (b->icons)
404      {
405         _ibox_icon_free(b->icons->data);
406         b->icons = eina_list_remove_list(b->icons, b->icons);
407      }
408    _ibox_empty_handle(b);
409 }
410
411 static void
412 _ibox_orient_set(IBox *b, int horizontal)
413 {
414    e_box_orientation_set(b->o_box, horizontal);
415    e_box_align_set(b->o_box, 0.5, 0.5);
416 }
417
418 static void
419 _ibox_resize_handle(IBox *b)
420 {
421    Eina_List *l;
422    IBox_Icon *ic;
423    Evas_Coord w, h;
424
425    evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
426    if (e_box_orientation_get(b->o_box))
427      w = h;
428    else
429      h = w;
430    e_box_freeze(b->o_box);
431    for (l = b->icons; l; l = l->next)
432      {
433         ic = l->data;
434         e_box_pack_options_set(ic->o_holder,
435                                1, 1, /* fill */
436                                0, 0, /* expand */
437                                0.5, 0.5, /* align */
438                                w, h, /* min */
439                                w, h /* max */
440                                );
441      }
442    e_box_thaw(b->o_box);
443 }
444
445 static void
446 _ibox_instance_drop_zone_recalc(Instance *inst)
447 {
448    Evas_Coord x, y, w, h;
449
450    e_gadcon_client_viewport_geometry_get(inst->gcc, &x, &y, &w, &h);
451    e_drop_handler_geometry_set(inst->drop_handler, x, y, w, h);
452 }
453
454 static IBox_Icon *
455 _ibox_icon_find(IBox *b, E_Border *bd)
456 {
457    Eina_List *l;
458    IBox_Icon *ic;
459
460    for (l = b->icons; l; l = l->next)
461      {
462         ic = l->data;
463         
464         if (ic->border == bd) return ic;
465      }
466    return NULL;
467 }
468
469 static IBox_Icon *
470 _ibox_icon_at_coord(IBox *b, Evas_Coord x, Evas_Coord y)
471 {
472    Eina_List *l;
473    IBox_Icon *ic;
474
475    for (l = b->icons; l; l = l->next)
476      {
477         Evas_Coord dx, dy, dw, dh;
478         ic = l->data;
479         
480         evas_object_geometry_get(ic->o_holder, &dx, &dy, &dw, &dh);
481         if (E_INSIDE(x, y, dx, dy, dw, dh)) return ic;
482      }
483    return NULL;
484 }
485
486 static IBox_Icon *
487 _ibox_icon_new(IBox *b, E_Border *bd)
488 {
489    IBox_Icon *ic;
490
491    ic = E_NEW(IBox_Icon, 1);
492    e_object_ref(E_OBJECT(bd));
493    ic->ibox = b;
494    ic->border = bd;
495    ic->o_holder = edje_object_add(evas_object_evas_get(b->o_box));
496    e_theme_edje_object_set(ic->o_holder, "base/theme/modules/ibox",
497                            "e/modules/ibox/icon");
498    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_IN,  _ibox_cb_icon_mouse_in,  ic);
499    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_OUT, _ibox_cb_icon_mouse_out, ic);
500    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_DOWN, _ibox_cb_icon_mouse_down, ic);
501    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_UP, _ibox_cb_icon_mouse_up, ic);
502    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_MOVE, _ibox_cb_icon_mouse_move, ic);
503    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOVE, _ibox_cb_icon_move, ic);
504    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_RESIZE, _ibox_cb_icon_resize, ic);
505    evas_object_show(ic->o_holder);
506
507    ic->o_holder2 = edje_object_add(evas_object_evas_get(b->o_box));
508    e_theme_edje_object_set(ic->o_holder2, "base/theme/modules/ibox",
509                            "e/modules/ibox/icon_overlay");
510    evas_object_layer_set(ic->o_holder2, 9999);
511    evas_object_pass_events_set(ic->o_holder2, 1);
512    evas_object_show(ic->o_holder2);
513
514    _ibox_icon_fill(ic);
515    return ic;
516 }
517
518 static void
519 _ibox_icon_free(IBox_Icon *ic)
520 {
521    if (ibox_config->menu)
522      {
523         e_menu_post_deactivate_callback_set(ibox_config->menu, NULL, NULL);
524         e_object_del(E_OBJECT(ibox_config->menu));
525         ibox_config->menu = NULL;
526      }
527    if (ic->ibox->ic_drop_before == ic)
528      ic->ibox->ic_drop_before = NULL;
529    _ibox_icon_empty(ic);
530    evas_object_del(ic->o_holder);
531    evas_object_del(ic->o_holder2);
532    e_object_unref(E_OBJECT(ic->border));
533    free(ic);
534 }
535
536 static void
537 _ibox_icon_fill(IBox_Icon *ic)
538 {
539    ic->o_icon = e_border_icon_add(ic->border, evas_object_evas_get(ic->ibox->o_box));
540    edje_object_part_swallow(ic->o_holder, "e.swallow.content", ic->o_icon);
541    evas_object_pass_events_set(ic->o_icon, 1);
542    evas_object_show(ic->o_icon);
543    ic->o_icon2 = e_border_icon_add(ic->border, evas_object_evas_get(ic->ibox->o_box));
544    edje_object_part_swallow(ic->o_holder2, "e.swallow.content", ic->o_icon2);
545    evas_object_pass_events_set(ic->o_icon2, 1);
546    evas_object_show(ic->o_icon2);
547
548    _ibox_icon_fill_label(ic);
549 }
550
551 static void
552 _ibox_icon_fill_label(IBox_Icon *ic)
553 {
554    const char *label = NULL;
555
556    switch (ic->ibox->inst->ci->icon_label)
557      {
558       case 0:
559         label = ic->border->client.netwm.name;
560         if (!label)
561           label = ic->border->client.icccm.name;
562         break;
563       case 1:
564         label = ic->border->client.icccm.title;
565         break;
566       case 2:
567         label = ic->border->client.icccm.class;
568         break;
569       case 3:
570         label = ic->border->client.netwm.icon_name;
571         if (!label)
572           label = ic->border->client.icccm.icon_name;
573         break;
574       case 4:
575         label = e_border_name_get(ic->border);
576         break;
577      }
578
579    if (!label) label = "?";
580    edje_object_part_text_set(ic->o_holder2, "e.text.label", label);
581 }
582
583 static void
584 _ibox_icon_empty(IBox_Icon *ic)
585 {
586    if (ic->o_icon) evas_object_del(ic->o_icon);
587    if (ic->o_icon2) evas_object_del(ic->o_icon2);
588    ic->o_icon = NULL;
589    ic->o_icon2 = NULL;
590 }
591
592 static void
593 _ibox_icon_signal_emit(IBox_Icon *ic, char *sig, char *src)
594 {
595    if (ic->o_holder)
596      edje_object_signal_emit(ic->o_holder, sig, src);
597    if (ic->o_icon)
598      edje_object_signal_emit(ic->o_icon, sig, src);
599    if (ic->o_holder2)
600      edje_object_signal_emit(ic->o_holder2, sig, src);
601    if (ic->o_icon2)
602      edje_object_signal_emit(ic->o_icon2, sig, src);
603 }
604
605 static Eina_List *
606 _ibox_zone_find(E_Zone *zone)
607 {
608    Eina_List *ibox = NULL;
609    Eina_List *l;
610
611    for (l = ibox_config->instances; l; l = l->next)
612      {
613         Instance *inst;
614
615         inst = l->data;
616         if (inst->ci->show_zone == 0)
617           ibox = eina_list_append(ibox, inst->ibox);
618         else if ((inst->ci->show_zone == 1) && (inst->ibox->zone == zone))
619           ibox = eina_list_append(ibox, inst->ibox);
620      }
621    return ibox;
622 }
623
624 static void
625 _ibox_cb_obj_moveresize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
626 {
627    Instance *inst;
628
629    inst = data;
630    _ibox_resize_handle(inst->ibox);
631    _ibox_instance_drop_zone_recalc(inst);
632 }
633
634 static void
635 _ibox_cb_menu_post(void *data __UNUSED__, E_Menu *m __UNUSED__)
636 {
637    if (!ibox_config->menu) return;
638    e_object_del(E_OBJECT(ibox_config->menu));
639    ibox_config->menu = NULL;
640 }
641
642 static void
643 _ibox_cb_icon_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
644 {
645    IBox_Icon *ic;
646
647    ic = data;
648    _ibox_icon_signal_emit(ic, "e,state,focused", "e");
649    if (ic->ibox->inst->ci->show_label)
650      {
651         _ibox_icon_fill_label(ic);
652         _ibox_icon_signal_emit(ic, "e,action,show,label", "e");
653      }
654 }
655
656 static void
657 _ibox_cb_icon_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
658 {
659    Evas_Event_Mouse_Out *ev;
660    IBox_Icon *ic;
661
662    ev = event_info;
663    ic = data;
664    _ibox_icon_signal_emit(ic, "e,state,unfocused", "e");
665    if (ic->ibox->inst->ci->show_label)
666      _ibox_icon_signal_emit(ic, "e,action,hide,label", "e");
667 }
668
669 static void
670 _ibox_cb_icon_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
671 {
672    Evas_Event_Mouse_Down *ev;
673    IBox_Icon *ic;
674
675    ev = event_info;
676    ic = data;
677    if (ev->button == 1)
678      {
679         ic->drag.x = ev->output.x;
680         ic->drag.y = ev->output.y;
681         ic->drag.start = 1;
682         ic->drag.dnd = 0;
683      }
684    else if ((ev->button == 3) && (!ibox_config->menu))
685      {
686         E_Menu *m;
687         E_Menu_Item *mi;
688         int cx, cy;
689
690         m = e_menu_new();
691
692         /* FIXME: other icon options go here too */
693         mi = e_menu_item_new(m);
694         e_menu_item_label_set(mi, _("Settings"));
695         e_util_menu_item_theme_icon_set(mi, "configure");
696         e_menu_item_callback_set(mi, _ibox_cb_menu_configuration, ic->ibox);
697
698         m = e_gadcon_client_util_menu_items_append(ic->ibox->inst->gcc, m, 0);
699         e_menu_post_deactivate_callback_set(m, _ibox_cb_menu_post, NULL);
700         ibox_config->menu = m;
701         
702         e_gadcon_canvas_zone_geometry_get(ic->ibox->inst->gcc->gadcon,
703                                           &cx, &cy, NULL, NULL);
704         e_menu_activate_mouse(m,
705                               e_util_zone_current_get(e_manager_current_get()),
706                               cx + ev->output.x, cy + ev->output.y, 1, 1,
707                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
708      }
709 }
710
711 static void
712 _ibox_cb_icon_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
713 {
714    Evas_Event_Mouse_Up *ev;
715    IBox_Icon *ic;
716
717    ev = event_info;
718    ic = data;
719    if ((ev->button == 1) && (!ic->drag.dnd))
720      {
721         e_border_uniconify(ic->border);
722         e_border_focus_set(ic->border, 1, 1);
723      }
724 }
725
726 static void
727 _ibox_cb_icon_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
728 {
729    Evas_Event_Mouse_Move *ev;
730    IBox_Icon *ic;
731
732    ev = event_info;
733    ic = data;
734    if (ic->drag.start)
735      {
736         int dx, dy;
737
738         dx = ev->cur.output.x - ic->drag.x;
739         dy = ev->cur.output.y - ic->drag.y;
740         if (((dx * dx) + (dy * dy)) >
741             (e_config->drag_resist * e_config->drag_resist))
742           {
743              E_Drag *d;
744              Evas_Object *o;
745              Evas_Coord x, y, w, h;
746              const char *drag_types[] = { "enlightenment/border" };
747              E_Gadcon_Client *gcc;
748              ic->drag.dnd = 1;
749              ic->drag.start = 0;
750
751              evas_object_geometry_get(ic->o_icon, &x, &y, &w, &h);
752              d = e_drag_new(ic->ibox->inst->gcc->gadcon->zone->container,
753                             x, y, drag_types, 1,
754                             ic->border, -1, NULL, _ibox_cb_drag_finished);
755              o = e_border_icon_add(ic->border, e_drag_evas_get(d));
756              e_drag_object_set(d, o);
757
758              e_drag_resize(d, w, h);
759              e_drag_start(d, ic->drag.x, ic->drag.y);
760              e_object_ref(E_OBJECT(ic->border));
761              ic->ibox->icons = eina_list_remove(ic->ibox->icons, ic);
762              _ibox_resize_handle(ic->ibox);
763              gcc = ic->ibox->inst->gcc;
764              _gc_orient(gcc, -1);
765              _ibox_icon_free(ic);
766           }
767      }
768 }
769
770 static void
771 _ibox_cb_icon_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
772 {
773    IBox_Icon *ic;
774    Evas_Coord x, y;
775
776    ic = data;
777    evas_object_geometry_get(ic->o_holder, &x, &y, NULL, NULL);
778    evas_object_move(ic->o_holder2, x, y);
779    evas_object_raise(ic->o_holder2);
780 }
781
782 static void
783 _ibox_cb_icon_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
784 {
785    IBox_Icon *ic;
786    Evas_Coord w, h;
787
788    ic = data;
789    evas_object_geometry_get(ic->o_holder, NULL, NULL, &w, &h);
790    evas_object_resize(ic->o_holder2, w, h);
791    evas_object_raise(ic->o_holder2);
792 }
793
794 static void
795 _ibox_cb_drag_finished(E_Drag *drag, int dropped)
796 {
797    E_Border *bd;
798
799    bd = drag->data;
800    if (!dropped) e_border_uniconify(bd);
801    e_object_unref(E_OBJECT(bd));
802 }
803
804 static void
805 _ibox_cb_drop_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
806 {
807    IBox *b;
808    Evas_Coord x, y;
809
810    b = data;
811    evas_object_geometry_get(b->o_drop, &x, &y, NULL, NULL);
812    evas_object_move(b->o_drop_over, x, y);
813 }
814
815 static void
816 _ibox_cb_drop_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
817 {
818    IBox *b;
819    Evas_Coord w, h;
820
821    b = data;
822    evas_object_geometry_get(b->o_drop, NULL, NULL, &w, &h);
823    evas_object_resize(b->o_drop_over, w, h);
824 }
825
826 static void
827 _ibox_inst_cb_scroll(void *data)
828 {
829    Instance *inst;
830
831    /* Update the position of the dnd to handle for autoscrolling
832     * gadgets. */
833    inst = data;
834    _ibox_drop_position_update(inst, inst->ibox->dnd_x, inst->ibox->dnd_y);
835 }
836
837 static void
838 _ibox_drop_position_update(Instance *inst, Evas_Coord x, Evas_Coord y)
839 {
840    IBox_Icon *ic;
841
842    inst->ibox->dnd_x = x;
843    inst->ibox->dnd_y = y;
844
845    if (inst->ibox->o_drop)
846       e_box_unpack(inst->ibox->o_drop);
847    ic = _ibox_icon_at_coord(inst->ibox, x, y);
848    inst->ibox->ic_drop_before = ic;
849    if (ic)
850      {
851         Evas_Coord ix, iy, iw, ih;
852         int before = 0;
853         
854         evas_object_geometry_get(ic->o_holder, &ix, &iy, &iw, &ih);
855         if (e_box_orientation_get(inst->ibox->o_box))
856           {
857              if (x < (ix + (iw / 2))) before = 1;
858           }
859         else
860           {
861              if (y < (iy + (ih / 2))) before = 1;
862           }
863         if (before)
864           e_box_pack_before(inst->ibox->o_box, inst->ibox->o_drop, ic->o_holder);
865         else
866           e_box_pack_after(inst->ibox->o_box, inst->ibox->o_drop, ic->o_holder);
867         inst->ibox->drop_before = before;
868      }
869    else e_box_pack_end(inst->ibox->o_box, inst->ibox->o_drop);
870    e_box_pack_options_set(inst->ibox->o_drop,
871                           1, 1, /* fill */
872                           1, 1, /* expand */
873                           0.5, 0.5, /* align */
874                           1, 1, /* min */
875                           -1, -1 /* max */
876                           );
877    _ibox_resize_handle(inst->ibox);
878    _gc_orient(inst->gcc, -1);
879 }
880
881 static void
882 _ibox_inst_cb_enter(void *data, const char *type __UNUSED__, void *event_info)
883 {
884    E_Event_Dnd_Enter *ev;
885    Instance *inst;
886    Evas_Object *o, *o2;
887
888    ev = event_info;
889    inst = data;
890    o = edje_object_add(evas_object_evas_get(inst->ibox->o_box));
891    inst->ibox->o_drop = o;
892    o2 = edje_object_add(evas_object_evas_get(inst->ibox->o_box));
893    inst->ibox->o_drop_over = o2;
894    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _ibox_cb_drop_move, inst->ibox);
895    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _ibox_cb_drop_resize, inst->ibox);
896    e_theme_edje_object_set(o, "base/theme/modules/ibox",
897                            "e/modules/ibox/drop");
898    e_theme_edje_object_set(o2, "base/theme/modules/ibox",
899                            "e/modules/ibox/drop_overlay");
900    evas_object_layer_set(o2, 19999);
901    evas_object_show(o);
902    evas_object_show(o2);
903    _ibox_drop_position_update(inst, ev->x, ev->y);
904    e_gadcon_client_autoscroll_cb_set(inst->gcc, _ibox_inst_cb_scroll, inst);
905    e_gadcon_client_autoscroll_update(inst->gcc, ev->x, ev->y);
906 }
907
908 static void
909 _ibox_inst_cb_move(void *data, const char *type __UNUSED__, void *event_info)
910 {
911    E_Event_Dnd_Move *ev;
912    Instance *inst;
913
914    ev = event_info;
915    inst = data;
916    _ibox_drop_position_update(inst, ev->x, ev->y);
917    e_gadcon_client_autoscroll_update(inst->gcc, ev->x, ev->y);
918 }
919
920 static void
921 _ibox_inst_cb_leave(void *data, const char *type __UNUSED__, void *event_info __UNUSED__)
922 {
923    Instance *inst;
924
925    inst = data;
926    inst->ibox->ic_drop_before = NULL;
927    evas_object_del(inst->ibox->o_drop);
928    inst->ibox->o_drop = NULL;
929    evas_object_del(inst->ibox->o_drop_over);
930    inst->ibox->o_drop_over = NULL;
931    e_gadcon_client_autoscroll_cb_set(inst->gcc, NULL, NULL);
932    _ibox_resize_handle(inst->ibox);
933    _gc_orient(inst->gcc, -1);
934 }
935
936 static void
937 _ibox_inst_cb_drop(void *data, const char *type, void *event_info)
938 {
939    E_Event_Dnd_Drop *ev;
940    Instance *inst;
941    E_Border *bd = NULL;
942    IBox *b;
943    IBox_Icon *ic, *ic2;
944    Eina_List *l;
945
946    ev = event_info;
947    inst = data;
948    if (!strcmp(type, "enlightenment/border"))
949      {
950         bd = ev->data;
951         if (!bd) return;
952      }
953    else return;
954
955    if (!bd->iconic) e_border_iconify(bd);
956
957    ic2 = inst->ibox->ic_drop_before;
958    if (ic2)
959      {
960         /* Add new eapp before this icon */
961         if (!inst->ibox->drop_before)
962           {
963              for (l = inst->ibox->icons; l; l = l->next)
964                {
965                   if (l->data == ic2)
966                     {
967                        if (l->next)
968                          ic2 = l->next->data;
969                        else
970                          ic2 = NULL;
971                        break;
972                     }
973                }
974           }
975         if (!ic2) goto atend;
976         b = inst->ibox;
977         if (_ibox_icon_find(b, bd)) return;
978         ic = _ibox_icon_new(b, bd);
979         if (!ic) return;
980         b->icons = eina_list_prepend_relative(b->icons, ic, ic2);
981         e_box_pack_before(b->o_box, ic->o_holder, ic2->o_holder);
982      }
983    else
984      {
985         atend:
986         b = inst->ibox;
987         if (_ibox_icon_find(b, bd)) return;
988         ic = _ibox_icon_new(b, bd);
989         if (!ic) return;
990         b->icons = eina_list_append(b->icons, ic);
991         e_box_pack_end(b->o_box, ic->o_holder);
992      }
993
994    evas_object_del(inst->ibox->o_drop);
995    inst->ibox->o_drop = NULL;
996    evas_object_del(inst->ibox->o_drop_over);
997    inst->ibox->o_drop_over = NULL;
998    _ibox_empty_handle(b);
999    e_gadcon_client_autoscroll_cb_set(inst->gcc, NULL, NULL);
1000    _ibox_resize_handle(inst->ibox);
1001    _gc_orient(inst->gcc, -1);
1002 }
1003
1004 static Eina_Bool
1005 _ibox_cb_event_border_add(void *data __UNUSED__, int type __UNUSED__, void *event)
1006 {
1007    E_Event_Border_Add *ev;
1008    IBox *b;
1009    IBox_Icon *ic;
1010    E_Desk *desk;
1011
1012    ev = event;
1013    /* add if iconic */
1014    desk = e_desk_current_get(ev->border->zone);
1015    if (ev->border->iconic)
1016      {
1017         Eina_List *l, *ibox;
1018         ibox = _ibox_zone_find(ev->border->zone);
1019         for (l = ibox; l; l = l->next)
1020           {
1021              b = l->data;
1022              if (_ibox_icon_find(b, ev->border)) continue;
1023              if ((b->inst->ci->show_desk) && (ev->border->desk != desk) && (!ev->border->sticky)) continue;
1024              ic = _ibox_icon_new(b, ev->border);
1025              if (!ic) continue;
1026              b->icons = eina_list_append(b->icons, ic);
1027              e_box_pack_end(b->o_box, ic->o_holder);
1028              _ibox_empty_handle(b);
1029              _ibox_resize_handle(b);
1030              _gc_orient(b->inst->gcc, -1);
1031           }
1032
1033         while (ibox)
1034           ibox = eina_list_remove_list(ibox, ibox);
1035      }
1036    return ECORE_CALLBACK_PASS_ON;
1037 }
1038
1039 static Eina_Bool
1040 _ibox_cb_event_border_remove(void *data __UNUSED__, int type __UNUSED__, void *event)
1041 {
1042    E_Event_Border_Remove *ev;
1043    IBox *b;
1044    IBox_Icon *ic;
1045    Eina_List *l, *ibox;
1046
1047    ev = event;
1048    /* find icon and remove if there */
1049    ibox = _ibox_zone_find(ev->border->zone);
1050    for (l = ibox; l; l = l->next)
1051      {
1052         b = l->data;
1053         ic = _ibox_icon_find(b, ev->border);
1054         if (!ic) continue;
1055         _ibox_icon_free(ic);
1056         b->icons = eina_list_remove(b->icons, ic);
1057         _ibox_empty_handle(b);
1058         _ibox_resize_handle(b);
1059         _gc_orient(b->inst->gcc, -1);
1060      }
1061    while (ibox)
1062      ibox = eina_list_remove_list(ibox, ibox);
1063
1064    return ECORE_CALLBACK_PASS_ON;
1065 }
1066
1067 static Eina_Bool
1068 _ibox_cb_event_border_iconify(void *data __UNUSED__, int type __UNUSED__, void *event)
1069 {
1070    E_Event_Border_Iconify *ev;
1071    IBox *b;
1072    IBox_Icon *ic;
1073    Eina_List *l, *ibox;
1074    E_Desk *desk;
1075
1076    ev = event;
1077    /* add icon for ibox for right zone */
1078    /* do some sort of anim when iconifying */
1079    desk = e_desk_current_get(ev->border->zone);
1080    ibox = _ibox_zone_find(ev->border->zone);
1081    for (l = ibox; l; l = l->next)
1082      {
1083         b = l->data;
1084         if (_ibox_icon_find(b, ev->border)) continue;
1085         if ((b->inst->ci->show_desk) && (ev->border->desk != desk) && (!ev->border->sticky)) continue;
1086         ic = _ibox_icon_new(b, ev->border);
1087         if (!ic) continue;
1088         b->icons = eina_list_append(b->icons, ic);
1089         e_box_pack_end(b->o_box, ic->o_holder);
1090         _ibox_empty_handle(b);
1091         _ibox_resize_handle(b);
1092         _gc_orient(b->inst->gcc, -1);
1093      }
1094
1095    while (ibox)
1096      ibox = eina_list_remove_list(ibox, ibox);
1097    return ECORE_CALLBACK_PASS_ON;
1098 }
1099
1100 static Eina_Bool
1101 _ibox_cb_event_border_uniconify(void *data __UNUSED__, int type __UNUSED__, void *event)
1102 {
1103    E_Event_Border_Uniconify *ev;
1104    IBox *b;
1105    IBox_Icon *ic;
1106    Eina_List *l, *ibox;
1107
1108    ev = event;
1109    /* del icon for ibox for right zone */
1110    /* do some sort of anim when uniconifying */
1111    ibox = _ibox_zone_find(ev->border->zone);
1112    for (l = ibox; l; l = l->next)
1113      {
1114         b = l->data;
1115         ic = _ibox_icon_find(b, ev->border);
1116         if (!ic) continue;
1117         _ibox_icon_free(ic);
1118         b->icons = eina_list_remove(b->icons, ic);
1119         _ibox_empty_handle(b);
1120         _ibox_resize_handle(b);
1121         _gc_orient(b->inst->gcc, -1);
1122      }
1123
1124    while (ibox)
1125      ibox = eina_list_remove_list(ibox, ibox);
1126
1127    return ECORE_CALLBACK_PASS_ON;
1128 }
1129
1130 static Eina_Bool
1131 _ibox_cb_event_border_icon_change(void *data __UNUSED__, int type __UNUSED__, void *event)
1132 {
1133    E_Event_Border_Icon_Change *ev;
1134    IBox *b;
1135    IBox_Icon *ic;
1136    Eina_List *l, *ibox;
1137
1138    ev = event;
1139    /* update icon */
1140    ibox = _ibox_zone_find(ev->border->zone);
1141    for (l = ibox; l; l = l->next)
1142      {
1143         b = l->data;
1144         ic = _ibox_icon_find(b, ev->border);
1145         if (!ic) continue;
1146         _ibox_icon_empty(ic);
1147         _ibox_icon_fill(ic);
1148      }
1149
1150    while (ibox)
1151      ibox = eina_list_remove_list(ibox, ibox);
1152
1153    return ECORE_CALLBACK_PASS_ON;
1154 }
1155
1156 static Eina_Bool
1157 _ibox_cb_event_border_urgent_change(void *data __UNUSED__, int type __UNUSED__, void *event)
1158 {
1159    E_Event_Border_Urgent_Change *ev;
1160    IBox *b;
1161    IBox_Icon *ic;
1162    Eina_List *l, *ibox;
1163
1164    ev = event;
1165    /* update icon */
1166    ibox = _ibox_zone_find(ev->border->zone);
1167    for (l = ibox; l; l = l->next)
1168      {
1169         b = l->data;
1170         ic = _ibox_icon_find(b, ev->border);
1171         if (!ic) continue;
1172         if (ev->border->client.icccm.urgent)
1173           {
1174              e_gadcon_urgent_show(b->inst->gcc->gadcon);
1175              edje_object_signal_emit(ic->o_holder, "e,state,urgent", "e");
1176              edje_object_signal_emit(ic->o_holder2, "e,state,urgent", "e");
1177           }
1178         else
1179           {
1180              edje_object_signal_emit(ic->o_holder, "e,state,not_urgent", "e");
1181              edje_object_signal_emit(ic->o_holder2, "e,state,not_urgent", "e");
1182           }
1183      }
1184
1185    return ECORE_CALLBACK_PASS_ON;
1186 }
1187
1188 static Eina_Bool
1189 _ibox_cb_event_border_zone_set(void *data __UNUSED__, int type __UNUSED__, void *event)
1190 {
1191    E_Event_Border_Zone_Set *ev;
1192
1193    ev = event;
1194    /* delete from current zone ibox, add to new one */
1195    if (ev->border->iconic)
1196      {
1197      }
1198    return 1;
1199 }
1200
1201 static Eina_Bool
1202 _ibox_cb_event_desk_show(void *data __UNUSED__, int type __UNUSED__, void *event)
1203 {
1204    E_Event_Desk_Show *ev;
1205    IBox *b;
1206    Eina_List *l, *ibox;
1207
1208    ev = event;
1209    /* delete all wins from ibox and add only for current desk */
1210    ibox = _ibox_zone_find(ev->desk->zone);
1211    for (l = ibox; l; l = l->next)
1212      {
1213         b = l->data;
1214         if (b->inst->ci->show_desk)
1215           {
1216              _ibox_empty(b);
1217              _ibox_fill(b);
1218              _ibox_resize_handle(b);
1219              _gc_orient(b->inst->gcc, -1);
1220           }
1221      }
1222
1223    while (ibox)
1224      ibox = eina_list_remove_list(ibox, ibox);
1225
1226    return ECORE_CALLBACK_PASS_ON;
1227 }
1228
1229 static Config_Item *
1230 _ibox_config_item_get(const char *id)
1231 {
1232    Eina_List *l;
1233    Config_Item *ci;
1234    char buf[128];
1235
1236    if (!id)
1237      {
1238         snprintf(buf, sizeof(buf), "%s.%d", _gadcon_class.name, ++uuid);
1239         id = buf;
1240      }
1241    else
1242      {
1243         /* Find old config */
1244         for (l = ibox_config->items; l; l = l->next)
1245           {
1246              ci = l->data;
1247              if ((ci->id) && (!strcmp(ci->id, id)))
1248                return ci;
1249           }
1250      }
1251    ci = E_NEW(Config_Item, 1);
1252    ci->id = eina_stringshare_add(id);
1253    ci->show_label = 0;
1254    ci->show_zone = 1;
1255    ci->show_desk = 0;
1256    ci->icon_label = 0;
1257    ibox_config->items = eina_list_append(ibox_config->items, ci);
1258    return ci;
1259 }
1260
1261 void
1262 _ibox_config_update(Config_Item *ci)
1263 {
1264    Eina_List *l;
1265    for (l = ibox_config->instances; l; l = l->next)
1266      {
1267         Instance *inst;
1268
1269         inst = l->data;
1270         if (inst->ci != ci) continue;
1271
1272         _ibox_empty(inst->ibox);
1273         _ibox_fill(inst->ibox);
1274         _ibox_resize_handle(inst->ibox);
1275         _gc_orient(inst->gcc, -1);
1276      }
1277 }
1278
1279 static void
1280 _ibox_cb_menu_configuration(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1281 {
1282    IBox *b;
1283    int ok = 1;
1284    Eina_List *l;
1285
1286    b = data;
1287    for (l = ibox_config->config_dialog; l; l = l->next)
1288      {
1289         E_Config_Dialog *cfd;
1290
1291         cfd = l->data;
1292         if (cfd->data == b->inst->ci)
1293           {
1294              ok = 0;
1295              break;
1296           }
1297      }
1298    if (ok) _config_ibox_module(b->inst->ci);
1299 }
1300
1301 /***************************************************************************/
1302 /**/
1303 /* module setup */
1304 EAPI E_Module_Api e_modapi =
1305 {
1306    E_MODULE_API_VERSION,
1307      "IBox"
1308 };
1309
1310 EAPI void *
1311 e_modapi_init(E_Module *m)
1312 {
1313    conf_item_edd = E_CONFIG_DD_NEW("IBox_Config_Item", Config_Item);
1314    #undef T
1315    #undef D
1316    #define T Config_Item
1317    #define D conf_item_edd
1318    E_CONFIG_VAL(D, T, id, STR);
1319    E_CONFIG_VAL(D, T, show_label, INT);
1320    E_CONFIG_VAL(D, T, show_zone, INT);
1321    E_CONFIG_VAL(D, T, show_desk, INT);
1322    E_CONFIG_VAL(D, T, icon_label, INT);
1323
1324    conf_edd = E_CONFIG_DD_NEW("IBox_Config", Config);
1325    #undef T
1326    #undef D
1327    #define T Config
1328    #define D conf_edd
1329    E_CONFIG_LIST(D, T, items, conf_item_edd);
1330
1331    ibox_config = e_config_domain_load("module.ibox", conf_edd);
1332    if (!ibox_config)
1333      {
1334         Config_Item *ci;
1335
1336         ibox_config = E_NEW(Config, 1);
1337         
1338         ci = E_NEW(Config_Item, 1);
1339         ci->id = eina_stringshare_add("ibox.1");
1340         ci->show_label = 0;
1341         ci->show_zone = 1;
1342         ci->show_desk = 0;
1343         ci->icon_label = 0;
1344         ibox_config->items = eina_list_append(ibox_config->items, ci);
1345      }
1346    else
1347      {
1348     Eina_List *removes = NULL;
1349         Eina_List *l;
1350         
1351         for (l = ibox_config->items; l; l = l->next)
1352           {
1353              Config_Item *ci = l->data;
1354              if (!ci->id)
1355                removes = eina_list_append(removes, ci);
1356              else
1357                {
1358                   Eina_List *ll;
1359                   
1360                   for (ll = l->next; ll; ll = ll->next)
1361                     {
1362                        Config_Item *ci2 = ll->data;
1363                        if ((ci2->id) && (!strcmp(ci->id, ci2->id)))
1364                          {
1365                             removes = eina_list_append(removes, ci);
1366                             break;
1367                          }
1368                     }
1369                }
1370           }
1371         while (removes)
1372           {
1373              Config_Item *ci = removes->data;
1374              removes = eina_list_remove_list(removes, removes);
1375              ibox_config->items = eina_list_remove(ibox_config->items, ci);
1376              if (ci->id) eina_stringshare_del(ci->id);
1377              free(ci);
1378           }
1379         for (l = ibox_config->items; l; l = l->next)
1380           {
1381              Config_Item *ci = l->data;
1382              if (ci->id)
1383                {
1384                   const char *p;
1385                   p = strrchr(ci->id, '.');
1386                   if (p)
1387                     {
1388                        int id;
1389                        
1390                        id = atoi(p + 1);
1391                        if (id > uuid) uuid = id;
1392                     }
1393                }
1394           }
1395      }
1396    
1397    ibox_config->module = m;
1398    
1399    ibox_config->handlers = eina_list_append
1400      (ibox_config->handlers, ecore_event_handler_add
1401       (E_EVENT_BORDER_ADD, _ibox_cb_event_border_add, NULL));
1402    ibox_config->handlers = eina_list_append
1403      (ibox_config->handlers, ecore_event_handler_add
1404       (E_EVENT_BORDER_REMOVE, _ibox_cb_event_border_remove, NULL));
1405    ibox_config->handlers = eina_list_append
1406      (ibox_config->handlers, ecore_event_handler_add
1407       (E_EVENT_BORDER_ICONIFY, _ibox_cb_event_border_iconify, NULL));
1408    ibox_config->handlers = eina_list_append
1409      (ibox_config->handlers, ecore_event_handler_add
1410       (E_EVENT_BORDER_UNICONIFY, _ibox_cb_event_border_uniconify, NULL));
1411    ibox_config->handlers = eina_list_append
1412      (ibox_config->handlers, ecore_event_handler_add
1413       (E_EVENT_BORDER_ICON_CHANGE, _ibox_cb_event_border_icon_change, NULL));
1414    ibox_config->handlers = eina_list_append
1415      (ibox_config->handlers, ecore_event_handler_add
1416       (E_EVENT_BORDER_URGENT_CHANGE,
1417        _ibox_cb_event_border_urgent_change, NULL));
1418    ibox_config->handlers = eina_list_append
1419      (ibox_config->handlers, ecore_event_handler_add
1420       (E_EVENT_BORDER_ZONE_SET, _ibox_cb_event_border_zone_set, NULL));
1421    ibox_config->handlers = eina_list_append
1422      (ibox_config->handlers, ecore_event_handler_add
1423       (E_EVENT_DESK_SHOW, _ibox_cb_event_desk_show, NULL));
1424
1425 /* FIXME: add these later for things taskbar-like functionality
1426    ibox_config->handlers = eina_list_append
1427      (ibox_config->handlers, ecore_event_handler_add
1428       (E_EVENT_BORDER_DESK_SET, _ibox_cb_event_border_zone_set, NULL));
1429    ibox_config->handlers = eina_list_append
1430      (ibox_config->handlers, ecore_event_handler_add
1431       (E_EVENT_BORDER_SHOW, _ibox_cb_event_border_zone_set, NULL));
1432    ibox_config->handlers = eina_list_append
1433      (ibox_config->handlers, ecore_event_handler_add
1434       (E_EVENT_BORDER_HIDE, _ibox_cb_event_border_zone_set, NULL));
1435    ibox_config->handlers = eina_list_append
1436      (ibox_config->handlers, ecore_event_handler_add
1437       (E_EVENT_BORDER_STACK, _ibox_cb_event_border_zone_set, NULL));
1438    ibox_config->handlers = eina_list_append
1439      (ibox_config->handlers, ecore_event_handler_add
1440       (E_EVENT_BORDER_STICK, _ibox_cb_event_border_zone_set, NULL));
1441  */
1442    e_gadcon_provider_register(&_gadcon_class);
1443    return m;
1444 }
1445
1446 EAPI int
1447 e_modapi_shutdown(E_Module *m __UNUSED__)
1448 {
1449    e_gadcon_provider_unregister(&_gadcon_class);
1450
1451    while (ibox_config->handlers)
1452      {
1453         ecore_event_handler_del(ibox_config->handlers->data);
1454         ibox_config->handlers = eina_list_remove_list(ibox_config->handlers, ibox_config->handlers);
1455      }
1456
1457    while (ibox_config->config_dialog)
1458      /* there is no need to eves_list_remove_list. It is done implicitly in
1459       * dialog _free_data function
1460       */
1461      e_object_del(E_OBJECT(ibox_config->config_dialog->data));
1462
1463    if (ibox_config->menu)
1464      {
1465         e_menu_post_deactivate_callback_set(ibox_config->menu, NULL, NULL);
1466         e_object_del(E_OBJECT(ibox_config->menu));
1467         ibox_config->menu = NULL;
1468      }
1469    while (ibox_config->items)
1470      {
1471         Config_Item *ci;
1472         
1473         ci = ibox_config->items->data;
1474         ibox_config->items = eina_list_remove_list(ibox_config->items, ibox_config->items);
1475         if (ci->id)
1476           eina_stringshare_del(ci->id);
1477         free(ci);
1478      }
1479
1480    free(ibox_config);
1481    ibox_config = NULL;
1482    E_CONFIG_DD_FREE(conf_item_edd);
1483    E_CONFIG_DD_FREE(conf_edd);
1484    return 1;
1485 }
1486
1487 EAPI int
1488 e_modapi_save(E_Module *m __UNUSED__)
1489 {
1490    e_config_domain_save("module.ibox", conf_edd, ibox_config);
1491    return 1;
1492 }