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