7d4ddd9e9e2f0b0158c6df7d5857310ecf9da92f
[framework/uifw/e17.git] / src / modules / ibar / e_mod_main.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 #ifndef MAX
5 # define MAX(x, y) (((x) > (y)) ? (x) : (y))
6 #endif
7
8 /* TODO:
9  * - Track execution status
10  */
11
12 /* gadcon requirements */
13 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
14 static void _gc_shutdown(E_Gadcon_Client *gcc);
15 static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
16 static const char *_gc_label(E_Gadcon_Client_Class *client_class);
17 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class, Evas *evas);
18 static const char *_gc_id_new(E_Gadcon_Client_Class *client_class);
19 static void _gc_id_del(E_Gadcon_Client_Class *client_class, const char *id);
20
21 /* and actually define the gadcon class that this module provides (just 1) */
22 static const E_Gadcon_Client_Class _gadcon_class =
23 {
24    GADCON_CLIENT_CLASS_VERSION,
25      "ibar",
26      {
27         _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, _gc_id_del,
28         e_gadcon_site_is_not_toolbar
29      },
30    E_GADCON_CLIENT_STYLE_INSET
31 };
32
33 /* actual module specifics */
34 typedef struct _Instance  Instance;
35 typedef struct _IBar IBar;
36 typedef struct _IBar_Icon IBar_Icon;
37
38 struct _Instance
39 {
40    E_Gadcon_Client *gcc;
41    Evas_Object *o_ibar;
42    IBar *ibar;
43    E_Drop_Handler *drop_handler;
44    Config_Item *ci;
45    E_Gadcon_Orient orient;
46 };
47
48 struct _IBar
49 {
50    Instance *inst;
51    Evas_Object *o_box, *o_drop;
52    Evas_Object *o_drop_over, *o_empty;
53    IBar_Icon *ic_drop_before;
54    int drop_before;
55    E_Order *apps;
56    Eina_List *icons;
57    Evas_Coord dnd_x, dnd_y;
58 };
59
60 struct _IBar_Icon
61 {
62    IBar *ibar;
63    Evas_Object *o_holder, *o_icon;
64    Evas_Object *o_holder2, *o_icon2;
65    Efreet_Desktop *app;
66    int mouse_down;
67    struct 
68      {
69         unsigned char start : 1;
70         unsigned char dnd : 1;
71         int x, y;
72      } drag;
73 };
74
75 static IBar *_ibar_new(Evas *evas, Instance *inst);
76 static void _ibar_free(IBar *b);
77 static void _ibar_cb_empty_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _ibar_empty_handle(IBar *b);
79 static void _ibar_fill(IBar *b);
80 static void _ibar_empty(IBar *b);
81 static void _ibar_orient_set(IBar *b, int horizontal);
82 static void _ibar_resize_handle(IBar *b);
83 static void _ibar_instance_drop_zone_recalc(Instance *inst);
84 static Config_Item *_ibar_config_item_get(const char *id);
85 static IBar_Icon *_ibar_icon_at_coord(IBar *b, Evas_Coord x, Evas_Coord y);
86 static IBar_Icon *_ibar_icon_new(IBar *b, Efreet_Desktop *desktop);
87 static void _ibar_icon_free(IBar_Icon *ic);
88 static void _ibar_icon_fill(IBar_Icon *ic);
89 static void _ibar_icon_empty(IBar_Icon *ic);
90 static void _ibar_icon_signal_emit(IBar_Icon *ic, char *sig, char *src);
91 static void _ibar_cb_app_change(void *data, E_Order *eo);
92 static void _ibar_cb_obj_moveresize(void *data, Evas *e, Evas_Object *obj, void *event_info);
93 static void _ibar_cb_menu_icon_new(void *data, E_Menu *m, E_Menu_Item *mi);
94 static void _ibar_cb_menu_icon_add(void *data, E_Menu *m, E_Menu_Item *mi);
95 static void _ibar_cb_menu_icon_properties(void *data, E_Menu *m, E_Menu_Item *mi);
96 static void _ibar_cb_menu_icon_remove(void *data, E_Menu *m, E_Menu_Item *mi);
97 static void _ibar_cb_menu_configuration(void *data, E_Menu *m, E_Menu_Item *mi);
98 static void _ibar_cb_menu_post(void *data, E_Menu *m);
99 static void _ibar_cb_icon_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info);
100 static void _ibar_cb_icon_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info);
101 static void _ibar_cb_icon_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
102 static void _ibar_cb_icon_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
103 static void _ibar_cb_icon_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
104 static void _ibar_cb_icon_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
105 static void _ibar_cb_icon_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
106 static void _ibar_inst_cb_enter(void *data, const char *type, void *event_info);
107 static void _ibar_inst_cb_move(void *data, const char *type, void *event_info);
108 static void _ibar_inst_cb_leave(void *data, const char *type, void *event_info);
109 static void _ibar_inst_cb_drop(void *data, const char *type, void *event_info);
110 static void _ibar_cb_drag_finished(E_Drag *data, int dropped);
111 static void _ibar_drop_position_update(Instance *inst, Evas_Coord x, Evas_Coord y);
112 static void _ibar_inst_cb_scroll(void *data);
113 static Eina_Bool  _ibar_cb_config_icons(void *data, int ev_type, void *ev);
114
115 static E_Config_DD *conf_edd = NULL;
116 static E_Config_DD *conf_item_edd = NULL;
117
118 Config *ibar_config = NULL;
119
120 static E_Gadcon_Client *
121 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
122 {
123    IBar *b;
124    Evas_Object *o;
125    E_Gadcon_Client *gcc;
126    Instance *inst;
127    Evas_Coord x, y, w, h;
128    const char *drop[] = { "enlightenment/desktop", "enlightenment/border", "text/uri-list" };
129    Config_Item *ci;
130
131    inst = E_NEW(Instance, 1);
132
133    ci = _ibar_config_item_get(id);
134    inst->ci = ci;
135    if (!ci->dir) ci->dir = eina_stringshare_add("default");
136    b = _ibar_new(gc->evas, inst);
137    o = b->o_box;
138    gcc = e_gadcon_client_new(gc, name, id, style, o);
139    gcc->data = inst;
140
141    inst->gcc = gcc;
142    inst->o_ibar = o;
143    inst->orient = E_GADCON_ORIENT_HORIZ;
144
145    evas_object_geometry_get(o, &x, &y, &w, &h);
146    inst->drop_handler =
147      e_drop_handler_add(E_OBJECT(inst->gcc), inst,
148                         _ibar_inst_cb_enter, _ibar_inst_cb_move,
149                         _ibar_inst_cb_leave, _ibar_inst_cb_drop,
150                         drop, 3, x, y, w,  h);
151    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE,
152                                   _ibar_cb_obj_moveresize, inst);
153    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
154                                   _ibar_cb_obj_moveresize, inst);
155    ibar_config->instances = eina_list_append(ibar_config->instances, inst);
156    return gcc;
157 }
158
159 static void
160 _gc_shutdown(E_Gadcon_Client *gcc)
161 {
162    Instance *inst;
163
164    inst = gcc->data;
165    ibar_config->instances = eina_list_remove(ibar_config->instances, inst);
166    e_drop_handler_del(inst->drop_handler);
167    _ibar_free(inst->ibar);
168    E_FREE(inst);
169 }
170
171 static void
172 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient)
173 {
174    Instance *inst;
175
176    inst = gcc->data;
177    if ((int)orient != -1) inst->orient = orient;
178
179    switch (inst->orient)
180      {
181       case E_GADCON_ORIENT_FLOAT:
182       case E_GADCON_ORIENT_HORIZ:
183       case E_GADCON_ORIENT_TOP:
184       case E_GADCON_ORIENT_BOTTOM:
185       case E_GADCON_ORIENT_CORNER_TL:
186       case E_GADCON_ORIENT_CORNER_TR:
187       case E_GADCON_ORIENT_CORNER_BL:
188       case E_GADCON_ORIENT_CORNER_BR:
189         _ibar_orient_set(inst->ibar, 1);
190         e_gadcon_client_aspect_set(gcc, eina_list_count(inst->ibar->icons) * 16, 16);
191         break;
192       case E_GADCON_ORIENT_VERT:
193       case E_GADCON_ORIENT_LEFT:
194       case E_GADCON_ORIENT_RIGHT:
195       case E_GADCON_ORIENT_CORNER_LT:
196       case E_GADCON_ORIENT_CORNER_RT:
197       case E_GADCON_ORIENT_CORNER_LB:
198       case E_GADCON_ORIENT_CORNER_RB:
199         _ibar_orient_set(inst->ibar, 0);
200         e_gadcon_client_aspect_set(gcc, 16, eina_list_count(inst->ibar->icons) * 16);
201         break;
202       default:
203         break;
204      }
205    e_gadcon_client_min_size_set(gcc, 16, 16);
206 }
207
208 static const char *
209 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
210 {
211    return _("IBar");
212 }
213
214 static Evas_Object *
215 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
216 {
217    Evas_Object *o;
218    char buf[PATH_MAX];
219
220    o = edje_object_add(evas);
221    snprintf(buf, sizeof(buf), "%s/e-module-ibar.edj",
222             e_module_dir_get(ibar_config->module));
223    edje_object_file_set(o, buf, "icon");
224    return o;
225 }
226
227 static const char *
228 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
229 {
230    Config_Item *ci;
231
232    ci = _ibar_config_item_get(NULL);
233    return ci->id;
234 }
235
236 static void
237 _gc_id_del(E_Gadcon_Client_Class *client_class __UNUSED__, const char *id __UNUSED__)
238 {
239 /* yes - don't do this. on shutdown gadgets are deleted and this means config
240  * for them is deleted - that means empty config is saved. keep them around
241  * as if u add a gadget back it can pick up its old config again
242  * 
243    Config_Item *ci;
244
245    ci = _ibar_config_item_get(id);
246    if (ci)
247      {
248         if (ci->id) eina_stringshare_del(ci->id);
249         ibar_config->items = eina_list_remove(ibar_config->items, ci);
250      }
251  */
252 }
253
254 static IBar *
255 _ibar_new(Evas *evas, Instance *inst)
256 {
257    IBar *b;
258    char buf[PATH_MAX];
259
260    b = E_NEW(IBar, 1);
261    inst->ibar = b;
262    b->inst = inst;
263    b->o_box = e_box_add(evas);
264    e_box_homogenous_set(b->o_box, 1);
265    e_box_orientation_set(b->o_box, 1);
266    e_box_align_set(b->o_box, 0.5, 0.5);
267    if (inst->ci->dir[0] != '/')
268      e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order", 
269                          inst->ci->dir);
270    else
271      eina_strlcpy(buf, inst->ci->dir, sizeof(buf));
272    b->apps = e_order_new(buf);
273    e_order_update_callback_set(b->apps, _ibar_cb_app_change, b);
274    _ibar_fill(b);
275    return b;
276 }
277
278 static void
279 _ibar_free(IBar *b)
280 {
281    _ibar_empty(b);
282    evas_object_del(b->o_box);
283    if (b->o_drop) evas_object_del(b->o_drop);
284    if (b->o_drop_over) evas_object_del(b->o_drop_over);
285    if (b->o_empty) evas_object_del(b->o_empty);
286    e_order_update_callback_set(b->apps, NULL, NULL);
287    if (b->apps) e_object_del(E_OBJECT(b->apps));
288    E_FREE(b);
289 }
290
291 static void
292 _ibar_cb_empty_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
293 {
294    Evas_Event_Mouse_Down *ev;
295    IBar *b;
296
297    ev = event_info;
298    b = data;
299    if (!ibar_config->menu)
300      {
301         E_Menu *m;
302         E_Menu_Item *mi;
303         int cx, cy, cw, ch;
304
305         m = e_menu_new();
306         mi = e_menu_item_new(m);
307         e_menu_item_label_set(mi, _("Settings"));
308         e_util_menu_item_theme_icon_set(mi, "configure");
309         e_menu_item_callback_set(mi, _ibar_cb_menu_configuration, b);
310
311         m = e_gadcon_client_util_menu_items_append(b->inst->gcc, m, 0);
312         e_menu_post_deactivate_callback_set(m, _ibar_cb_menu_post, NULL);
313         ibar_config->menu = m;
314
315         e_gadcon_canvas_zone_geometry_get(b->inst->gcc->gadcon,
316                                           &cx, &cy, &cw, &ch);
317         e_menu_activate_mouse(m,
318                               e_util_zone_current_get(e_manager_current_get()),
319                               cx + ev->output.x, cy + ev->output.y, 1, 1,
320                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
321      }
322 }
323
324 static void
325 _ibar_empty_handle(IBar *b)
326 {
327    if (!b->icons)
328      {
329         if (!b->o_empty)
330           {
331              Evas_Coord w, h;
332
333              b->o_empty = evas_object_rectangle_add(evas_object_evas_get(b->o_box));
334              evas_object_event_callback_add(b->o_empty, 
335                                             EVAS_CALLBACK_MOUSE_DOWN, 
336                                             _ibar_cb_empty_mouse_down, b);
337              evas_object_color_set(b->o_empty, 0, 0, 0, 0);
338              evas_object_show(b->o_empty);
339              e_box_pack_end(b->o_box, b->o_empty);
340              evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
341              if (e_box_orientation_get(b->o_box))
342                w = h;
343              else
344                h = w;
345              e_box_pack_options_set(b->o_empty,
346                                     1, 1, /* fill */
347                                     1, 1, /* expand */
348                                     0.5, 0.5, /* align */
349                                     w, h, /* min */
350                                     9999, 9999 /* max */
351                                     );
352           }
353      }
354    else if (b->o_empty)
355      {
356         evas_object_del(b->o_empty);
357         b->o_empty = NULL;
358      }
359 }
360
361 static void
362 _ibar_fill(IBar *b)
363 {
364    if (b->apps)
365      {
366         Efreet_Desktop *desktop;
367         const Eina_List *l;
368
369         EINA_LIST_FOREACH(b->apps->desktops, l, desktop)
370           {
371              IBar_Icon *ic = _ibar_icon_new(b, desktop);
372              b->icons = eina_list_append(b->icons, ic);
373              e_box_pack_end(b->o_box, ic->o_holder);
374           }
375      }
376    _ibar_empty_handle(b);
377    _ibar_resize_handle(b);
378 }
379
380 static void
381 _ibar_empty(IBar *b)
382 {
383    IBar_Icon *ic;
384
385    EINA_LIST_FREE(b->icons, ic)
386      _ibar_icon_free(ic);
387
388    _ibar_empty_handle(b);
389 }
390
391 static void
392 _ibar_orient_set(IBar *b, int horizontal)
393 {
394    e_box_orientation_set(b->o_box, horizontal);
395    e_box_align_set(b->o_box, 0.5, 0.5);
396 }
397
398 static void
399 _ibar_resize_handle(IBar *b)
400 {
401    const Eina_List *l;
402    IBar_Icon *ic;
403    Evas_Coord w, h;
404
405    evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
406    if (e_box_orientation_get(b->o_box))
407      w = h;
408    else
409      h = w;
410    e_box_freeze(b->o_box);
411    EINA_LIST_FOREACH(b->icons, l, ic)
412      {
413         e_box_pack_options_set(ic->o_holder,
414                                1, 1, /* fill */
415                                0, 0, /* expand */
416                                0.5, 0.5, /* align */
417                                w, h, /* min */
418                                w, h /* max */
419                                );
420      }
421    e_box_thaw(b->o_box);
422 }
423
424 static void
425 _ibar_instance_drop_zone_recalc(Instance *inst)
426 {
427    Evas_Coord x, y, w, h;
428
429    e_gadcon_client_viewport_geometry_get(inst->gcc, &x, &y, &w, &h);
430    e_drop_handler_geometry_set(inst->drop_handler, x, y, w, h);
431 }  
432
433 static Config_Item *
434 _ibar_config_item_get(const char *id)
435 {
436    Config_Item *ci;
437
438    GADCON_CLIENT_CONFIG_GET(Config_Item, ibar_config->items, _gadcon_class, id);
439
440    ci = E_NEW(Config_Item, 1);
441    ci->id = eina_stringshare_add(id);
442    ci->dir = eina_stringshare_add("default");
443    ci->show_label = 1;
444    ci->eap_label = 0;
445    ibar_config->items = eina_list_append(ibar_config->items, ci);
446    return ci;
447 }
448
449 void
450 _ibar_config_update(Config_Item *ci)
451 {
452    const Eina_List *l;
453    Instance *inst;
454
455    EINA_LIST_FOREACH(ibar_config->instances, l, inst)
456      {
457         char buf[PATH_MAX];
458         const Eina_List *i;
459         IBar_Icon *ic;
460
461         if (inst->ci != ci) continue;
462
463         _ibar_empty(inst->ibar);
464         if (inst->ibar->apps)
465           e_object_del(E_OBJECT(inst->ibar->apps));
466         if (inst->ci->dir[0] != '/')
467           e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order", 
468                               inst->ci->dir);
469         else
470           eina_strlcpy(buf, inst->ci->dir, sizeof(buf));
471         inst->ibar->apps = e_order_new(buf);
472         _ibar_fill(inst->ibar);
473         _ibar_resize_handle(inst->ibar);
474         _gc_orient(inst->gcc, -1);
475
476         EINA_LIST_FOREACH(inst->ibar->icons, i, ic)
477           {
478              switch (ci->eap_label)
479                {
480                 case 0:
481                   edje_object_part_text_set(ic->o_holder2, "e.text.label", 
482                                             ic->app->name);
483                   break;
484                 case 1:
485                   edje_object_part_text_set(ic->o_holder2, "e.text.label", 
486                                             ic->app->comment);
487                   break;
488                 case 2:
489                   edje_object_part_text_set(ic->o_holder2, "e.text.label", 
490                                             ic->app->generic_name);
491                   break;
492                }
493           }
494      }
495 }
496
497 static IBar_Icon *
498 _ibar_icon_at_coord(IBar *b, Evas_Coord x, Evas_Coord y)
499 {
500    const Eina_List *l;
501    IBar_Icon *ic;
502
503    EINA_LIST_FOREACH(b->icons, l, ic)
504      {
505         Evas_Coord dx, dy, dw, dh;
506
507         evas_object_geometry_get(ic->o_holder, &dx, &dy, &dw, &dh);
508         if (E_INSIDE(x, y, dx, dy, dw, dh)) return ic;
509      }
510    return NULL;
511 }
512
513 static IBar_Icon *
514 _ibar_icon_new(IBar *b, Efreet_Desktop *desktop)
515 {
516    IBar_Icon *ic;
517
518    ic = E_NEW(IBar_Icon, 1);
519    ic->ibar = b;
520    ic->app = desktop;
521    ic->o_holder = edje_object_add(evas_object_evas_get(b->o_box));
522    e_theme_edje_object_set(ic->o_holder, "base/theme/modules/ibar",
523                            "e/modules/ibar/icon");
524    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_IN,  
525                                   _ibar_cb_icon_mouse_in,  ic);
526    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_OUT, 
527                                   _ibar_cb_icon_mouse_out, ic);
528    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_DOWN, 
529                                   _ibar_cb_icon_mouse_down, ic);
530    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_UP, 
531                                   _ibar_cb_icon_mouse_up, ic);
532    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_MOVE, 
533                                   _ibar_cb_icon_mouse_move, ic);
534    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOVE, 
535                                   _ibar_cb_icon_move, ic);
536    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_RESIZE, 
537                                   _ibar_cb_icon_resize, ic);
538    evas_object_show(ic->o_holder);
539
540    ic->o_holder2 = edje_object_add(evas_object_evas_get(b->o_box));
541    e_theme_edje_object_set(ic->o_holder2, "base/theme/modules/ibar",
542                            "e/modules/ibar/icon_overlay");
543    evas_object_layer_set(ic->o_holder2, 9999);
544    evas_object_pass_events_set(ic->o_holder2, 1);
545    evas_object_show(ic->o_holder2);
546
547    _ibar_icon_fill(ic);
548    return ic;
549 }
550
551 static void
552 _ibar_icon_free(IBar_Icon *ic)
553 {
554    if (ibar_config->menu)
555      {
556         e_menu_post_deactivate_callback_set(ibar_config->menu, NULL, NULL);
557         e_object_del(E_OBJECT(ibar_config->menu));
558         ibar_config->menu = NULL;
559      }
560    if (ic->ibar->ic_drop_before == ic)
561      ic->ibar->ic_drop_before = NULL;
562    _ibar_icon_empty(ic);
563    evas_object_del(ic->o_holder);
564    evas_object_del(ic->o_holder2);
565    E_FREE(ic);
566 }
567
568 static void
569 _ibar_icon_fill(IBar_Icon *ic)
570 {
571    if (ic->o_icon) evas_object_del(ic->o_icon);
572    ic->o_icon = e_icon_add(evas_object_evas_get(ic->ibar->o_box));
573    e_icon_fdo_icon_set(ic->o_icon, ic->app->icon);
574    edje_object_part_swallow(ic->o_holder, "e.swallow.content", ic->o_icon);
575    evas_object_pass_events_set(ic->o_icon, 1);
576    evas_object_show(ic->o_icon);
577    if (ic->o_icon2) evas_object_del(ic->o_icon2);
578    ic->o_icon2 = e_icon_add(evas_object_evas_get(ic->ibar->o_box));
579    e_icon_fdo_icon_set(ic->o_icon2, ic->app->icon);
580    edje_object_part_swallow(ic->o_holder2, "e.swallow.content", ic->o_icon2);
581    evas_object_pass_events_set(ic->o_icon2, 1);
582    evas_object_show(ic->o_icon2);
583
584    switch (ic->ibar->inst->ci->eap_label) 
585      {
586       case 0: /* Eap Name */
587         edje_object_part_text_set(ic->o_holder2, "e.text.label", ic->app->name);
588         break;
589       case 1: /* Eap Comment */
590         edje_object_part_text_set(ic->o_holder2, "e.text.label", ic->app->comment);
591         break;  
592       case 2: /* Eap Generic */
593         edje_object_part_text_set(ic->o_holder2, "e.text.label", ic->app->generic_name);
594         break;  
595      }
596 }
597
598 static void
599 _ibar_icon_empty(IBar_Icon *ic)
600 {
601    if (ic->o_icon) evas_object_del(ic->o_icon);
602    if (ic->o_icon2) evas_object_del(ic->o_icon2);
603    ic->o_icon = NULL;
604    ic->o_icon2 = NULL;
605 }
606
607 static void
608 _ibar_icon_signal_emit(IBar_Icon *ic, char *sig, char *src)
609 {
610    if (ic->o_holder)
611      edje_object_signal_emit(ic->o_holder, sig, src);
612    if (ic->o_icon)
613      edje_object_signal_emit(ic->o_icon, sig, src);
614    if (ic->o_holder2)
615      edje_object_signal_emit(ic->o_holder2, sig, src);
616    if (ic->o_icon2)
617      edje_object_signal_emit(ic->o_icon2, sig, src);
618 }
619
620 static void
621 _ibar_cb_app_change(void *data, E_Order *eo __UNUSED__)
622 {
623    IBar *b;
624
625    b = data;
626    if (!b->apps) return;
627    _ibar_empty(b);
628    _ibar_fill(b);
629    _ibar_resize_handle(b);
630    if (b->inst) _gc_orient(b->inst->gcc, -1);
631 }
632
633 static void
634 _ibar_cb_obj_moveresize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
635 {
636    Instance *inst;
637
638    inst = data;
639    _ibar_resize_handle(inst->ibar);
640    _ibar_instance_drop_zone_recalc(inst);
641 }
642
643 static void 
644 _ibar_cb_menu_icon_new(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
645 {
646    E_Container *con;
647
648    if (!e_configure_registry_exists("applications/new_application")) return;
649    con = e_container_current_get(e_manager_current_get());
650    e_configure_registry_call("applications/new_application", con, NULL);
651 }
652
653 static void 
654 _ibar_cb_menu_icon_add(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
655 {
656    E_Container *con;
657
658    if (!e_configure_registry_exists("applications/ibar_applications")) return;
659    con = e_container_current_get(e_manager_current_get());
660    e_configure_registry_call("applications/ibar_applications", con, NULL);
661 }
662
663 static void
664 _ibar_cb_menu_icon_properties(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
665 {
666    IBar_Icon *ic;
667
668    ic = data;
669    e_desktop_edit(ic->ibar->inst->gcc->gadcon->zone->container, ic->app);
670 }
671
672 static void
673 _ibar_cb_menu_icon_remove(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
674 {
675    IBar_Icon *ic;
676    E_Gadcon_Client *gc;
677
678    ic = data;
679    ic->ibar->icons = eina_list_remove(ic->ibar->icons, ic);
680    _ibar_resize_handle(ic->ibar);
681    gc = ic->ibar->inst->gcc;
682    _gc_orient(gc, -1);
683    e_order_remove(ic->ibar->apps, ic->app);
684    _ibar_icon_free(ic);
685 }
686
687 static void
688 _ibar_cb_menu_configuration(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
689 {
690    IBar *b;
691
692    b = data;
693    _config_ibar_module(b->inst->ci);
694 }
695
696 /*
697 static void
698 _ibar_cb_menu_add(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
699 {
700    IBar *b;
701
702    b = data;
703    e_configure_registry_call("internal/ibar_other",
704                              b->inst->gcc->gadcon->zone->container,
705                              b->apps->path);
706 }
707 */
708
709 static void
710 _ibar_cb_menu_post(void *data __UNUSED__, E_Menu *m __UNUSED__)
711 {
712    if (!ibar_config->menu) return;
713    e_object_del(E_OBJECT(ibar_config->menu));
714    ibar_config->menu = NULL;
715 }
716
717 static void
718 _ibar_cb_icon_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
719 {
720    IBar_Icon *ic;
721
722    ic = data;
723    _ibar_icon_signal_emit(ic, "e,state,focused", "e");
724    if (ic->ibar->inst->ci->show_label)
725      _ibar_icon_signal_emit(ic, "e,action,show,label", "e");
726 }
727
728 static void
729 _ibar_cb_icon_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
730 {
731    IBar_Icon *ic;
732
733    ic = data;
734    _ibar_icon_signal_emit(ic, "e,state,unfocused", "e");
735    if (ic->ibar->inst->ci->show_label)
736      _ibar_icon_signal_emit(ic, "e,action,hide,label", "e");
737 }
738
739 static void
740 _ibar_cb_icon_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
741 {
742    Evas_Event_Mouse_Down *ev;
743    IBar_Icon *ic;
744
745    ev = event_info;
746    ic = data;
747    if (ev->button == 1)
748      {
749         ic->drag.x = ev->output.x;
750         ic->drag.y = ev->output.y;
751         ic->drag.start = 1;
752         ic->drag.dnd = 0;
753         ic->mouse_down = 1;
754      }
755    else if ((ev->button == 3) && (!ibar_config->menu))
756      {
757         E_Menu *m, *mo;
758         E_Menu_Item *mi;
759         char buf[256];
760         int cx, cy;
761
762         m = e_menu_new();
763
764         /* FIXME: other icon options go here too */
765         mo = e_menu_new();
766
767         if (e_configure_registry_exists("applications/new_application")) 
768           {
769              mi = e_menu_item_new(m);
770              e_menu_item_label_set(mi, _("Create new Icon"));
771              e_util_menu_item_theme_icon_set(mi, "document-new");
772              e_menu_item_callback_set(mi, _ibar_cb_menu_icon_new, NULL);
773
774              mi = e_menu_item_new(m);
775              e_menu_item_separator_set(mi, 1);
776           }
777
778         if (e_configure_registry_exists("applications/ibar_applications")) 
779           {
780              mi = e_menu_item_new(m);
781              e_menu_item_label_set(mi, _("Contents"));
782              e_util_menu_item_theme_icon_set(mi, "list-add");
783              e_menu_item_callback_set(mi, _ibar_cb_menu_icon_add, NULL);
784           }
785
786         mi = e_menu_item_new(m);
787         e_menu_item_label_set(mi, _("Settings"));
788         e_util_menu_item_theme_icon_set(mi, "configure");
789         e_menu_item_callback_set(mi, _ibar_cb_menu_configuration, ic->ibar);
790
791         m = e_gadcon_client_util_menu_items_append(ic->ibar->inst->gcc, m, 0);
792         e_menu_post_deactivate_callback_set(m, _ibar_cb_menu_post, NULL);
793         ibar_config->menu = m;
794
795         mi = e_menu_item_new(mo);
796         e_menu_item_label_set(mi, _("Properties"));
797         e_util_menu_item_theme_icon_set(mi, "configure");
798         e_menu_item_callback_set(mi, _ibar_cb_menu_icon_properties, ic);
799
800         mi = e_menu_item_new(mo);
801         e_menu_item_label_set(mi, _("Remove"));
802         e_util_menu_item_theme_icon_set(mi, "list-remove");
803         e_menu_item_callback_set(mi, _ibar_cb_menu_icon_remove, ic);
804
805         mi = e_menu_item_new_relative(m, NULL);
806         snprintf(buf, sizeof(buf), "Icon %s", ic->app->name);
807         e_menu_item_label_set(mi, _(buf));
808         e_util_desktop_menu_item_icon_add(ic->app, 
809                                           e_util_icon_size_normalize(24 * e_scale), 
810                                           mi);
811         e_menu_item_submenu_set(mi, mo);
812
813         e_gadcon_canvas_zone_geometry_get(ic->ibar->inst->gcc->gadcon,
814                                           &cx, &cy, NULL, NULL);
815         e_menu_activate_mouse(m,
816                               e_util_zone_current_get(e_manager_current_get()),
817                               cx + ev->output.x, cy + ev->output.y, 1, 1,
818                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
819      }
820 }
821
822 static void
823 _ibar_cb_icon_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
824 {
825    Evas_Event_Mouse_Up *ev;
826    IBar_Icon *ic;
827
828    ev = event_info;
829    ic = data;
830    if ((ev->button == 1) && (!ic->drag.dnd) && (ic->mouse_down == 1))
831      {
832         if (ic->app->type == EFREET_DESKTOP_TYPE_APPLICATION)
833           e_exec(ic->ibar->inst->gcc->gadcon->zone, ic->app, NULL, NULL, "ibar");
834         else if (ic->app->type == EFREET_DESKTOP_TYPE_LINK)
835           {
836              if (!strncasecmp(ic->app->url, "file:", 5))
837                {
838                   E_Action *act;
839
840                   act = e_action_find("fileman");
841                   if (act) act->func.go(E_OBJECT(obj), ic->app->url + 5);
842                }
843           }
844
845         ic->drag.start = 0;
846         ic->drag.dnd = 0;
847         ic->mouse_down = 0;
848         /* TODO: bring back "e,action,start|stop" for the startup_notify apps
849          *       when startup_notify is used again
850          */
851         _ibar_icon_signal_emit(ic, "e,action,exec", "e");
852      }
853 }
854
855 static void
856 _ibar_cb_icon_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
857 {
858    Evas_Event_Mouse_Move *ev;
859    IBar_Icon *ic;
860
861    ev = event_info;
862    ic = data;
863    if (ic->drag.start)
864      {
865         int dx, dy;
866
867         dx = ev->cur.output.x - ic->drag.x;
868         dy = ev->cur.output.y - ic->drag.y;
869         if (((dx * dx) + (dy * dy)) >
870             (e_config->drag_resist * e_config->drag_resist))
871           {
872              E_Drag *d;
873              Evas_Object *o;
874              Evas_Coord x, y, w, h;
875              unsigned int size;
876              const char *drag_types[] = { "enlightenment/desktop" };
877              E_Gadcon_Client *gc;
878
879              ic->drag.dnd = 1;
880              ic->drag.start = 0;
881
882              evas_object_geometry_get(ic->o_icon, &x, &y, &w, &h);
883              d = e_drag_new(ic->ibar->inst->gcc->gadcon->zone->container,
884                             x, y, drag_types, 1,
885                             ic->app, -1, NULL, _ibar_cb_drag_finished);
886              efreet_desktop_ref(ic->app);
887              size = MAX(w, h);
888              o = e_util_desktop_icon_add(ic->app, size, e_drag_evas_get(d));
889              e_drag_object_set(d, o);
890
891              e_drag_resize(d, w, h);
892              e_drag_start(d, ic->drag.x, ic->drag.y);
893              ic->ibar->icons = eina_list_remove(ic->ibar->icons, ic);
894              _ibar_resize_handle(ic->ibar);
895              gc = ic->ibar->inst->gcc;
896              _gc_orient(gc, -1);
897              e_order_remove(ic->ibar->apps, ic->app);
898              _ibar_icon_free(ic);
899           }
900      }
901 }
902
903 static void
904 _ibar_cb_icon_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
905 {
906    IBar_Icon *ic;
907    Evas_Coord x, y;
908
909    ic = data;
910    evas_object_geometry_get(ic->o_holder, &x, &y, NULL, NULL);
911    evas_object_move(ic->o_holder2, x, y);
912    evas_object_raise(ic->o_holder2);
913 }
914
915 static void
916 _ibar_cb_icon_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
917 {
918    IBar_Icon *ic;
919    Evas_Coord w, h;
920
921    ic = data;
922    evas_object_geometry_get(ic->o_holder, NULL, NULL, &w, &h);
923    evas_object_resize(ic->o_holder2, w, h);
924    evas_object_raise(ic->o_holder2);
925 }
926
927 static void
928 _ibar_cb_drop_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
929 {
930    IBar *b;
931    Evas_Coord x, y;
932
933    b = data;
934    evas_object_geometry_get(b->o_drop, &x, &y, NULL, NULL);
935    evas_object_move(b->o_drop_over, x, y);
936 }
937
938 static void
939 _ibar_cb_drop_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
940 {
941    IBar *b;
942    Evas_Coord w, h;
943
944    b = data;
945    evas_object_geometry_get(b->o_drop, NULL, NULL, &w, &h);
946    evas_object_resize(b->o_drop_over, w, h);
947 }
948
949 static void
950 _ibar_cb_drag_finished(E_Drag *drag, int dropped __UNUSED__)
951 {
952    efreet_desktop_unref(drag->data);
953 }
954
955 static void
956 _ibar_inst_cb_scroll(void *data)
957 {
958    Instance *inst;
959
960    /* Update the position of the dnd to handle for autoscrolling
961     * gadgets. */
962    inst = data;
963    _ibar_drop_position_update(inst, inst->ibar->dnd_x, inst->ibar->dnd_y);
964 }
965
966 static void
967 _ibar_drop_position_update(Instance *inst, Evas_Coord x, Evas_Coord y)
968 {
969    IBar_Icon *ic;
970
971    inst->ibar->dnd_x = x;
972    inst->ibar->dnd_y = y;
973
974    if (inst->ibar->o_drop) e_box_unpack(inst->ibar->o_drop);
975    ic = _ibar_icon_at_coord(inst->ibar, x, y);
976
977    inst->ibar->ic_drop_before = ic;
978    if (ic)
979      {
980         Evas_Coord ix, iy, iw, ih;
981         int before = 0;
982
983         evas_object_geometry_get(ic->o_holder, &ix, &iy, &iw, &ih);
984         if (e_box_orientation_get(inst->ibar->o_box))
985           {
986              if (x < (ix + (iw / 2))) before = 1;
987           }
988         else
989           {
990              if (y < (iy + (ih / 2))) before = 1;
991           }
992         if (before)
993           e_box_pack_before(inst->ibar->o_box, inst->ibar->o_drop, ic->o_holder);
994         else
995           e_box_pack_after(inst->ibar->o_box, inst->ibar->o_drop, ic->o_holder);
996         inst->ibar->drop_before = before;
997      }
998    else e_box_pack_end(inst->ibar->o_box, inst->ibar->o_drop);
999    e_box_pack_options_set(inst->ibar->o_drop,
1000                           1, 1, /* fill */
1001                           1, 1, /* expand */
1002                           0.5, 0.5, /* align */
1003                           1, 1, /* min */
1004                           -1, -1 /* max */
1005                           );
1006    _ibar_resize_handle(inst->ibar);
1007    _gc_orient(inst->gcc, -1);
1008 }
1009
1010 static void
1011 _ibar_inst_cb_enter(void *data, const char *type __UNUSED__, void *event_info)
1012 {
1013    E_Event_Dnd_Enter *ev;
1014    Instance *inst;
1015    Evas_Object *o, *o2;
1016
1017    ev = event_info;
1018    inst = data;
1019    o = edje_object_add(evas_object_evas_get(inst->ibar->o_box));
1020    inst->ibar->o_drop = o;
1021    o2 = edje_object_add(evas_object_evas_get(inst->ibar->o_box));
1022    inst->ibar->o_drop_over = o2;
1023    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, 
1024                                   _ibar_cb_drop_move, inst->ibar);
1025    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, 
1026                                   _ibar_cb_drop_resize, inst->ibar);
1027    e_theme_edje_object_set(o, "base/theme/modules/ibar",
1028                            "e/modules/ibar/drop");
1029    e_theme_edje_object_set(o2, "base/theme/modules/ibar",
1030                            "e/modules/ibar/drop_overlay");
1031    evas_object_layer_set(o2, 19999);
1032    evas_object_show(o);
1033    evas_object_show(o2);
1034
1035    _ibar_drop_position_update(inst, ev->x, ev->y);
1036    e_gadcon_client_autoscroll_cb_set(inst->gcc, _ibar_inst_cb_scroll, inst);
1037    e_gadcon_client_autoscroll_update(inst->gcc, ev->x, ev->y);
1038 }
1039
1040 static void
1041 _ibar_inst_cb_move(void *data, const char *type __UNUSED__, void *event_info)
1042 {
1043    E_Event_Dnd_Move *ev;
1044    Instance *inst;
1045
1046    ev = event_info;
1047    inst = data;
1048    _ibar_drop_position_update(inst, ev->x, ev->y);
1049    e_gadcon_client_autoscroll_update(inst->gcc, ev->x, ev->y);
1050 }
1051
1052 static void
1053 _ibar_inst_cb_leave(void *data, const char *type __UNUSED__, void *event_info __UNUSED__)
1054 {
1055    Instance *inst;
1056
1057    inst = data;
1058    inst->ibar->ic_drop_before = NULL;
1059    evas_object_del(inst->ibar->o_drop);
1060    inst->ibar->o_drop = NULL;
1061    evas_object_del(inst->ibar->o_drop_over);
1062    inst->ibar->o_drop_over = NULL;
1063    _ibar_resize_handle(inst->ibar);
1064    e_gadcon_client_autoscroll_cb_set(inst->gcc, NULL, NULL);
1065    _gc_orient(inst->gcc, -1);
1066 }
1067
1068 static void
1069 _ibar_inst_cb_drop(void *data, const char *type, void *event_info)
1070 {
1071    E_Event_Dnd_Drop *ev;
1072    Instance *inst;
1073    Efreet_Desktop *app = NULL;
1074    Eina_List *fl = NULL;
1075    IBar_Icon *ic;
1076
1077    ev = event_info;
1078    inst = data;
1079
1080    if (!strcmp(type, "enlightenment/desktop"))
1081      app = ev->data;
1082    else if (!strcmp(type, "enlightenment/border"))
1083      {
1084         E_Border *bd;
1085
1086         bd = ev->data;
1087         app = bd->desktop;
1088         if (!app)
1089           {
1090              app = e_desktop_border_create(bd);
1091              efreet_desktop_save(app);
1092              e_desktop_edit(e_container_current_get(e_manager_current_get()), 
1093                             app);
1094           }
1095      }
1096    else if (!strcmp(type, "text/uri-list"))
1097      fl = ev->data;
1098
1099    ic = inst->ibar->ic_drop_before;
1100    if (ic)
1101      {
1102         /* Add new eapp before this icon */
1103         if (!inst->ibar->drop_before)
1104           {
1105              const Eina_List *l;
1106              IBar_Icon *ic2;
1107
1108              EINA_LIST_FOREACH(inst->ibar->icons, l, ic2)
1109                {
1110                   if (ic2 == ic)
1111                     {
1112                        if (l->next)
1113                          ic = l->next->data;
1114                        else
1115                          ic = NULL;
1116                        break;
1117                     }
1118                }
1119           }
1120         if (!ic) goto atend;
1121         if (app)
1122           e_order_prepend_relative(ic->ibar->apps, app, ic->app);
1123         else if (fl)
1124           e_order_files_prepend_relative(ic->ibar->apps, fl, ic->app);
1125      }
1126    else
1127      {
1128         atend:
1129         if (inst->ibar->apps)
1130           {
1131              if (app)
1132                e_order_append(inst->ibar->apps, app);
1133              else if (fl)
1134                e_order_files_append(inst->ibar->apps, fl);
1135           }
1136      }
1137    evas_object_del(inst->ibar->o_drop);
1138    inst->ibar->o_drop = NULL;
1139    evas_object_del(inst->ibar->o_drop_over);
1140    inst->ibar->o_drop_over = NULL;
1141    e_gadcon_client_autoscroll_cb_set(inst->gcc, NULL, NULL);
1142    _ibar_empty_handle(inst->ibar);
1143    _ibar_resize_handle(inst->ibar);
1144    _gc_orient(inst->gcc, -1);
1145 }
1146
1147 /* module setup */
1148 EAPI E_Module_Api e_modapi =
1149 {
1150    E_MODULE_API_VERSION, "IBar"
1151 };
1152
1153 EAPI void *
1154 e_modapi_init(E_Module *m)
1155 {
1156    conf_item_edd = E_CONFIG_DD_NEW("IBar_Config_Item", Config_Item);
1157 #undef T
1158 #undef D
1159 #define T Config_Item
1160 #define D conf_item_edd
1161    E_CONFIG_VAL(D, T, id, STR);
1162    E_CONFIG_VAL(D, T, dir, STR);
1163    E_CONFIG_VAL(D, T, show_label, INT);
1164    E_CONFIG_VAL(D, T, eap_label, INT);
1165
1166    conf_edd = E_CONFIG_DD_NEW("IBar_Config", Config);
1167 #undef T
1168 #undef D
1169 #define T Config
1170 #define D conf_edd
1171    E_CONFIG_LIST(D, T, items, conf_item_edd);
1172
1173    ibar_config = e_config_domain_load("module.ibar", conf_edd);
1174
1175    if (!ibar_config)
1176      {
1177         Config_Item *ci;
1178
1179         ibar_config = E_NEW(Config, 1);
1180
1181         ci = E_NEW(Config_Item, 1);
1182         ci->id = eina_stringshare_add("ibar.1");
1183         ci->dir = eina_stringshare_add("default");
1184         ci->show_label = 1;
1185         ci->eap_label = 0;
1186         ibar_config->items = eina_list_append(ibar_config->items, ci);
1187      }
1188  
1189    ibar_config->module = m;
1190
1191    ibar_config->handlers = 
1192      eina_list_append(ibar_config->handlers,
1193                       ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, 
1194                                               _ibar_cb_config_icons, NULL));
1195    ibar_config->handlers = 
1196      eina_list_append(ibar_config->handlers,
1197                       ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE,
1198                                               _ibar_cb_config_icons, NULL));
1199
1200    e_gadcon_provider_register(&_gadcon_class);
1201    return m;
1202 }
1203
1204 EAPI int
1205 e_modapi_shutdown(E_Module *m __UNUSED__)
1206 {
1207    Ecore_Event_Handler *eh;
1208    Config_Item *ci;
1209
1210    e_gadcon_provider_unregister(&_gadcon_class);
1211
1212    if (ibar_config->config_dialog)
1213      e_object_del(E_OBJECT(ibar_config->config_dialog));
1214
1215    EINA_LIST_FREE(ibar_config->handlers, eh)
1216      ecore_event_handler_del(eh);
1217
1218    if (ibar_config->menu)
1219      {
1220         e_menu_post_deactivate_callback_set(ibar_config->menu, NULL, NULL);
1221         e_object_del(E_OBJECT(ibar_config->menu));
1222         ibar_config->menu = NULL;
1223      }
1224
1225    EINA_LIST_FREE(ibar_config->items, ci)
1226      {
1227         if (ci->id) eina_stringshare_del(ci->id);
1228         if (ci->dir) eina_stringshare_del(ci->dir);
1229         E_FREE(ci);
1230      }
1231    E_FREE(ibar_config);
1232    ibar_config = NULL;
1233    E_CONFIG_DD_FREE(conf_item_edd);
1234    E_CONFIG_DD_FREE(conf_edd);
1235    return 1;
1236 }
1237
1238 EAPI int
1239 e_modapi_save(E_Module *m __UNUSED__)
1240 {
1241    e_config_domain_save("module.ibar", conf_edd, ibar_config);
1242    return 1;
1243 }
1244
1245 static Eina_Bool
1246 _ibar_cb_config_icons(__UNUSED__ void *data, __UNUSED__ int ev_type, __UNUSED__ void *ev)
1247 {
1248    const Eina_List *l;
1249    Instance *inst;
1250
1251    EINA_LIST_FOREACH(ibar_config->instances, l, inst)
1252      {
1253         const Eina_List *l2;
1254         IBar_Icon *icon;
1255
1256         EINA_LIST_FOREACH(inst->ibar->icons, l2, icon)
1257           _ibar_icon_fill(icon);
1258      }
1259    return ECORE_CALLBACK_PASS_ON;
1260 }