chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / src / container.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2004-2009 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "E.h"
25 #include "container.h"
26 #include "dialog.h"
27 #include "e16-ecore_list.h"
28 #include "emodule.h"
29 #include "eobj.h"
30 #include "ewins.h"
31 #include "hints.h"
32 #include "iclass.h"
33 #include "menus.h"
34
35 extern const ContainerOps IconboxOps;
36 extern const ContainerOps SystrayOps;
37
38 static void         ContainersConfigSave(void);
39
40 static void         ContainerLayout(Container * ct, int *px, int *py, int *pw,
41                                     int *ph);
42 static void         ContainerDraw(Container * ct);
43
44 static void         ContainerEventScrollWin(Win win, XEvent * ev, void *prm);
45 static void         ContainerEventScrollbarWin(Win win, XEvent * ev, void *prm);
46 static void         ContainerEventCoverWin(Win win, XEvent * ev, void *prm);
47 static void         ContainerEventArrow1Win(Win win, XEvent * ev, void *prm);
48 static void         ContainerEventArrow2Win(Win win, XEvent * ev, void *prm);
49 static void         ContainerEventIconWin(Win win, XEvent * ev, void *prm);
50
51 ContainerCfg        Conf_containers;
52
53 static Ecore_List  *container_list = NULL;
54
55 static int
56 _ContainerMatchName(const void *data, const void *match)
57 {
58    return strcmp(((const Container *)data)->name, (const char *)match);
59 }
60
61 static Container   *
62 ContainerFind(const char *name)
63 {
64    return (Container *) ecore_list_find(container_list, _ContainerMatchName,
65                                         name);
66 }
67
68 static Container   *
69 ContainerCreate(const char *name)
70 {
71    Container          *ct;
72
73    if (ContainerFind(name))
74       return NULL;
75
76    ct = ECALLOC(Container, 1);
77    if (!ct)
78       return NULL;
79
80    if (!container_list)
81       container_list = ecore_list_new();
82    ecore_list_append(container_list, ct);
83
84    ct->name = Estrdup(name);
85    ct->type = (name && !strcmp(name, "_ST_")) ?
86       IB_TYPE_SYSTRAY : IB_TYPE_ICONBOX;
87    ct->orientation = 0;
88    ct->scrollbar_side = 1;
89    ct->arrow_side = 1;
90    ct->nobg = 0;
91    ct->shownames = 1;
92    ct->iconsize = 48;
93    ct->icon_mode = 2;
94    ct->auto_resize = 0;
95    ct->draw_icon_base = 0;
96    ct->scrollbar_hide = 0;
97    ct->cover_hide = 0;
98    ct->auto_resize_anchor = 0;
99    /* FIXME: need to have theme settable params for this and get them */
100    ct->scroll_thickness = 12;
101    ct->arrow_thickness = 12;
102    ct->bar_thickness = 8;
103    ct->knob_length = 8;
104
105    ct->w = 0;
106    ct->h = 0;
107    ct->pos = 0;
108    ct->max = 1;
109    ct->arrow1_hilited = 0;
110    ct->arrow1_clicked = 0;
111    ct->arrow2_hilited = 0;
112    ct->arrow2_clicked = 0;
113    ct->icon_clicked = 0;
114    ct->scrollbar_hilited = 0;
115    ct->scrollbar_clicked = 0;
116    ct->scrollbox_clicked = 0;
117
118    ct->win = ECreateClientWindow(VROOT, 0, 0, 1, 1);
119    ct->icon_win = ECreateWindow(ct->win, 0, 0, 128, 26, 0);
120    EventCallbackRegister(ct->icon_win, 0, ContainerEventIconWin, ct);
121    ct->cover_win = ECreateWindow(ct->win, 0, 0, 128, 26, 0);
122    EventCallbackRegister(ct->cover_win, 0, ContainerEventCoverWin, ct);
123    ct->scroll_win = ECreateWindow(ct->win, 6, 26, 116, 6, 0);
124    EventCallbackRegister(ct->scroll_win, 0, ContainerEventScrollWin, ct);
125    ct->arrow1_win = ECreateWindow(ct->win, 0, 26, 6, 6, 0);
126    EventCallbackRegister(ct->arrow1_win, 0, ContainerEventArrow1Win, ct);
127    ct->arrow2_win = ECreateWindow(ct->win, 122, 26, 6, 6, 0);
128    EventCallbackRegister(ct->arrow2_win, 0, ContainerEventArrow2Win, ct);
129    ct->scrollbar_win = ECreateWindow(ct->scroll_win, 122, 26, 6, 6, 0);
130    EventCallbackRegister(ct->scrollbar_win, 0, ContainerEventScrollbarWin, ct);
131    ct->scrollbarknob_win = ECreateWindow(ct->scrollbar_win, -20, -20, 4, 4, 0);
132
133    ESelectInput(ct->icon_win,
134                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
135                 ButtonReleaseMask | PointerMotionMask);
136    ESelectInput(ct->scroll_win,
137                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
138                 ButtonReleaseMask);
139    ESelectInput(ct->cover_win,
140                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
141                 ButtonReleaseMask);
142    ESelectInput(ct->arrow1_win,
143                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
144                 ButtonReleaseMask);
145    ESelectInput(ct->arrow2_win,
146                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
147                 ButtonReleaseMask);
148    ESelectInput(ct->scrollbar_win,
149                 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
150                 ButtonReleaseMask | PointerMotionMask);
151
152    EMapWindow(ct->icon_win);
153    EMapWindow(ct->scrollbar_win);
154
155    ct->ewin = NULL;
156    ct->num_objs = 0;
157    ct->objs = NULL;
158
159    if (ct->type == IB_TYPE_ICONBOX)
160       ct->ops = &IconboxOps;
161    else if (ct->type == IB_TYPE_SYSTRAY)
162       ct->ops = &SystrayOps;
163
164    ct->ops->Init(ct);
165
166    return ct;
167 }
168
169 static void
170 ContainerDestroy(Container * ct, int exiting)
171 {
172    ecore_list_node_remove(container_list, ct);
173
174    ct->ops->Exit(ct, exiting);
175
176    Efree(ct->name);
177    Efree(ct->objs);
178
179    Efree(ct);
180
181    if (!exiting)
182       ContainersConfigSave();
183 }
184
185 static void
186 ContainerReconfigure(Container * ct)
187 {
188    ImageClass         *ic, *ic2;
189    EImageBorder       *pad;
190    EWin               *ewin;
191    int                 extra;
192    unsigned int        wmin, hmin, wmax, hmax;
193
194    ewin = ct->ewin;
195
196    wmin = hmin = 8;
197    wmax = hmax = 16384;
198
199    extra = 0;
200    if (ct->orientation)
201      {
202         ic = ImageclassFind("ICONBOX_VERTICAL", 0);
203         pad = ImageclassGetPadding(ic);
204         if (ic)
205            extra = pad->left + pad->right;
206         if (ct->draw_icon_base)
207           {
208              ic2 = ImageclassFind("DEFAULT_ICON_BUTTON", 0);
209              pad = ImageclassGetPadding(ic2);
210              if (ic2)
211                 extra += pad->left + pad->right;
212           }
213         wmax = wmin = ct->iconsize + ct->scroll_thickness + extra;
214         ct->max_min = hmin;
215      }
216    else
217      {
218         ic = ImageclassFind("ICONBOX_HORIZONTAL", 0);
219         pad = ImageclassGetPadding(ic);
220         if (ic)
221            extra = pad->top + pad->bottom;
222         if (ct->draw_icon_base)
223           {
224              ic2 = ImageclassFind("DEFAULT_ICON_BUTTON", 0);
225              pad = ImageclassGetPadding(ic2);
226              if (ic2)
227                 extra += pad->top + pad->bottom;
228           }
229         hmax = hmin = ct->iconsize + ct->scroll_thickness + extra;
230         ct->max_min = wmin;
231      }
232
233    ICCCM_SetSizeConstraints(ewin, wmin, hmin, wmax, hmax, 0, 0, 1, 1,
234                             0.0, 65535.0);
235 }
236
237 static void
238 _ContainerEwinInit(EWin * ewin)
239 {
240    Container          *ct = (Container *) ewin->data;
241
242    EwinSetTitle(ewin, ct->wm_name);
243    EwinSetClass(ewin, ct->name, "Enlightenment_IconBox");
244
245    ewin->props.skip_ext_task = 1;
246    ewin->props.skip_ext_pager = 1;
247    ewin->props.skip_focuslist = 1;
248    ewin->props.skip_winlist = 1;
249    EwinInhSetWM(ewin, focus, 1);
250    EwinInhSetWM(ewin, iconify, 1);
251    ewin->props.autosave = 1;
252
253    EoSetSticky(ewin, 1);
254 }
255
256 static void
257 _ContainerEwinLayout(EWin * ewin, int *px, int *py, int *pw, int *ph)
258 {
259    Container          *ct = (Container *) ewin->data;
260
261    ContainerLayout(ct, px, py, pw, ph);
262
263    if (*pw != ct->w || *ph != ct->h)
264       ct->do_update = 1;
265 }
266
267 static void
268 _ContainerEwinMoveResize(EWin * ewin, int resize)
269 {
270    Container          *ct = (Container *) ewin->data;
271
272    if (!resize && !ct->do_update && !TransparencyUpdateNeeded())
273       return;
274
275    ct->w = ewin->client.w;
276    ct->h = ewin->client.h;
277
278    ContainerDraw(ct);
279    ct->do_update = 0;
280 }
281
282 static void
283 _ContainerEwinClose(EWin * ewin)
284 {
285    ContainerDestroy((Container *) ewin->data, 0);
286    ewin->data = NULL;
287 }
288
289 static const EWinOps _ContainerEwinOps = {
290    _ContainerEwinInit,
291    _ContainerEwinLayout,
292    _ContainerEwinMoveResize,
293    _ContainerEwinClose,
294 };
295
296 static void
297 ContainerShow(Container * ct)
298 {
299    EWin               *ewin;
300
301    if (!ct)
302       return;
303
304    ewin = AddInternalToFamily(ct->win, "ICONBOX", EWIN_TYPE_ICONBOX,
305                               &_ContainerEwinOps, ct);
306    ct->ewin = ewin;
307    if (!ewin)
308       return;
309
310    ContainerReconfigure(ct);
311
312    if (ewin->state.placed)
313      {
314         EwinMoveToDesktop(ewin, EoGetDesk(ewin));
315         EwinMoveResize(ewin, EoGetX(ewin), EoGetY(ewin), ewin->client.w,
316                        ewin->client.h);
317      }
318    else
319      {
320         /* The first one */
321         EwinMoveToDesktop(ewin, EoGetDesk(ewin));
322         EwinResize(ewin, 128, 32);
323         EwinMove(ewin, WinGetW(VROOT) - EoGetW(ewin),
324                  WinGetH(VROOT) - EoGetH(ewin));
325      }
326
327    EwinShow(ewin);
328 }
329
330 /*
331  * Return index, -1 if not found.
332  */
333 int
334 ContainerObjectFind(Container * ct, void *obj)
335 {
336    int                 i;
337
338    for (i = 0; i < ct->num_objs; i++)
339       if (ct->objs[i].obj == obj)
340          return i;
341
342    return -1;
343 }
344
345 int
346 ContainerObjectAdd(Container * ct, void *obj)
347 {
348    /* Not if already there */
349    if (ContainerObjectFind(ct, obj) >= 0)
350       return -1;
351
352    ct->num_objs++;
353    ct->objs = EREALLOC(ContainerObject, ct->objs, ct->num_objs);
354    ct->objs[ct->num_objs - 1].obj = obj;
355
356    return ct->num_objs - 1;     /* Success */
357 }
358
359 int
360 ContainerObjectDel(Container * ct, void *obj)
361 {
362    int                 i, j;
363
364    /* Quit if not there */
365    i = ContainerObjectFind(ct, obj);
366    if (i < 0)
367       return -1;
368
369    for (j = i; j < ct->num_objs - 1; j++)
370       ct->objs[j] = ct->objs[j + 1];
371    ct->num_objs--;
372    if (ct->num_objs > 0)
373       ct->objs = EREALLOC(ContainerObject, ct->objs, ct->num_objs);
374    else
375      {
376         Efree(ct->objs);
377         ct->objs = NULL;
378      }
379
380    return 0;                    /* Success */
381 }
382
383 void               *
384 ContainerObjectFindByXY(Container * ct, int px, int py)
385 {
386    int                 i;
387    ContainerObject    *cto;
388
389    for (i = 0; i < ct->num_objs; i++)
390      {
391         cto = &ct->objs[i];
392
393         if (px >= cto->xo - 1 && py >= cto->yo - 1 &&
394             px < cto->xo + cto->wo + 1 && py < cto->yo + cto->ho + 1)
395            return cto->obj;
396      }
397
398    return NULL;
399 }
400
401 static void
402 ContainerLayoutImageWin(Container * ct)
403 {
404    int                 i, xo, yo;
405    int                 item_pad, padl, padr, padt, padb;
406    ContainerObject    *cto;
407    EImageBorder       *pad, *pad_base;
408
409    if (ct->orientation)
410       ct->ic_box = ImageclassFind("ICONBOX_VERTICAL", 0);
411    else
412       ct->ic_box = ImageclassFind("ICONBOX_HORIZONTAL", 0);
413
414    if (ct->draw_icon_base && !ct->im_item_base)
415      {
416         ct->ic_item_base = ImageclassFind("DEFAULT_ICON_BUTTON", 0);
417         if (ct->ic_item_base)
418            ct->im_item_base =
419               ImageclassGetImage(ct->ic_item_base, 0, 0, STATE_NORMAL);
420         if (!ct->im_item_base)
421           {
422              ct->ic_item_base = NULL;
423              ct->draw_icon_base = 0;
424           }
425      }
426
427    if (ct->draw_icon_base)
428      {
429         pad_base = ImageclassGetPadding(ct->ic_item_base);
430         padl = pad_base->left;
431         padr = pad_base->right;
432         padt = pad_base->top;
433         padb = pad_base->bottom;
434
435         item_pad = 0;
436      }
437    else
438      {
439         pad_base = NULL;
440         padl = padr = padt = padb = 0;
441
442         item_pad = 2;
443      }
444
445    xo = 0;
446    yo = 0;
447    if (ct->ic_box)
448      {
449         pad = ImageclassGetPadding(ct->ic_box);
450         xo += pad->left;
451         yo += pad->top;
452      }
453
454    for (i = 0; i < ct->num_objs; i++)
455      {
456         cto = &ct->objs[i];
457
458         /* Inner size */
459         ct->ops->ObjSizeCalc(ct, cto);
460
461         /* Outer size */
462         if (ct->draw_icon_base && ct->im_item_base)
463           {
464              if (cto->wi > 0 && cto->hi > 0)
465                {
466                   cto->wo = ct->iconsize + padl + padr;
467                   cto->ho = ct->iconsize + padt + padb;
468                }
469              else
470                {
471                   cto->wo = cto->ho = 0;
472                }
473           }
474         else
475           {
476              if (cto->wi > 0 && cto->hi > 0)
477                {
478                   if (ct->orientation)
479                     {
480                        cto->wo = ct->iconsize;
481                        cto->ho = cto->hi;
482                     }
483                   else
484                     {
485                        cto->wo = cto->wi;
486                        cto->ho = ct->iconsize;
487                     }
488                }
489              else
490                {
491                   cto->wo = cto->ho = 0;
492                }
493           }
494
495         cto->xo = xo;
496         cto->yo = yo;
497         cto->xi = xo + (cto->wo - cto->wi) / 2;
498         cto->yi = yo + (cto->ho - cto->hi) / 2;
499 #if 0
500         Eprintf("xo,yo=%d,%d wo,ho=%d,%d  xi,yi=%d,%d wi,hi=%d,%d\n",
501                 cto->xo, cto->yo, cto->wo, cto->ho, cto->xi, cto->yi, cto->wi,
502                 cto->hi);
503 #endif
504
505         if (ct->orientation)
506            yo += cto->ho + item_pad;
507         else
508            xo += cto->wo + item_pad;
509      }
510
511    if (ct->ic_box)
512      {
513         pad = ImageclassGetPadding(ct->ic_box);
514         xo += pad->right;
515         yo += pad->bottom;
516      }
517
518    if (ct->orientation)
519       ct->max = yo - item_pad;
520    else
521       ct->max = xo - item_pad;
522
523    if (ct->max < ct->max_min)
524       ct->max = ct->max_min;
525 }
526
527 static void
528 ContainerDrawScroll(Container * ct)
529 {
530    ImageClass         *ic, *ic_sbb;
531    EImageBorder       *pad;
532    int                 arrow_mode = ct->arrow_side;
533    int                 bs, bw, bx;
534    int                 state;
535
536    switch (ct->orientation)
537      {
538      default:
539         if (ct->h < 2 * ct->arrow_thickness + ct->knob_length)
540            arrow_mode = 3;      /* No arrows */
541
542         ic_sbb = ImageclassFind("ICONBOX_SCROLLBAR_BASE_VERTICAL", 1);
543         pad = ImageclassGetPadding(ic_sbb);
544         if (arrow_mode < 3)
545            bs = ct->h - (ct->arrow_thickness * 2);
546         else
547            bs = ct->h;
548         if (pad)
549            bs -= pad->top + pad->bottom;
550         bw = (ct->h * bs) / ct->max;
551         if (bs < 1)
552            bs = 1;
553         if (bw > bs)
554            bw = bs;
555         if (bw < 1)
556            bw = 1;
557         bx = ((ct->pos * bs) / ct->max);
558         if (pad)
559            bx += pad->top;
560         if ((ct->scrollbar_hide) && (bw == bs))
561            goto do_hide_sb;
562
563         EMapWindow(ct->scroll_win);
564         if (arrow_mode < 3)
565           {
566              EMapWindow(ct->arrow1_win);
567              EMapWindow(ct->arrow2_win);
568           }
569         else
570           {
571              EUnmapWindow(ct->arrow1_win);
572              EUnmapWindow(ct->arrow2_win);
573           }
574
575         /* fix this area */
576         if (ct->scrollbar_side == 1)
577            /* right */
578           {
579              /* start */
580              if (arrow_mode == 0)
581                {
582                   EMoveResizeWindow(ct->arrow1_win,
583                                     ct->w - ct->scroll_thickness, 0,
584                                     ct->scroll_thickness, ct->arrow_thickness);
585                   EMoveResizeWindow(ct->arrow2_win,
586                                     ct->w - ct->scroll_thickness,
587                                     ct->arrow_thickness,
588                                     ct->scroll_thickness, ct->arrow_thickness);
589                   EMoveResizeWindow(ct->scroll_win,
590                                     ct->w - ct->scroll_thickness,
591                                     ct->arrow_thickness * 2,
592                                     ct->scroll_thickness,
593                                     ct->h - (ct->arrow_thickness * 2));
594                }
595              /* both ends */
596              else if (arrow_mode == 1)
597                {
598                   EMoveResizeWindow(ct->arrow1_win,
599                                     ct->w - ct->scroll_thickness, 0,
600                                     ct->scroll_thickness, ct->arrow_thickness);
601                   EMoveResizeWindow(ct->arrow2_win,
602                                     ct->w - ct->scroll_thickness,
603                                     ct->h - ct->arrow_thickness,
604                                     ct->scroll_thickness, ct->arrow_thickness);
605                   EMoveResizeWindow(ct->scroll_win,
606                                     ct->w - ct->scroll_thickness,
607                                     ct->arrow_thickness,
608                                     ct->scroll_thickness,
609                                     ct->h - (ct->arrow_thickness * 2));
610                }
611              /* end */
612              else if (arrow_mode == 2)
613                {
614                   EMoveResizeWindow(ct->arrow1_win,
615                                     ct->w - ct->scroll_thickness,
616                                     ct->h - (ct->arrow_thickness * 2),
617                                     ct->scroll_thickness, ct->arrow_thickness);
618                   EMoveResizeWindow(ct->arrow2_win,
619                                     ct->w - ct->scroll_thickness,
620                                     ct->h - ct->arrow_thickness,
621                                     ct->scroll_thickness, ct->arrow_thickness);
622                   EMoveResizeWindow(ct->scroll_win,
623                                     ct->w - ct->scroll_thickness, 0,
624                                     ct->scroll_thickness,
625                                     ct->h - (ct->arrow_thickness * 2));
626                }
627              /* no arrows */
628              else
629                {
630                   EMoveResizeWindow(ct->scroll_win,
631                                     ct->w - ct->scroll_thickness, 0,
632                                     ct->scroll_thickness, ct->h);
633                }
634           }
635         else
636            /* left */
637           {
638              /* start */
639              if (arrow_mode == 0)
640                {
641                   EMoveResizeWindow(ct->arrow1_win, 0, 0,
642                                     ct->scroll_thickness, ct->arrow_thickness);
643                   EMoveResizeWindow(ct->arrow2_win, 0,
644                                     ct->arrow_thickness,
645                                     ct->scroll_thickness, ct->arrow_thickness);
646                   EMoveResizeWindow(ct->scroll_win, 0,
647                                     ct->arrow_thickness * 2,
648                                     ct->scroll_thickness,
649                                     ct->h - (ct->arrow_thickness * 2));
650                }
651              /* both ends */
652              else if (arrow_mode == 1)
653                {
654                   EMoveResizeWindow(ct->arrow1_win, 0, 0,
655                                     ct->scroll_thickness, ct->arrow_thickness);
656                   EMoveResizeWindow(ct->arrow2_win, 0,
657                                     ct->h - ct->arrow_thickness,
658                                     ct->scroll_thickness, ct->arrow_thickness);
659                   EMoveResizeWindow(ct->scroll_win, 0,
660                                     ct->arrow_thickness,
661                                     ct->scroll_thickness,
662                                     ct->h - (ct->arrow_thickness * 2));
663                }
664              /* end */
665              else if (arrow_mode == 2)
666                {
667                   EMoveResizeWindow(ct->arrow1_win, 0,
668                                     ct->h - (ct->arrow_thickness * 2),
669                                     ct->scroll_thickness, ct->arrow_thickness);
670                   EMoveResizeWindow(ct->arrow2_win, 0,
671                                     ct->h - ct->arrow_thickness,
672                                     ct->scroll_thickness, ct->arrow_thickness);
673                   EMoveResizeWindow(ct->scroll_win, 0, 0,
674                                     ct->scroll_thickness,
675                                     ct->h - (ct->arrow_thickness * 2));
676                }
677              /* no arrows */
678              else
679                {
680                   EMoveResizeWindow(ct->scroll_win, 0, 0,
681                                     ct->scroll_thickness, ct->h);
682                }
683           }
684
685         ImageclassApply(ic_sbb, ct->scroll_win, 0, 0, STATE_NORMAL, ST_ICONBOX);
686
687         EMoveResizeWindow(ct->scrollbar_win,
688                           (ct->scroll_thickness - ct->bar_thickness) / 2, bx,
689                           ct->bar_thickness, bw);
690
691         ic = ImageclassFind("ICONBOX_SCROLLBAR_KNOB_VERTICAL", 1);
692         if (ic)
693           {
694              state = STATE_NORMAL;
695              if (ct->scrollbar_hilited)
696                 state = STATE_HILITED;
697              if (ct->scrollbar_clicked)
698                 state = STATE_CLICKED;
699              ImageclassApply(ic, ct->scrollbar_win, 0, 0, state, ST_ICONBOX);
700           }
701
702         ic = ImageclassFind("ICONBOX_SCROLLKNOB_VERTICAL", 0);
703         if ((ic) && (bw > ct->knob_length))
704           {
705              EMapWindow(ct->scrollbarknob_win);
706              EMoveResizeWindow(ct->scrollbarknob_win, 0,
707                                (bw - ct->knob_length) / 2, ct->bar_thickness,
708                                ct->knob_length);
709
710              state = STATE_NORMAL;
711              if (ct->scrollbar_hilited)
712                 state = STATE_HILITED;
713              if (ct->scrollbar_clicked)
714                 state = STATE_CLICKED;
715              ImageclassApply(ic, ct->scrollbarknob_win, 0, 0, state,
716                              ST_ICONBOX);
717           }
718         else
719           {
720              EUnmapWindow(ct->scrollbarknob_win);
721           }
722
723         if (arrow_mode < 3)
724           {
725              ic = ImageclassFind("ICONBOX_ARROW_UP", 1);
726              if (ic)
727                {
728                   state = STATE_NORMAL;
729                   if (ct->arrow1_hilited)
730                      state = STATE_HILITED;
731                   if (ct->arrow1_clicked)
732                      state = STATE_CLICKED;
733                   ImageclassApply(ic, ct->arrow1_win, 0, 0, state, ST_ICONBOX);
734                }
735
736              ic = ImageclassFind("ICONBOX_ARROW_DOWN", 1);
737              if (ic)
738                {
739                   state = STATE_NORMAL;
740                   if (ct->arrow2_hilited)
741                      state = STATE_HILITED;
742                   if (ct->arrow2_clicked)
743                      state = STATE_CLICKED;
744                   ImageclassApply(ic, ct->arrow2_win, 0, 0, state, ST_ICONBOX);
745                }
746           }
747         break;
748
749      case 0:
750         if (ct->w < 2 * ct->arrow_thickness + ct->knob_length)
751            arrow_mode = 3;      /* No arrows */
752
753         ic_sbb = ImageclassFind("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 1);
754         pad = ImageclassGetPadding(ic_sbb);
755         if (arrow_mode < 3)
756            bs = ct->w - (ct->arrow_thickness * 2);
757         else
758            bs = ct->w;
759         if (pad)
760            bs -= pad->left + pad->right;
761         bw = (ct->w * bs) / ct->max;
762         if (bs < 1)
763            bs = 1;
764         if (bw > bs)
765            bw = bs;
766         if (bw < 1)
767            bw = 1;
768         bx = ((ct->pos * bs) / ct->max);
769         if (pad)
770            bx += pad->left;
771         if ((ct->scrollbar_hide) && (bw == bs))
772            goto do_hide_sb;
773
774         EMapWindow(ct->scroll_win);
775         if (arrow_mode < 3)
776           {
777              EMapWindow(ct->arrow1_win);
778              EMapWindow(ct->arrow2_win);
779           }
780         else
781           {
782              EUnmapWindow(ct->arrow1_win);
783              EUnmapWindow(ct->arrow2_win);
784           }
785
786         if (ct->scrollbar_side == 1)
787            /* bottom */
788           {
789              /* start */
790              if (arrow_mode == 0)
791                {
792                   EMoveResizeWindow(ct->arrow1_win, 0,
793                                     ct->h - ct->scroll_thickness,
794                                     ct->arrow_thickness, ct->scroll_thickness);
795                   EMoveResizeWindow(ct->arrow2_win,
796                                     ct->arrow_thickness,
797                                     ct->h - ct->scroll_thickness,
798                                     ct->arrow_thickness, ct->scroll_thickness);
799                   EMoveResizeWindow(ct->scroll_win,
800                                     ct->arrow_thickness * 2,
801                                     ct->h - ct->scroll_thickness,
802                                     ct->w - (ct->arrow_thickness * 2),
803                                     ct->scroll_thickness);
804                }
805              /* both ends */
806              else if (arrow_mode == 1)
807                {
808                   EMoveResizeWindow(ct->arrow1_win, 0,
809                                     ct->h - ct->scroll_thickness,
810                                     ct->arrow_thickness, ct->scroll_thickness);
811                   EMoveResizeWindow(ct->arrow2_win,
812                                     ct->w - ct->arrow_thickness,
813                                     ct->h - ct->scroll_thickness,
814                                     ct->arrow_thickness, ct->scroll_thickness);
815                   EMoveResizeWindow(ct->scroll_win,
816                                     ct->arrow_thickness,
817                                     ct->h - ct->scroll_thickness,
818                                     ct->w - (ct->arrow_thickness * 2),
819                                     ct->scroll_thickness);
820                }
821              /* end */
822              else if (arrow_mode == 2)
823                {
824                   EMoveResizeWindow(ct->arrow1_win,
825                                     ct->w - (ct->arrow_thickness * 2),
826                                     ct->h - ct->scroll_thickness,
827                                     ct->arrow_thickness, ct->scroll_thickness);
828                   EMoveResizeWindow(ct->arrow2_win,
829                                     ct->w - ct->arrow_thickness,
830                                     ct->h - ct->scroll_thickness,
831                                     ct->arrow_thickness, ct->scroll_thickness);
832                   EMoveResizeWindow(ct->scroll_win, 0,
833                                     ct->h - ct->scroll_thickness,
834                                     ct->w - (ct->arrow_thickness * 2),
835                                     ct->scroll_thickness);
836                }
837              /* no arrows */
838              else
839                {
840                   EMoveResizeWindow(ct->scroll_win, 0,
841                                     ct->h - ct->scroll_thickness, ct->w,
842                                     ct->scroll_thickness);
843                }
844           }
845         else
846            /* top */
847           {
848              /* start */
849              if (arrow_mode == 0)
850                {
851                   EMoveResizeWindow(ct->arrow1_win, 0, 0,
852                                     ct->arrow_thickness, ct->scroll_thickness);
853                   EMoveResizeWindow(ct->arrow2_win,
854                                     ct->arrow_thickness, 0,
855                                     ct->arrow_thickness, ct->scroll_thickness);
856                   EMoveResizeWindow(ct->scroll_win,
857                                     ct->arrow_thickness * 2, 0,
858                                     ct->w - (ct->arrow_thickness * 2),
859                                     ct->scroll_thickness);
860                }
861              /* both ends */
862              else if (arrow_mode == 1)
863                {
864                   EMoveResizeWindow(ct->arrow1_win, 0, 0,
865                                     ct->arrow_thickness, ct->scroll_thickness);
866                   EMoveResizeWindow(ct->arrow2_win,
867                                     ct->w - ct->arrow_thickness, 0,
868                                     ct->arrow_thickness, ct->scroll_thickness);
869                   EMoveResizeWindow(ct->scroll_win,
870                                     ct->arrow_thickness, 0,
871                                     ct->w - (ct->arrow_thickness * 2),
872                                     ct->scroll_thickness);
873                }
874              /* end */
875              else if (arrow_mode == 2)
876                {
877                   EMoveResizeWindow(ct->arrow1_win,
878                                     ct->w - (ct->arrow_thickness * 2), 0,
879                                     ct->arrow_thickness, ct->scroll_thickness);
880                   EMoveResizeWindow(ct->arrow2_win,
881                                     ct->w - ct->arrow_thickness, 0,
882                                     ct->arrow_thickness, ct->scroll_thickness);
883                   EMoveResizeWindow(ct->scroll_win, 0, 0,
884                                     ct->w - (ct->arrow_thickness * 2),
885                                     ct->scroll_thickness);
886                }
887              /* no arrows */
888              else
889                {
890                   EMoveResizeWindow(ct->scroll_win, 0, 0, ct->w,
891                                     ct->scroll_thickness);
892                }
893           }
894
895         EMoveResizeWindow(ct->scrollbar_win, bx,
896                           (ct->scroll_thickness - ct->bar_thickness) / 2, bw,
897                           ct->bar_thickness);
898
899         ImageclassApply(ic_sbb, ct->scroll_win, 0, 0, STATE_NORMAL, ST_ICONBOX);
900
901         ic = ImageclassFind("ICONBOX_SCROLLBAR_KNOB_HORIZONTAL", 1);
902         if (ic)
903           {
904              state = STATE_NORMAL;
905              if (ct->scrollbar_hilited)
906                 state = STATE_HILITED;
907              if (ct->scrollbar_clicked)
908                 state = STATE_CLICKED;
909              ImageclassApply(ic, ct->scrollbar_win, 0, 0, state, ST_ICONBOX);
910           }
911
912         ic = ImageclassFind("ICONBOX_SCROLLKNOB_HORIZONTAL", 0);
913         if ((ic) && (bw > ct->knob_length))
914           {
915              EMapWindow(ct->scrollbarknob_win);
916              EMoveResizeWindow(ct->scrollbarknob_win,
917                                (bw - ct->knob_length) / 2, 0, ct->knob_length,
918                                ct->bar_thickness);
919
920              state = STATE_NORMAL;
921              if (ct->scrollbar_hilited)
922                 state = STATE_HILITED;
923              if (ct->scrollbar_clicked)
924                 state = STATE_CLICKED;
925              ImageclassApply(ic, ct->scrollbarknob_win, 0, 0, state,
926                              ST_ICONBOX);
927           }
928         else
929           {
930              EUnmapWindow(ct->scrollbarknob_win);
931           }
932
933         if (arrow_mode < 3)
934           {
935              ic = ImageclassFind("ICONBOX_ARROW_LEFT", 1);
936              if (ic)
937                {
938                   state = STATE_NORMAL;
939                   if (ct->arrow1_hilited)
940                      state = STATE_HILITED;
941                   if (ct->arrow1_clicked)
942                      state = STATE_CLICKED;
943                   ImageclassApply(ic, ct->arrow1_win, 0, 0, state, ST_ICONBOX);
944                }
945
946              ic = ImageclassFind("ICONBOX_ARROW_RIGHT", 1);
947              if (ic)
948                {
949                   state = STATE_NORMAL;
950                   if (ct->arrow2_hilited)
951                      state = STATE_HILITED;
952                   if (ct->arrow2_clicked)
953                      state = STATE_CLICKED;
954                   ImageclassApply(ic, ct->arrow2_win, 0, 0, state, ST_ICONBOX);
955                }
956           }
957         break;
958
959       do_hide_sb:
960         EUnmapWindow(ct->scroll_win);
961         EUnmapWindow(ct->arrow1_win);
962         EUnmapWindow(ct->arrow2_win);
963         break;
964      }
965 }
966
967 static void
968 ContainerFixPos(Container * ct)
969 {
970    int                 v;
971
972    if (ct->orientation)
973       v = ct->max - ct->h;
974    else
975       v = ct->max - ct->w;
976
977    if (ct->pos > v)
978       ct->pos = v;
979    if (ct->pos < 0)
980       ct->pos = 0;
981 }
982
983 static void
984 ContainerLayout(Container * ct, int *px, int *py, int *pw, int *ph)
985 {
986    int                 x, y, w, h;
987    EWin               *ewin = ct->ewin;
988
989    x = *px;
990    y = *py;
991    w = *pw;
992    h = *ph;
993    ICCCM_SizeMatch(ewin, w, h, &w, &h);
994
995    ContainerLayoutImageWin(ct);
996
997    if (ct->auto_resize)
998      {
999         int                 add = 0;
1000         int                 bl, br, bt, bb;
1001
1002         EwinBorderGetSize(ct->ewin, &bl, &br, &bt, &bb);
1003
1004         if (ct->orientation)
1005           {
1006              add = ct->max;
1007              if (ct->ewin->border)
1008                {
1009                   if ((bt + bb + add) > WinGetH(VROOT))
1010                      add = WinGetH(VROOT) - (bt + bb);
1011                }
1012              y += (((ct->ewin->client.h - add) * ct->auto_resize_anchor) >> 10);
1013              h = add;
1014              if (ct->ewin->border)
1015                {
1016                   if ((EoGetY(ct->ewin) + bt + bb + add) > WinGetH(VROOT))
1017                      y = WinGetH(VROOT) - (bt + bb + add);
1018                }
1019           }
1020         else
1021           {
1022              add = ct->max;
1023              if (ct->ewin->border)
1024                {
1025                   if ((bl + br + add) > WinGetW(VROOT))
1026                      add = WinGetW(VROOT) - (bl + br);
1027                }
1028              x += (((ct->ewin->client.w - add) * ct->auto_resize_anchor) >> 10);
1029              w = add;
1030              if (ct->ewin->border)
1031                {
1032                   if ((EoGetX(ct->ewin) + bl + br + add) > WinGetW(VROOT))
1033                      x = WinGetW(VROOT) - (bl + br + add);
1034                }
1035           }
1036      }
1037
1038    ContainerFixPos(ct);
1039
1040    *px = x;
1041    *py = y;
1042    *pw = w;
1043    *ph = h;
1044 }
1045
1046 static void
1047 ContainerDraw(Container * ct)
1048 {
1049    int                 i, w, h;
1050    ImageClass         *ib_ic_cover;
1051    int                 ib_xlt, ib_ylt, ib_ww, ib_hh;
1052    int                 ib_x0, ib_y0, ib_w0, ib_h0;
1053    EImage             *im;
1054    int                 ww, hh;
1055
1056    if (!ct->ic_box)
1057       ContainerLayoutImageWin(ct);
1058
1059    w = ct->w;
1060    h = ct->h;
1061
1062    ContainerDrawScroll(ct);
1063
1064    /* Geometry of iconbox window, excluding scrollbar */
1065    ib_xlt = 0;
1066    ib_ylt = 0;
1067    ib_ww = w;
1068    ib_hh = h;
1069    if (ct->orientation)
1070      {
1071         ib_ic_cover = ImageclassFind("ICONBOX_COVER_VERTICAL", 0);
1072         if (ct->scrollbar_side == 0)
1073            ib_xlt = ct->scroll_thickness;
1074         ib_ww -= ct->scroll_thickness;
1075
1076         /* Geometry of icon window (including invisible parts) */
1077         ib_x0 = ib_xlt;
1078         ib_y0 = ib_ylt - ct->pos;
1079         ib_w0 = ib_ww;
1080         ib_h0 = ib_hh;
1081         if (ib_h0 < ct->max)
1082            ib_h0 = ct->max;
1083      }
1084    else
1085      {
1086         ib_ic_cover = ImageclassFind("ICONBOX_COVER_HORIZONTAL", 0);
1087         if (ct->scrollbar_side == 0)
1088            ib_ylt = ct->scroll_thickness;
1089         ib_hh -= ct->scroll_thickness;
1090
1091         /* Geometry of icon window (including invisible parts) */
1092         ib_x0 = ib_xlt - ct->pos;
1093         ib_y0 = ib_ylt;
1094         ib_w0 = ib_ww;
1095         if (ib_w0 < ct->max)
1096            ib_w0 = ct->max;
1097         ib_h0 = ib_hh;
1098      }
1099
1100    EMoveResizeWindow(ct->icon_win, ib_x0, ib_y0, ib_w0, ib_h0);
1101
1102    if (ib_ic_cover && !ct->cover_hide)
1103      {
1104         EMoveResizeWindow(ct->cover_win, ib_xlt, ib_ylt, ib_ww, ib_hh);
1105         EMapWindow(ct->cover_win);
1106         ImageclassApply(ib_ic_cover, ct->cover_win, 0, 0, STATE_NORMAL,
1107                         ST_ICONBOX);
1108      }
1109    else
1110      {
1111         EMoveResizeWindow(ct->cover_win, -30000, -30000, 2, 2);
1112         EUnmapWindow(ct->cover_win);
1113      }
1114
1115    if (ct->nobg && ct->num_objs == 0)
1116      {
1117         im = NULL;
1118      }
1119    else if (ct->ic_box &&
1120             (!ct->nobg || (ct->type == IB_TYPE_SYSTRAY && !ct->draw_icon_base)))
1121      {
1122         /* Start out with iconbox image class image */
1123         im = ImageclassGetImageBlended(ct->ic_box, ct->icon_win, ib_w0, ib_h0,
1124                                        0, 0, STATE_NORMAL, ST_ICONBOX);
1125      }
1126    else
1127      {
1128         /* Start out with blank image */
1129         im = EImageCreate(ib_w0, ib_h0);
1130         EImageSetHasAlpha(im, 1);
1131         EImageFill(im, 0, 0, ib_w0, ib_h0, 0, 0, 0, 0);
1132      }
1133
1134    for (i = 0; i < ct->num_objs; i++)
1135      {
1136         ContainerObject    *cto;
1137
1138         cto = &ct->objs[i];
1139
1140         if (ct->draw_icon_base && ct->im_item_base)
1141           {
1142              EImageGetSize(ct->im_item_base, &ww, &hh);
1143              EImageBlend(im, ct->im_item_base, EIMAGE_BLEND | EIMAGE_ANTI_ALIAS,
1144                          0, 0, ww, hh, cto->xo, cto->yo, cto->wo, cto->ho, 1);
1145           }
1146
1147         ct->ops->ObjPlace(ct, cto, im);
1148      }
1149
1150    if (im)
1151      {
1152         EMapWindow(ct->icon_win);
1153         EImageApplyToWin(im, ct->icon_win, EIMAGE_HIGH_MASK_THR, 0, 0);
1154         EImageFree(im);
1155
1156         if (ct->type == IB_TYPE_SYSTRAY && ct->nobg && !ct->draw_icon_base)
1157            EShapePropagate(ct->icon_win);
1158      }
1159    else
1160      {
1161         /* Transparent and no objects */
1162         EUnmapWindow(ct->icon_win);
1163      }
1164    EShapePropagate(ct->win);
1165    EwinUpdateShapeInfo(ct->ewin);
1166    ct->ewin->update.shape = 1;
1167    EwinPropagateShapes(ct->ewin);
1168 }
1169
1170 void
1171 ContainerRedraw(Container * ct)
1172 {
1173    EWin               *ewin = ct->ewin;
1174
1175    ct->do_update = 1;
1176    EwinResize(ct->ewin, ewin->client.w, ewin->client.h);
1177 }
1178
1179 static int
1180 ContainerScroll(Container * ct, int dir)
1181 {
1182    int                 ppos;
1183
1184    ppos = ct->pos;
1185    ct->pos += dir;
1186    ContainerFixPos(ct);
1187    if (ct->pos == ppos)
1188       return 0;
1189
1190    ContainerDraw(ct);
1191    return 1;
1192 }
1193
1194 static void
1195 ContainerShowMenu(Container * ct, int x __UNUSED__, int y __UNUSED__)
1196 {
1197    static Menu        *p_menu = NULL;
1198    MenuItem           *mi;
1199    char                s[1024];
1200
1201    if (p_menu)
1202       MenuDestroy(p_menu);
1203
1204    p_menu = MenuCreate("__CT_MENU", ct->menu_title, NULL, NULL);
1205
1206    Esnprintf(s, sizeof(s), "ibox cfg %s", ct->name);
1207    mi = MenuItemCreate(_("Settings..."), NULL, s, NULL);
1208    MenuAddItem(p_menu, mi);
1209
1210    Esnprintf(s, sizeof(s), "wop %#lx cl", WinGetXwin(ct->win));
1211    mi = MenuItemCreate(_("Close"), NULL, s, NULL);
1212    MenuAddItem(p_menu, mi);
1213
1214    if (ct->type == IB_TYPE_ICONBOX)
1215      {
1216         mi = MenuItemCreate(_("Create New Iconbox"), NULL, "ibox new", NULL);
1217         MenuAddItem(p_menu, mi);
1218      }
1219
1220    EFunc(NULL, "menus show __CT_MENU");
1221 }
1222
1223 static void
1224 ContainersShow(void)
1225 {
1226    Container          *ct;
1227
1228    if (ecore_list_count(container_list) > 0)
1229      {
1230         ECORE_LIST_FOR_EACH(container_list, ct) ContainerShow(ct);
1231      }
1232    else if (Conf.startup.firsttime)
1233      {
1234         ct = ContainerCreate("_IB_0");
1235         ContainerShow(ct);
1236         ContainersConfigSave();
1237      }
1238 }
1239
1240 static void
1241 ContainersDestroy(void)
1242 {
1243    Container          *ct;
1244
1245    ECORE_LIST_FOR_EACH(container_list, ct) ContainerDestroy(ct, 1);
1246 }
1247
1248 static void
1249 ContainerEventScrollWin(Win win __UNUSED__, XEvent * ev, void *prm)
1250 {
1251    Container          *ct = (Container *) prm;
1252    int                 x, y, w, h;
1253
1254    switch (ev->type)
1255      {
1256      case ButtonPress:
1257         if (ev->xbutton.button == 1)
1258            ct->scrollbox_clicked = 1;
1259         else if (ev->xbutton.button == 3)
1260            ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1261         break;
1262
1263      case ButtonRelease:
1264         if (!ct->scrollbox_clicked)
1265            break;
1266         ct->scrollbox_clicked = 0;
1267         EGetGeometry(ct->scrollbar_win, NULL, &x, &y, &w, &h, NULL, NULL);
1268         if (ct->orientation)
1269           {
1270              if (ev->xbutton.y < y)
1271                 ContainerScroll(ct, -8);
1272              else if (ev->xbutton.y > (y + h))
1273                 ContainerScroll(ct, 8);
1274           }
1275         else
1276           {
1277              if (ev->xbutton.x < x)
1278                 ContainerScroll(ct, -8);
1279              else if (ev->xbutton.x > (x + w))
1280                 ContainerScroll(ct, 8);
1281           }
1282         break;
1283      }
1284 }
1285
1286 static void
1287 ContainerEventScrollbarWin(Win win __UNUSED__, XEvent * ev, void *prm)
1288 {
1289    Container          *ct = (Container *) prm;
1290    static int          px, py, pos0;
1291    int                 bs, dp;
1292    ImageClass         *ic_sbb;
1293    EImageBorder       *pad;
1294
1295    switch (ev->type)
1296      {
1297      case ButtonPress:
1298         if (ev->xbutton.button == 1)
1299           {
1300              px = ev->xbutton.x_root;
1301              py = ev->xbutton.y_root;
1302              pos0 = ct->pos;
1303              ct->scrollbar_clicked = 1;
1304           }
1305         else if (ev->xbutton.button == 3)
1306            ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1307         break;
1308
1309      case ButtonRelease:
1310         if (ct->scrollbar_clicked)
1311            ct->scrollbar_clicked = 0;
1312         break;
1313
1314      case EnterNotify:
1315         ct->scrollbar_hilited = 1;
1316         break;
1317
1318      case LeaveNotify:
1319         ct->scrollbar_hilited = 0;
1320         break;
1321
1322      case MotionNotify:
1323         if (!ct->scrollbar_clicked)
1324            break;
1325
1326         if (ct->orientation)
1327           {
1328              ic_sbb = ImageclassFind("ICONBOX_SCROLLBAR_BASE_VERTICAL", 1);
1329              pad = ImageclassGetPadding(ic_sbb);
1330              bs = ct->h - (ct->arrow_thickness * 2);
1331              if (pad)
1332                 bs -= pad->top + pad->bottom;
1333              if (bs < 1)
1334                 bs = 1;
1335              dp = ev->xmotion.y_root - py;
1336           }
1337         else
1338           {
1339              ic_sbb = ImageclassFind("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 1);
1340              pad = ImageclassGetPadding(ic_sbb);
1341              bs = ct->w - (ct->arrow_thickness * 2);
1342              if (pad)
1343                 bs -= pad->left + pad->right;
1344              if (bs < 1)
1345                 bs = 1;
1346              dp = ev->xmotion.x_root - px;
1347           }
1348         dp = pos0 + (dp * ct->max) / bs - ct->pos;
1349         if (dp)
1350            ContainerScroll(ct, dp);
1351         return;
1352      }
1353    ContainerDrawScroll(ct);
1354 }
1355
1356 static void
1357 ContainerEventCoverWin(Win win __UNUSED__, XEvent * ev, void *prm)
1358 {
1359    Container          *ct = (Container *) prm;
1360
1361    switch (ev->type)
1362      {
1363      case ButtonPress:
1364         ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1365         break;
1366      case ButtonRelease:
1367         break;
1368      }
1369 }
1370
1371 static void
1372 ContainerEventArrow1Win(Win win __UNUSED__, XEvent * ev, void *prm)
1373 {
1374    Container          *ct = (Container *) prm;
1375
1376    switch (ev->type)
1377      {
1378      case ButtonPress:
1379         if (ev->xbutton.button == 1)
1380            ct->arrow1_clicked = 1;
1381         else if (ev->xbutton.button == 3)
1382            ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1383         break;
1384
1385      case ButtonRelease:
1386         if (!ct->arrow1_clicked)
1387            break;
1388         ct->arrow1_clicked = 0;
1389         if (ContainerScroll(ct, -8))
1390            return;
1391         break;
1392
1393      case EnterNotify:
1394         ct->arrow1_hilited = 1;
1395         break;
1396
1397      case LeaveNotify:
1398         ct->arrow1_hilited = 0;
1399         break;
1400      }
1401    ContainerDrawScroll(ct);
1402 }
1403
1404 static void
1405 ContainerEventArrow2Win(Win win __UNUSED__, XEvent * ev, void *prm)
1406 {
1407    Container          *ct = (Container *) prm;
1408
1409    switch (ev->type)
1410      {
1411      case ButtonPress:
1412         if (ev->xbutton.button == 1)
1413            ct->arrow2_clicked = 1;
1414         else if (ev->xbutton.button == 3)
1415            ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1416         break;
1417
1418      case ButtonRelease:
1419         if (!ct->arrow2_clicked)
1420            break;
1421         ct->arrow2_clicked = 0;
1422         if (ContainerScroll(ct, 8))
1423            return;
1424         break;
1425
1426      case EnterNotify:
1427         ct->arrow2_hilited = 1;
1428         break;
1429
1430      case LeaveNotify:
1431         ct->arrow2_hilited = 0;
1432         break;
1433      }
1434    ContainerDrawScroll(ct);
1435 }
1436
1437 static void
1438 ContainerEventIconWin(Win win __UNUSED__, XEvent * ev, void *prm)
1439 {
1440    Container          *ct = (Container *) prm;
1441
1442    switch (ev->type)
1443      {
1444      case ButtonPress:
1445         if (ev->xbutton.button != 3)
1446            break;
1447         ContainerShowMenu(ct, ev->xbutton.x, ev->xbutton.y);
1448         return;
1449      }
1450
1451    if (ct->ops->Event)
1452       ct->ops->Event(ct, ev);
1453 }
1454
1455 #if ENABLE_DIALOGS
1456 /*
1457  * Configuration dialog
1458  */
1459 static char        *tmp_ib_name = NULL;
1460 static char         tmp_ib_nobg;
1461 static char         tmp_ib_shownames;
1462 static int          tmp_ib_vert;
1463 static int          tmp_ib_side;
1464 static int          tmp_ib_arrows;
1465 static int          tmp_ib_iconsize;
1466 static int          tmp_ib_mode;
1467 static char         tmp_ib_auto_resize;
1468 static char         tmp_ib_draw_icon_base;
1469 static char         tmp_ib_scrollbar_hide;
1470 static char         tmp_ib_cover_hide;
1471 static int          tmp_ib_autoresize_anchor;
1472 static char         tmp_ib_anim_mode;
1473
1474 static void
1475 CB_ConfigureContainer(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
1476 {
1477    if (val < 2)
1478      {
1479         Container          *ct;
1480
1481         if (!tmp_ib_name)
1482            return;
1483         ct = ContainerFind(tmp_ib_name);
1484         if (!ct)
1485            return;
1486
1487         ct->nobg = tmp_ib_nobg;
1488         ct->shownames = tmp_ib_shownames;
1489         ct->orientation = tmp_ib_vert;
1490         ct->scrollbar_side = tmp_ib_side;
1491         ct->arrow_side = tmp_ib_arrows;
1492         ct->iconsize = tmp_ib_iconsize;
1493         ct->icon_mode = tmp_ib_mode;
1494         ct->auto_resize = tmp_ib_auto_resize;
1495         ct->draw_icon_base = tmp_ib_draw_icon_base;
1496         ct->scrollbar_hide = tmp_ib_scrollbar_hide;
1497         ct->cover_hide = tmp_ib_cover_hide;
1498         ct->auto_resize_anchor = tmp_ib_autoresize_anchor;
1499         ct->anim_mode = tmp_ib_anim_mode;
1500
1501         ContainerReconfigure(ct);
1502         ContainerRedraw(ct);
1503         ContainersConfigSave();
1504      }
1505 }
1506
1507 static void
1508 CB_IconSizeSlider(Dialog * d, int val __UNUSED__, void *data)
1509 {
1510    DItem              *di = (DItem *) data;
1511    char                s[256];
1512
1513    Esnprintf(s, sizeof(s), _("Icon size: %2d"), tmp_ib_iconsize);
1514    DialogItemSetText(di, s);
1515    DialogDrawItems(d, di, 0, 0, 99999, 99999);
1516 }
1517
1518 static void
1519 _DlgFillContainer(Dialog * d, DItem * table, void *data)
1520 {
1521    Container          *ct = (Container *) data;
1522    DItem              *di, *table2;
1523    DItem              *radio1, *radio2, *radio3, *radio4, *label;
1524    char                s[256];
1525
1526    if (!ct)
1527       return;
1528
1529    tmp_ib_nobg = ct->nobg;
1530    tmp_ib_shownames = ct->shownames;
1531    tmp_ib_vert = ct->orientation;
1532    tmp_ib_side = ct->scrollbar_side;
1533    tmp_ib_arrows = ct->arrow_side;
1534    tmp_ib_iconsize = ct->iconsize;
1535    tmp_ib_mode = ct->icon_mode;
1536    tmp_ib_auto_resize = ct->auto_resize;
1537    tmp_ib_draw_icon_base = ct->draw_icon_base;
1538    tmp_ib_scrollbar_hide = ct->scrollbar_hide;
1539    tmp_ib_cover_hide = ct->cover_hide;
1540    tmp_ib_autoresize_anchor = ct->auto_resize_anchor;
1541    tmp_ib_anim_mode = ct->anim_mode;
1542    Efree(tmp_ib_name);
1543    tmp_ib_name = Estrdup(ct->name);
1544
1545    DialogSetTitle(d, ct->dlg_title);
1546
1547    DialogItemTableSetOptions(table, 1, 0, 0, 0);
1548
1549    di = DialogAddItem(table, DITEM_CHECKBUTTON);
1550    DialogItemSetText(di, _("Transparent background"));
1551    DialogItemCheckButtonSetPtr(di, &tmp_ib_nobg);
1552
1553    di = DialogAddItem(table, DITEM_CHECKBUTTON);
1554    DialogItemSetText(di, _("Hide inner border"));
1555    DialogItemCheckButtonSetPtr(di, &tmp_ib_cover_hide);
1556
1557    di = DialogAddItem(table, DITEM_CHECKBUTTON);
1558    DialogItemSetText(di, _("Draw base image behind Icons"));
1559    DialogItemCheckButtonSetPtr(di, &tmp_ib_draw_icon_base);
1560
1561    di = DialogAddItem(table, DITEM_CHECKBUTTON);
1562    DialogItemSetText(di, _("Hide scrollbar when not needed"));
1563    DialogItemCheckButtonSetPtr(di, &tmp_ib_scrollbar_hide);
1564
1565    di = DialogAddItem(table, DITEM_CHECKBUTTON);
1566    DialogItemSetText(di, _("Automatically resize to fit Icons"));
1567    DialogItemCheckButtonSetPtr(di, &tmp_ib_auto_resize);
1568
1569    di = DialogAddItem(table, DITEM_TEXT);
1570    DialogItemSetFill(di, 0, 0);
1571    DialogItemSetAlign(di, 0, 512);
1572    DialogItemSetText(di,
1573                      _("Alignment of anchoring when automatically resizing:"));
1574
1575    di = DialogAddItem(table, DITEM_SLIDER);
1576    DialogItemSliderSetBounds(di, 0, 1024);
1577    DialogItemSliderSetUnits(di, 1);
1578    DialogItemSliderSetJump(di, 8);
1579    DialogItemSliderSetValPtr(di, &tmp_ib_autoresize_anchor);
1580
1581    di = DialogAddItem(table, DITEM_SEPARATOR);
1582
1583    label = di = DialogAddItem(table, DITEM_TEXT);
1584    DialogItemSetFill(di, 0, 0);
1585    DialogItemSetAlign(di, 0, 512);
1586    Esnprintf(s, sizeof(s), _("Icon size: %2d"), tmp_ib_iconsize);
1587    DialogItemSetText(di, s);
1588
1589    di = DialogAddItem(table, DITEM_SLIDER);
1590    DialogItemSliderSetBounds(di, 4, 128);
1591    DialogItemSliderSetUnits(di, 1);
1592    DialogItemSliderSetJump(di, 8);
1593    DialogItemSliderSetValPtr(di, &tmp_ib_iconsize);
1594    DialogItemSetCallback(di, CB_IconSizeSlider, 0, label);
1595
1596    di = DialogAddItem(table, DITEM_SEPARATOR);
1597
1598    table2 = DialogAddItem(table, DITEM_TABLE);
1599    DialogItemTableSetOptions(table2, 3, 0, 0, 0);
1600
1601    di = DialogAddItem(table2, DITEM_TEXT);
1602    DialogItemSetFill(di, 0, 0);
1603    DialogItemSetAlign(di, 0, 512);
1604    DialogItemSetText(di, _("Orientation:"));
1605
1606    di = DialogAddItem(table2, DITEM_TEXT);
1607    DialogItemSetFill(di, 0, 0);
1608    DialogItemSetAlign(di, 0, 512);
1609    DialogItemSetText(di, _("Scrollbar side:"));
1610
1611    di = DialogAddItem(table2, DITEM_TEXT);
1612    DialogItemSetFill(di, 0, 0);
1613    DialogItemSetAlign(di, 0, 512);
1614    DialogItemSetText(di, _("Scrollbar arrows:"));
1615
1616    radio1 = di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1617    DialogItemSetText(di, _("Horizontal"));
1618    DialogItemRadioButtonSetFirst(di, radio1);
1619    DialogItemRadioButtonGroupSetVal(di, 0);
1620
1621    radio2 = di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1622    DialogItemSetText(di, _("Left / Top"));
1623    DialogItemRadioButtonSetFirst(di, radio2);
1624    DialogItemRadioButtonGroupSetVal(di, 0);
1625
1626    radio3 = di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1627    DialogItemSetText(di, _("Start"));
1628    DialogItemRadioButtonSetFirst(di, radio3);
1629    DialogItemRadioButtonGroupSetVal(di, 0);
1630
1631    di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1632    DialogItemSetText(di, _("Vertical"));
1633    DialogItemRadioButtonSetFirst(di, radio1);
1634    DialogItemRadioButtonGroupSetVal(di, 1);
1635    DialogItemRadioButtonGroupSetValPtr(radio1, &tmp_ib_vert);
1636
1637    di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1638    DialogItemSetText(di, _("Right / Bottom"));
1639    DialogItemRadioButtonSetFirst(di, radio2);
1640    DialogItemRadioButtonGroupSetVal(di, 1);
1641    DialogItemRadioButtonGroupSetValPtr(radio2, &tmp_ib_side);
1642
1643    di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1644    DialogItemSetText(di, _("Both ends"));
1645    DialogItemRadioButtonSetFirst(di, radio3);
1646    DialogItemRadioButtonGroupSetVal(di, 1);
1647
1648    di = DialogAddItem(table2, DITEM_NONE);
1649    di = DialogAddItem(table2, DITEM_NONE);
1650
1651    di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1652    DialogItemSetText(di, _("End"));
1653    DialogItemRadioButtonSetFirst(di, radio3);
1654    DialogItemRadioButtonGroupSetVal(di, 2);
1655
1656    di = DialogAddItem(table2, DITEM_NONE);
1657    di = DialogAddItem(table2, DITEM_NONE);
1658
1659    di = DialogAddItem(table2, DITEM_RADIOBUTTON);
1660    DialogItemSetText(di, _("None"));
1661    DialogItemRadioButtonSetFirst(di, radio3);
1662    DialogItemRadioButtonGroupSetVal(di, 3);
1663    DialogItemRadioButtonGroupSetValPtr(radio3, &tmp_ib_arrows);
1664
1665    di = DialogAddItem(table, DITEM_SEPARATOR);
1666
1667    if (ct->type == IB_TYPE_ICONBOX)
1668      {
1669         di = DialogAddItem(table, DITEM_CHECKBUTTON);
1670         DialogItemSetText(di, _("Show icon names"));
1671         DialogItemCheckButtonSetPtr(di, &tmp_ib_shownames);
1672
1673         di = DialogAddItem(table, DITEM_CHECKBUTTON);
1674         DialogItemSetText(di, _("Animate when iconifying to this Iconbox"));
1675         DialogItemCheckButtonSetPtr(di, &tmp_ib_anim_mode);
1676
1677         di = DialogAddItem(table, DITEM_SEPARATOR);
1678
1679         di = DialogAddItem(table, DITEM_TEXT);
1680         DialogItemSetFill(di, 0, 0);
1681         DialogItemSetAlign(di, 0, 512);
1682         DialogItemSetText(di,
1683                           _
1684                           ("Icon image display policy (if one operation fails, try the next):"));
1685
1686         radio4 = di = DialogAddItem(table, DITEM_RADIOBUTTON);
1687         DialogItemSetText(di,
1688                           _
1689                           ("Snapshot Windows, Use application icon, Use Enlightenment Icon"));
1690         DialogItemRadioButtonSetFirst(di, radio4);
1691         DialogItemRadioButtonGroupSetVal(di, 0);
1692
1693         di = DialogAddItem(table, DITEM_RADIOBUTTON);
1694         DialogItemSetText(di,
1695                           _
1696                           ("Use application icon, Use Enlightenment Icon, Snapshot Window"));
1697         DialogItemRadioButtonSetFirst(di, radio4);
1698         DialogItemRadioButtonGroupSetVal(di, 1);
1699
1700         di = DialogAddItem(table, DITEM_RADIOBUTTON);
1701         DialogItemSetText(di, _("Use Enlightenment Icon, Snapshot Window"));
1702         DialogItemRadioButtonSetFirst(di, radio4);
1703         DialogItemRadioButtonGroupSetVal(di, 2);
1704         DialogItemRadioButtonGroupSetValPtr(radio4, &tmp_ib_mode);
1705      }
1706 }
1707
1708 static const DialogDef DlgContainer = {
1709    "CONFIGURE_ICONBOX",
1710    NULL,
1711    NULL,
1712    SOUND_SETTINGS_ICONBOX,
1713    "pix/iconbox.png",
1714    N_("Enlightenment Iconbox\n" "Settings Dialog\n"),
1715    _DlgFillContainer,
1716    DLG_OAC, CB_ConfigureContainer,
1717 };
1718 #endif /* ENABLE_DIALOGS */
1719
1720 /*
1721  * Configuration load/save
1722  */
1723 #include "conf.h"
1724
1725 static void
1726 ContainersConfigLoad(void)
1727 {
1728    int                 err = 0;
1729    FILE               *fs;
1730    char                s[FILEPATH_LEN_MAX];
1731    char                s2[FILEPATH_LEN_MAX];
1732    int                 i1, i2;
1733    Container          *ct, ct_dummy;
1734
1735    Esnprintf(s, sizeof(s), "%s.ibox", EGetSavePrefix());
1736    fs = fopen(s, "r");
1737    if (!fs)
1738       return;
1739
1740    ct = &ct_dummy;
1741    while (fgets(s, sizeof(s), fs))
1742      {
1743         i1 = ConfigParseline1(s, s2, NULL, NULL);
1744         i2 = atoi(s2);
1745         switch (i1)
1746           {
1747           case CONFIG_IBOX:
1748              err = -1;
1749              if (i2 != CONFIG_OPEN)
1750                 goto done;
1751              break;
1752           case CONFIG_CLOSE:
1753              ct = &ct_dummy;
1754              err = 0;
1755              break;
1756
1757           case CONFIG_CLASSNAME:        /* __NAME %s */
1758              ct = ContainerFind(s2);
1759              if (ct)
1760                 EwinHide(ct->ewin);
1761              ct = ContainerCreate(s2);
1762              break;
1763           case TEXT_ORIENTATION:        /* __ORIENTATION [ __HORIZONTAL | __VERTICAL ] */
1764              ct->orientation = i2;
1765              break;
1766           case CONFIG_TRANSPARENCY:     /* __TRANSPARENCY [ __ON | __OFF ] */
1767              ct->nobg = i2;
1768              break;
1769           case CONFIG_SHOW_NAMES:       /* __SHOW_NAMES [ __ON | __OFF ] */
1770              ct->shownames = i2;
1771              break;
1772           case CONFIG_ICON_SIZE:        /* __ICON_SIZE %i */
1773              ct->iconsize = i2;
1774              break;
1775           case CONFIG_ICON_MODE:        /* __ICON_MODE [ 0 | 1 | 2 | 3 | 4 ] */
1776              ct->icon_mode = i2;
1777              break;
1778           case CONFIG_SCROLLBAR_SIDE:   /* __SCROLLBAR_SIDE [ __BAR_LEFT/__BAR_TOP | __BAR_RIGHT/__BAR_BOTTOM ] */
1779              ct->scrollbar_side = i2;
1780              break;
1781           case CONFIG_SCROLLBAR_ARROWS: /* __SCROLLBAR_ARROWS [ __START | __BOTH | __FINISH | __NEITHER ] */
1782              ct->arrow_side = i2;
1783              break;
1784           case CONFIG_AUTOMATIC_RESIZE: /* __AUTOMATIC_RESIZE [ __ON | __OFF ] */
1785              ct->auto_resize = i2;
1786              break;
1787           case CONFIG_SHOW_ICON_BASE:   /* __SHOW_ICON_BASE [ __ON | __OFF ] */
1788              ct->draw_icon_base = i2;
1789              break;
1790           case CONFIG_SCROLLBAR_AUTOHIDE:       /* __SCROLLBAR_AUTOHIDE [ __ON | __OFF ] */
1791              ct->scrollbar_hide = i2;
1792              break;
1793           case CONFIG_COVER_HIDE:       /* __COVER_HIDE [ __ON | __OFF ] */
1794              ct->cover_hide = i2;
1795              break;
1796           case CONFIG_RESIZE_ANCHOR:    /* __RESIZE_ANCHOR 0-1024 */
1797              ct->auto_resize_anchor = i2;
1798              break;
1799           case CONFIG_IB_ANIMATE:       /* __ICONBOX_ANIMATE [ 0 | 1 | 2 ] */
1800              ct->anim_mode = i2;
1801              break;
1802           default:
1803              Eprintf("Warning: Iconbox configuration, ignoring: %s\n", s);
1804              break;
1805           }
1806      }
1807    if (err)
1808       Eprintf("Error: Iconbox configuration file load problem.\n");
1809
1810  done:
1811    fclose(fs);
1812 }
1813
1814 static void
1815 ContainersConfigSave(void)
1816 {
1817    char                s[FILEPATH_LEN_MAX];
1818    FILE               *fs;
1819    Container          *ct;
1820
1821    Esnprintf(s, sizeof(s), "%s.ibox", EGetSavePrefix());
1822    fs = fopen(s, "w");
1823    if (!fs)
1824       return;
1825
1826    /* We should check for errors... */
1827    ECORE_LIST_FOR_EACH(container_list, ct)
1828    {
1829       fprintf(fs, "19 999\n");
1830       fprintf(fs, "100 %s\n", ct->name);
1831       fprintf(fs, "200 %i\n", ct->orientation);
1832       fprintf(fs, "2001 %i\n", ct->nobg);
1833       fprintf(fs, "2002 %i\n", ct->shownames);
1834       fprintf(fs, "2003 %i\n", ct->iconsize);
1835       fprintf(fs, "2004 %i\n", ct->icon_mode);
1836       fprintf(fs, "2005 %i\n", ct->scrollbar_side);
1837       fprintf(fs, "2006 %i\n", ct->arrow_side);
1838       fprintf(fs, "2007 %i\n", ct->auto_resize);
1839       fprintf(fs, "2008 %i\n", ct->draw_icon_base);
1840       fprintf(fs, "2009 %i\n", ct->scrollbar_hide);
1841       fprintf(fs, "2010 %i\n", ct->cover_hide);
1842       fprintf(fs, "2011 %i\n", ct->auto_resize_anchor);
1843       fprintf(fs, "2012 %i\n", ct->anim_mode);
1844       fprintf(fs, "1000\n");
1845    }
1846
1847    fclose(fs);
1848 }
1849
1850 /*
1851  * Containers Module
1852  */
1853
1854 static void
1855 ContainersSighan(int sig, void *prm)
1856 {
1857    switch (sig)
1858      {
1859      case ESIGNAL_CONFIGURE:
1860         break;
1861      case ESIGNAL_START:
1862         ContainersConfigLoad();
1863         ContainersShow();
1864         break;
1865      case ESIGNAL_EXIT:
1866         ContainersDestroy();
1867         break;
1868      }
1869
1870 #if 0                           /* FIXME */
1871    ECORE_LIST_FOR_EACH(container_list, ct)
1872    {
1873       if (ct->ops)
1874          ct->ops->Signal(ct, sig, prm);
1875    }
1876 #else
1877    IconboxOps.Signal(NULL, sig, prm);
1878 #endif
1879 }
1880
1881 #if ENABLE_DIALOGS
1882 static void
1883 ContainersConfigure(const char *params)
1884 {
1885    Container          *ct;
1886
1887    if (!params || !params[0])
1888       params = "DEFAULT";
1889
1890    ct = ContainerFind(params);
1891    if (ct)
1892       DialogShowSimple(&DlgContainer, ct);
1893 }
1894 #endif /* ENABLE_DIALOGS */
1895
1896 Container          *
1897 ContainersIterate(ContainerIterator * cti, int type, void *data)
1898 {
1899    Container          *ct;
1900
1901    ECORE_LIST_FOR_EACH(container_list, ct)
1902    {
1903       if (ct->type != type)
1904          continue;
1905       if (cti(ct, data))
1906          return ct;
1907    }
1908
1909    return NULL;
1910 }
1911
1912 Container         **
1913 ContainersGetList(int *pnum)
1914 {
1915    return (Container **) ecore_list_items_get(container_list, pnum);
1916 }
1917
1918 /*
1919  * IPC functions
1920  */
1921 static void
1922 ContainerIpc(const char *params)
1923 {
1924    const char         *p;
1925    char                cmd[128], prm[128];
1926    int                 len, num;
1927
1928    cmd[0] = prm[0] = '\0';
1929    p = params;
1930    if (p)
1931      {
1932         len = 0;
1933         sscanf(p, "%100s %100s %n", cmd, prm, &len);
1934         p += len;
1935      }
1936
1937    if (!p || cmd[0] == '?')
1938      {
1939         /* List iconboxes */
1940      }
1941 #if ENABLE_DIALOGS
1942    else if (!strncmp(cmd, "cfg", 3))
1943      {
1944         ContainersConfigure(prm);
1945      }
1946 #endif
1947    else if (!strncmp(cmd, "new", 3))
1948      {
1949         Container          *ct;
1950
1951         if (!prm[0])
1952           {
1953              num = ecore_list_count(container_list);
1954              Esnprintf(prm, sizeof(prm), "_IB_%i", num);
1955           }
1956         ct = ContainerCreate(prm);
1957         ContainerShow(ct);
1958         ContainersConfigSave();
1959      }
1960 }
1961
1962 static const IpcItem ContainersIpcArray[] = {
1963    {
1964     ContainerIpc,
1965     "iconbox", "ibox",
1966     "Iconbox functions",
1967     "  iconbox new <name>   Create new iconbox\n"
1968     "  iconbox cfg          Configure iconboxes\n"}
1969 };
1970 #define N_IPC_FUNCS (sizeof(ContainersIpcArray)/sizeof(IpcItem))
1971
1972 /*
1973  * Configuration items
1974  */
1975 static const CfgItem ContainersCfgItems[] = {
1976    CFG_ITEM_INT(Conf_containers, anim_time, 250),
1977 };
1978 #define N_CFG_ITEMS (sizeof(ContainersCfgItems)/sizeof(CfgItem))
1979
1980 /*
1981  * Module descriptor
1982  */
1983 extern const EModule ModIconboxes;
1984 const EModule       ModIconboxes = {
1985    "iconboxes", "ibox",
1986    ContainersSighan,
1987    {N_IPC_FUNCS, ContainersIpcArray},
1988    {N_CFG_ITEMS, ContainersCfgItems}
1989 };