Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / illume2 / policies / tablet / policy.c
1 #include "e_illume.h"
2 #include "policy.h"
3 #include "e.h"
4
5 /* local function prototypes */
6 static void _policy_border_set_focus(E_Border *bd);
7 static void _policy_border_move(E_Border *bd, int x, int y);
8 static void _policy_border_resize(E_Border *bd, int w, int h);
9 static void _policy_border_hide_below(E_Border *bd);
10 static void _policy_zone_layout_update(E_Zone *zone);
11 static void _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz);
12 static void _policy_zone_layout_quickpanel(E_Border *bd);
13 static void _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz);
14 static void _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz);
15 static void _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz);
16 static void _policy_zone_layout_fullscreen(E_Border *bd);
17 static void _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz);
18 static void _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
19 static void _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
20 static void _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force);
21 static void _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz);
22 static void _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz);
23 static void _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz);
24 #if 0
25 static void _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
26 static void _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
27 static void _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
28 #endif
29
30 static Eina_List *_pol_focus_stack;
31
32 /* local functions */
33 static void
34 _policy_border_set_focus(E_Border *bd)
35 {
36    if (!bd) return;
37    /* printf("_policy_border_set_focus %s\n", e_border_name_get(bd)); */
38
39    /* if focus is locked out then get out */
40    if (bd->lock_focus_out) return;
41
42    if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
43      {
44         /* check E's focus settings */
45         if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
46             ((bd->parent) &&
47              ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
48               ((bd->parent->focused) &&
49                (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
50           {
51              /* if the border was hidden due to layout, we need to unhide */
52              if (!bd->visible) e_illume_border_show(bd);
53
54              if ((bd->iconic) && (!bd->lock_user_iconify))
55                e_border_uniconify(bd);
56
57              if (!bd->lock_user_stacking) e_border_raise(bd);
58
59              /* focus the border */
60              e_border_focus_set(bd, 1, 1);
61              /* e_border_raise(bd); */
62              /* hide the border below this one */
63              _policy_border_hide_below(bd);
64
65              /* NB: since we skip needless border evals when container layout
66               * is called (to save cpu cycles), we need to
67               * signal this border that it's focused so that the edj gets
68               * updated.
69               *
70               * This is potentially useless as THIS policy
71               * makes all windows borderless anyway, but it's in here for
72               * completeness
73               e_border_focus_latest_set(bd);
74               if (bd->bg_object)
75               edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
76               if (bd->icon_object)
77               edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
78               e_focus_event_focus_in(bd);
79              */
80           }
81      }
82 }
83
84 static void
85 _policy_border_move(E_Border *bd, int x, int y)
86 {
87    if (!bd) return;
88
89    bd->x = x;
90    bd->y = y;
91    bd->changes.pos = 1;
92    bd->changed = 1;
93 }
94
95 static void
96 _policy_border_resize(E_Border *bd, int w, int h)
97 {
98    if (!bd) return;
99
100    bd->w = w;
101    bd->h = h;
102    bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r));
103    bd->client.h = (bd->h - (bd->client_inset.t + bd->client_inset.b));
104    bd->changes.size = 1;
105    bd->changed = 1;
106 }
107
108 static void
109 _policy_border_hide_below(E_Border *bd)
110 {
111    int pos = 0, i;
112
113    return;
114
115    //   printf("Hide Borders Below: %s %d %d\n",
116    //          bd->client.icccm.name, bd->x, bd->y);
117
118    if (!bd) return;
119    /* printf("_policy_border_hide_below %s\n", e_border_name_get(bd)); */
120    /* determine layering position */
121    if (bd->layer <= 0) pos = 0;
122    else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
123    else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
124    else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
125    else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
126    else pos = 5;
127
128    /* Find the windows below this one */
129    for (i = pos; i >= 2; i--)
130      {
131         Eina_List *l;
132         E_Border *b;
133
134         EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b)
135           {
136              /* skip if it's the same border */
137              if (b == bd) continue;
138
139              /* skip if it's not on this zone */
140              if (b->zone != bd->zone) continue;
141
142              /* skip special borders */
143              if (e_illume_border_is_indicator(b)) continue;
144              if (e_illume_border_is_softkey(b)) continue;
145              if (e_illume_border_is_keyboard(b)) continue;
146              if (e_illume_border_is_quickpanel(b)) continue;
147              if (e_illume_border_is_home(b)) continue;
148
149              if ((bd->fullscreen) || (bd->need_fullscreen))
150                {
151                   if (b->visible) e_illume_border_hide(b);
152                }
153              else
154                {
155                   /* we need to check x/y position */
156                   if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
157                                  b->x, b->y, b->w, b->h))
158                     {
159                        if (b->visible) e_illume_border_hide(b);
160                     }
161                }
162           }
163      }
164 }
165
166 #if 0
167 static void
168 _policy_border_show_below(E_Border *bd)
169 {
170    Eina_List *l;
171    E_Border *prev;
172    int pos = 0, i;
173
174    //   printf("Show Borders Below: %s %d %d\n",
175    //          bd->client.icccm.class, bd->x, bd->y);
176
177    if (!bd) return;
178    /* printf("_policy_border_show_below %s\n", e_border_name_get(bd)); */
179    if (bd->client.icccm.transient_for)
180      {
181         if ((prev = e_border_find_by_client_window(bd->client.icccm.transient_for)))
182           {
183              _policy_border_set_focus(prev);
184              return;
185           }
186      }
187
188    /* determine layering position */
189    if (bd->layer <= 0) pos = 0;
190    else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
191    else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
192    else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
193    else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
194    else pos = 5;
195
196    /* Find the windows below this one */
197    for (i = pos; i >= 2; i--)
198      {
199         E_Border *b;
200
201         EINA_LIST_REVERSE_FOREACH(bd->zone->container->layers[i].clients, l, b)
202           {
203              /* skip if it's the same border */
204              if (b == bd) continue;
205
206              /* skip if it's not on this zone */
207              if (b->zone != bd->zone) continue;
208
209              /* skip special borders */
210              if (e_illume_border_is_indicator(b)) continue;
211              if (e_illume_border_is_softkey(b)) continue;
212              if (e_illume_border_is_keyboard(b)) continue;
213              if (e_illume_border_is_quickpanel(b)) continue;
214              if (e_illume_border_is_home(b)) continue;
215
216              if ((bd->fullscreen) || (bd->need_fullscreen))
217                {
218                   _policy_border_set_focus(b);
219                   return;
220                }
221              else
222                {
223                   /* need to check x/y position */
224                   if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
225                                  b->x, b->y, b->w, b->h))
226                     {
227                        _policy_border_set_focus(b);
228                        return;
229                     }
230                }
231           }
232      }
233
234    /* if we reach here, then there is a problem with showing a window below
235     * this one, so show previous window in stack */
236    EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, prev)
237      {
238         if (prev->zone != bd->zone) continue;
239         _policy_border_set_focus(prev);
240         return;
241      }
242
243    /* Fallback to focusing home if all above fails */
244    _policy_focus_home(bd->zone);
245 }
246 #endif
247
248 static void
249 _policy_zone_layout_update(E_Zone *zone)
250 {
251    Eina_List *l;
252    E_Border *bd;
253
254    if (!zone) return;
255
256    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
257      {
258         /* skip borders not on this zone */
259         if (bd->zone != zone) continue;
260
261         /* skip special windows */
262         if (e_illume_border_is_keyboard(bd)) continue;
263         if (e_illume_border_is_quickpanel(bd)) continue;
264
265         /* signal a changed pos here so layout gets updated */
266         bd->changes.pos = 1;
267         bd->changed = 1;
268      }
269 }
270
271 static void
272 _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz)
273 {
274    if ((!bd) || (!cz)) return;
275
276    /* grab minimum indicator size */
277    e_illume_border_min_get(bd, NULL, &cz->indicator.size);
278
279    /* no point in doing anything here if indicator is hidden */
280    if ((!bd->new_client) && (!bd->visible))
281      {
282         ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
283                                                 0, 0, 0, 0);
284         return;
285      }
286
287    /* if we are dragging, then skip it for now */
288    if (bd->client.illume.drag.drag)
289      {
290         /* when dragging indicator, we need to trigger a layout update */
291         ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
292                                                 0, 0, 0, 0);
293         _policy_zone_layout_update(bd->zone);
294         return;
295      }
296
297    //   printf("\tLayout Indicator: %d\n", bd->zone->num);
298
299    /* lock indicator window from dragging if we need to */
300    if ((cz->mode.dual == 1) && (cz->mode.side == 0))
301      ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
302    else
303      ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
304
305    if ((bd->w != bd->zone->w) || (bd->h != cz->indicator.size))
306      _policy_border_resize(bd, bd->zone->w, cz->indicator.size);
307
308    if (!cz->mode.dual)
309      {
310         /* move to 0, 0 (relative to zone) if needed */
311         if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
312           {
313              _policy_border_move(bd, bd->zone->x, bd->zone->y);
314              ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
315           }
316      }
317    else
318      {
319         if (cz->mode.side == 0)
320           {
321              /* top mode...indicator is draggable so just set X.
322               * in this case, the indicator itself should be responsible for
323               * sending the quickpanel position update message when it is
324               * finished dragging */
325              if (bd->x != bd->zone->x)
326                _policy_border_move(bd, bd->zone->x, bd->y);
327           }
328         else
329           {
330              /* move to 0, 0 (relative to zone) if needed */
331              if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
332                {
333                   _policy_border_move(bd, bd->zone->x, bd->zone->y);
334                   ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
335                }
336           }
337      }
338    ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
339                                            bd->x, bd->y,
340                                            bd->w, bd->h);
341
342    if (bd->layer != POL_INDICATOR_LAYER)
343      e_border_layer_set(bd, POL_INDICATOR_LAYER);
344 }
345
346 #define ZONE_GEOMETRY                                   \
347   int x, y, w, h;                                       \
348   e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h); \
349   x += bd->zone->x;                                     \
350   y += bd->zone->y;                                     \
351
352 static void
353 _border_geometry_set(E_Border *bd, int x, int y, int w, int h, int layer)
354 {
355    if ((bd->w != w) || (bd->h != h))
356      _policy_border_resize(bd, w, h);
357
358    if ((bd->x != x) || (bd->y != y))
359      _policy_border_move(bd, x, y);
360
361    if ((int)bd->layer != layer) e_border_layer_set(bd, layer);
362 }
363
364 static void
365 _policy_zone_layout_quickpanel(E_Border *bd)
366 {
367    int mh;
368
369    if (!bd) return;
370
371    e_illume_border_min_get(bd, NULL, &mh);
372
373    if ((bd->w != bd->zone->w) || (bd->h != mh))
374      _policy_border_resize(bd, bd->zone->w, mh);
375
376    if (bd->layer != POL_QUICKPANEL_LAYER)
377      e_border_layer_set(bd, POL_QUICKPANEL_LAYER);
378 }
379
380 static void
381 _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz)
382 {
383    int ny;
384
385    if ((!bd) || (!cz)) return;
386    if (!bd->visible)
387      {
388         ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win, 0, 0, 0, 0);
389         return;
390      }
391
392    ZONE_GEOMETRY;
393
394    e_illume_border_min_get(bd, NULL, &cz->softkey.size);
395
396    /* if we are dragging, then skip it for now */
397    /* NB: Disabled currently until we confirm that softkey should be draggable */
398    //   if (bd->client.illume.drag.drag) return;
399
400    if ((bd->w != w) || (bd->h != cz->softkey.size))
401      _policy_border_resize(bd, w, cz->softkey.size);
402
403    ny = ((bd->zone->y + bd->zone->h) - cz->softkey.size);
404
405    /* NB: not sure why yet, but on startup the border->y is reporting
406     * that it is already in this position...but it's actually not.
407     * So for now, just disable the ny check until this gets sorted out */
408
409    if ((bd->x != x) || (bd->y != ny))
410      _policy_border_move(bd, x, ny);
411
412    /* _border_geometry_set(bd, x, ny, nw, nh, bd, POL_CONFORMANT_LAYER); */
413
414    ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win,
415                                          bd->x, bd->y,
416                                          bd->w, bd->h);
417
418    if (bd->layer != POL_SOFTKEY_LAYER) e_border_layer_set(bd, POL_SOFTKEY_LAYER);
419 }
420
421
422
423 #define MIN_HEIGHT 100
424
425 static Eina_Bool
426 _policy_layout_app_check(E_Border *bd)
427 {
428    if (!bd)
429      return EINA_FALSE;
430
431    if (!bd->visible)
432      return EINA_FALSE;
433
434    if ((bd->desk != e_desk_current_get(bd->zone)) && (!bd->sticky))
435      return EINA_FALSE;
436
437    return EINA_TRUE;
438 }
439
440
441 static void
442 _policy_keyboard_restrict(E_Border *bd, int *h)
443 {
444    int kh;
445
446    if (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
447      {
448         e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
449         kh -= bd->zone->h - *h;
450         if ((kh < *h) && (kh > MIN_HEIGHT))
451           *h = kh;
452      }
453 }
454
455 static void
456 _policy_indicator_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
457 {
458    if ((cz->indicator.size) && (*y < cz->indicator.size))
459      {
460         *h -= cz->indicator.size;
461         *y = cz->indicator.size;
462      }
463 }
464
465 static void
466 _policy_softkey_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
467 {
468    if ((cz->softkey.size) && ((*y + *h) > cz->softkey.size))
469      *h -= (*y + *h) - cz->softkey.size;
470 }
471
472 static void
473 _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz)
474 {
475    int ny, layer;
476
477    if ((!bd) || (!cz) || (!bd->visible)) return;
478
479    ZONE_GEOMETRY;
480
481    e_illume_border_min_get(bd, NULL, &cz->vkbd.size);
482
483    ny = ((bd->zone->y + bd->zone->h) - cz->vkbd.size);
484
485    /* if ((bd->fullscreen) || (bd->need_fullscreen))
486     *   layer = POL_FULLSCREEN_LAYER;
487     * else */
488    layer = POL_KEYBOARD_LAYER;
489    
490    _border_geometry_set(bd, x, ny, w, cz->vkbd.size, layer);
491 }
492
493 static void
494 _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz)
495 {
496    if ((!bd) || (!cz) || (!bd->visible)) return;
497
498    ZONE_GEOMETRY;
499    _policy_indicator_restrict(cz, &y, &h);
500    _border_geometry_set(bd, x, y, w, h, POL_HOME_LAYER);
501 }
502
503 static void
504 _policy_zone_layout_fullscreen(E_Border *bd)
505 {
506    if (!_policy_layout_app_check(bd)) return;
507
508    ZONE_GEOMETRY;
509
510    _policy_keyboard_restrict(bd, &h);
511
512    _border_geometry_set(bd, x, y, w, h, POL_FULLSCREEN_LAYER);
513 }
514
515 static void
516 _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
517 {
518    if (!_policy_layout_app_check(bd)) return;
519
520    ZONE_GEOMETRY;
521
522    _policy_keyboard_restrict(bd, &h);
523    _policy_indicator_restrict(cz, &y, &h);
524    _policy_softkey_restrict(cz, &y, &h);
525
526    _border_geometry_set(bd, x, y, w, h, POL_APP_LAYER);
527 }
528
529 static void
530 _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
531 {
532    E_Border *bd2;
533
534    if (!_policy_layout_app_check(bd)) return;
535
536    ZONE_GEOMETRY;
537
538    _policy_keyboard_restrict(bd, &h);
539    _policy_indicator_restrict(cz, &y, &h);
540    _policy_softkey_restrict(cz, &y, &h);
541
542    bd2 = e_illume_border_at_xy_get(bd->zone, x, y);
543    if ((bd2) && (bd2 != bd))
544      {
545         if ((bd->focused) && (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF))
546           _border_geometry_set(bd2, x, h/2 + y, w, h/2, POL_APP_LAYER);
547         else
548           y += h/2;
549      }
550
551    _border_geometry_set(bd, x, y, w, h/2, POL_APP_LAYER);
552 }
553
554 static void
555 _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
556 {
557    E_Border *app;
558    int iy, ny, nh;
559
560    if (!_policy_layout_app_check(bd)) return;
561
562    ZONE_GEOMETRY;
563
564    e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
565
566    ny = bd->zone->y;
567    nh = iy;
568
569    app = e_illume_border_at_xy_get(bd->zone, bd->zone->x, bd->zone->y);
570    if ((app) && (bd != app))
571      {
572         ny = (iy + cz->indicator.size);
573         nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size);
574      }
575
576    _border_geometry_set(bd, x, ny, w, nh, POL_APP_LAYER);
577 }
578
579 static void
580 _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force)
581 {
582    E_Border *bd2;
583    int ky, kh, nx, nw;
584
585    if (!_policy_layout_app_check(bd)) return;
586
587    ZONE_GEOMETRY;
588
589    e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh);
590
591    if (kh >= bd->zone->h)
592      kh = (kh - cz->indicator.size - cz->softkey.size);
593    else
594      kh = (kh - cz->indicator.size);
595
596    nx = x;
597    nw = w / 2;
598
599    if (!force)
600      {
601         /* see if there is a border already there. if so, place at right */
602         bd2 = e_illume_border_at_xy_get(bd->zone, nx, y);
603         if ((bd2) && (bd != bd2)) nx = x + nw;
604      }
605
606    _border_geometry_set(bd, nx, y, nw, kh, POL_APP_LAYER);
607 }
608
609 static void
610 _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz)
611 {
612    E_Border *parent;
613    int mw, mh, nx, ny;
614
615    /* if (!_policy_layout_app_check(bd)) return; */
616    if ((!bd) || (!cz)) return;
617    printf("place dialog %d - %dx%d\n", bd->placed, bd->w, bd->h);
618
619    if (bd->placed)
620      return;
621
622    ZONE_GEOMETRY;
623
624    mw = bd->w;
625    mh = bd->h;
626
627    if (e_illume_border_is_fixed_size(bd))
628      {
629         if (mw > w) mw = w;
630         if (mh > h) mh = h;
631      }
632    else
633      {
634         if (w * 2/3 > bd->w)
635           mw = w * 2/3;
636
637         if (h * 2/3 > bd->h)
638           mh = h * 2/3;
639      }
640
641    parent = e_illume_border_parent_get(bd);
642
643    if ((!parent) || (cz->mode.dual == 1))
644      {
645         nx = (x + ((w - mw) / 2));
646         ny = (y + ((h - mh) / 2));
647      }
648    else
649      {
650         if (mw > parent->w) mw = parent->w;
651         if (mh > parent->h) mh = parent->h;
652
653         nx = (parent->x + ((parent->w - mw) / 2));
654         ny = (parent->y + ((parent->h - mh) / 2));
655      }
656
657    bd->placed = 1;
658    
659    _border_geometry_set(bd, nx, ny, mw, mh, POL_DIALOG_LAYER);
660    printf("set geom %d %d\n", mw, mh);
661 }
662
663 static void
664 _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
665 {
666    _policy_zone_layout_dialog(bd, cz);
667
668    if (bd->layer != POL_SPLASH_LAYER) e_border_layer_set(bd, POL_SPLASH_LAYER);
669 }
670
671 static void
672 _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz __UNUSED__)
673 {
674    if (!_policy_layout_app_check(bd)) return;
675
676    _border_geometry_set(bd, bd->zone->x, bd->zone->y,
677                         bd->zone->w, bd->zone->h,
678                         POL_CONFORMANT_LAYER);
679 }
680
681 #if 0
682 typedef struct _App_Desk App_Desk;
683
684 struct _App_Desk
685 {
686   E_Desk *desk;
687   const char *class;
688   Eina_List *borders;
689 };
690
691 static Eina_List *desks = NULL;
692
693 #define EINA_LIST_FIND(_list, _item, _match)    \
694   {                                             \
695      Eina_List *_l;                             \
696      EINA_LIST_FOREACH(_list, _l, _item)        \
697        if (_match) break;                       \
698   }
699 #endif
700
701
702 /* policy functions */
703 void
704 _policy_border_add(E_Border *bd)
705 {
706    //   printf("Border added: %s\n", bd->client.icccm.class);
707
708    if (!bd) return;
709
710    /* NB: this call sets an atom on the window that specifices the zone.
711     * the logic here is that any new windows created can access the zone
712     * window by a 'get' call. This is useful for elementary apps as they
713     * normally would not have access to the zone window. Typical use case
714     * is for indicator & softkey windows so that they can send messages
715     * that apply to their respective zone only. Example: softkey sends close
716     * messages (or back messages to cycle focus) that should pertain just
717     * to it's current zone */
718    ecore_x_e_illume_zone_set(bd->client.win, bd->zone->black_win);
719
720    if (e_illume_border_is_keyboard(bd))
721      {
722         bd->sticky = 1;
723         e_hints_window_sticky_set(bd, 1);
724      }
725    
726    if (e_illume_border_is_home(bd))
727      {
728         bd->sticky = 1;
729         e_hints_window_sticky_set(bd, 1);
730      }
731
732    if (e_illume_border_is_indicator(bd))
733      {
734         bd->sticky = 1;
735         e_hints_window_sticky_set(bd, 1);
736      }
737
738    if (e_illume_border_is_softkey(bd))
739      {
740         bd->sticky = 1;
741         e_hints_window_sticky_set(bd, 1);
742      }
743
744    /* ignore stolen borders. These are typically quickpanel or keyboards */
745    if (bd->stolen) return;
746
747    /* if this is a fullscreen window, than we need to hide indicator window */
748    /* NB: we could use the e_illume_border_is_fullscreen function here
749     * but we save ourselves a function call this way */
750    if ((bd->fullscreen) || (bd->need_fullscreen))
751      {
752         E_Border *ind, *sft;
753
754         if ((ind = e_illume_border_indicator_get(bd->zone)))
755           {
756              if (ind->visible) e_illume_border_hide(ind);
757           }
758         if ((sft = e_illume_border_softkey_get(bd->zone)))
759           {
760              if (e_illume_border_is_conformant(bd))
761                {
762                   if (sft->visible)
763                     e_illume_border_hide(sft);
764                   else if (!sft->visible)
765                     e_illume_border_show(sft);
766                }
767           }
768      }
769
770
771 #if 0
772    if (bd->client.icccm.class)
773      {
774         Eina_List *l;
775         App_Desk *d;
776
777         EINA_LIST_FIND(desks, d, (d->class == bd->client.icccm.class));
778
779         if (!d)
780           {
781              d = E_NEW(App_Desk, 1);
782              d->desk
783           }
784
785         d->borders = eina_list_append(d->borders, bd);
786         e_border_desk_set(bd, d->desk);
787      }
788 #endif
789
790    /* Add this border to our focus stack if it can accept or take focus */
791    if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
792      _pol_focus_stack = eina_list_append(_pol_focus_stack, bd);
793
794    if ((e_illume_border_is_softkey(bd)) || (e_illume_border_is_indicator(bd)))
795      _policy_zone_layout_update(bd->zone);
796    else
797      {
798         /* set focus on new border if we can */
799         _policy_border_set_focus(bd);
800      }
801 }
802
803 void
804 _policy_border_del(E_Border *bd)
805 {
806    //   printf("Policy Border deleted: %s\n", bd->client.icccm.class);
807
808    if (!bd) return;
809
810    /* if this is a fullscreen window, than we need to show indicator window */
811    /* NB: we could use the e_illume_border_is_fullscreen function here
812     * but we save ourselves a function call this way */
813    if ((bd->fullscreen) || (bd->need_fullscreen))
814      {
815         E_Border *ind;
816
817         /* try to get the Indicator on this zone */
818         if ((ind = e_illume_border_indicator_get(bd->zone)))
819           {
820              if (!ind->visible) e_illume_border_show(ind);
821           }
822         _policy_zone_layout_update(bd->zone);
823      }
824
825    /* remove from focus stack */
826    if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
827      _pol_focus_stack = eina_list_remove(_pol_focus_stack, bd);
828
829    if (e_illume_border_is_softkey(bd))
830      {
831         E_Illume_Config_Zone *cz;
832
833         cz = e_illume_zone_config_get(bd->zone->num);
834         cz->softkey.size = 0;
835         _policy_zone_layout_update(bd->zone);
836      }
837    else if (e_illume_border_is_indicator(bd))
838      {
839         E_Illume_Config_Zone *cz;
840
841         cz = e_illume_zone_config_get(bd->zone->num);
842         cz->indicator.size = 0;
843         _policy_zone_layout_update(bd->zone);
844      }
845    /* else
846     *   {
847     *   _policy_border_show_below(bd);
848     *   } */
849 }
850
851 void
852 _policy_border_focus_in(E_Border *bd __UNUSED__)
853 {
854    E_Border *ind;
855
856    //   printf("Border focus in: %s\n", bd->client.icccm.name);
857    if ((bd->fullscreen) || (bd->need_fullscreen))
858      {
859         /* try to get the Indicator on this zone */
860         if ((ind = e_illume_border_indicator_get(bd->zone)))
861           {
862              /* we have the indicator, show it if needed */
863              if (ind->visible) e_illume_border_hide(ind);
864           }
865      }
866    else
867      {
868         /* try to get the Indicator on this zone */
869         if ((ind = e_illume_border_indicator_get(bd->zone)))
870           {
871              /* we have the indicator, show it if needed */
872              if (!ind->visible) e_illume_border_show(ind);
873           }
874      }
875    _policy_zone_layout_update(bd->zone);
876 }
877
878 void
879 _policy_border_focus_out(E_Border *bd)
880 {
881    //   printf("Border focus out: %s\n", bd->client.icccm.name);
882
883    if (!bd) return;
884
885    /* NB: if we got this focus_out event on a deleted border, we check if
886     * it is a transient (child) of another window. If it is, then we
887     * transfer focus back to the parent window */
888    if (e_object_is_del(E_OBJECT(bd)))
889      {
890         if (e_illume_border_is_dialog(bd))
891           {
892              E_Border *parent;
893
894              if ((parent = e_illume_border_parent_get(bd)))
895                _policy_border_set_focus(parent);
896           }
897      }
898 }
899
900 void
901 _policy_border_activate(E_Border *bd)
902 {
903    E_Border *sft;
904
905    //   printf("Border Activate: %s\n", bd->client.icccm.name);
906
907    if (!bd) return;
908
909    /* NB: stolen borders may or may not need focus call...have to test */
910    if (bd->stolen) return;
911
912    /* conformant windows hide the softkey */
913    if ((sft = e_illume_border_softkey_get(bd->zone)))
914      {
915         if (e_illume_border_is_conformant(bd))
916           {
917              if (sft->visible) e_illume_border_hide(sft);
918           }
919         else
920           {
921              if (!sft->visible) e_illume_border_show(sft);
922           }
923      }
924
925    /* NB: We cannot use our set_focus function here because it does,
926     * occasionally fall through wrt E's focus policy, so cherry pick the good
927     * parts and use here :) */
928    if (bd->desk != e_desk_current_get(bd->zone))
929      e_desk_show(bd->desk);
930
931    /* if the border is iconified then uniconify if allowed */
932    if ((bd->iconic) && (!bd->lock_user_iconify))
933      e_border_uniconify(bd);
934
935    /* set very high layer for this window as it needs attention and thus
936     * should show above everything */
937    e_border_layer_set(bd, POL_ACTIVATE_LAYER);
938
939    /* if we can raise the border do it */
940    if (!bd->lock_user_stacking) e_border_raise(bd);
941
942    /* focus the border */
943    e_border_focus_set(bd, 1, 1);
944
945    /* NB: since we skip needless border evals when container layout
946     * is called (to save cpu cycles), we need to
947     * signal this border that it's focused so that the edj gets
948     * updated.
949     *
950     * This is potentially useless as THIS policy
951     * makes all windows borderless anyway, but it's in here for
952     * completeness
953     e_border_focus_latest_set(bd);
954     if (bd->bg_object)
955     edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
956     if (bd->icon_object)
957     edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
958     e_focus_event_focus_in(bd);
959    */
960 }
961 static Eina_Bool
962 _policy_border_is_dialog(E_Border *bd)
963 {
964    if (e_illume_border_is_dialog(bd))
965      return EINA_TRUE;
966
967    if (bd->client.e.state.centered)
968      return EINA_TRUE;
969
970    if (bd->internal)
971      {
972         if (bd->client.icccm.class)
973           {
974              if (!strncmp(bd->client.icccm.class, "Illume", 6))
975                return EINA_FALSE;
976              if (!strncmp(bd->client.icccm.class, "e_fwin", 6))
977                return EINA_FALSE;
978              if (!strncmp(bd->client.icccm.class, "every", 5))
979                return EINA_FALSE;
980
981           }
982         return EINA_TRUE;
983      }
984
985    return EINA_FALSE;
986 }
987
988 void
989 _policy_border_post_fetch(E_Border *bd)
990 {
991    if (!bd) return;
992
993    /* NB: for this policy we disable all remembers set on a border */
994    if (bd->remember) e_remember_del(bd->remember);
995    bd->remember = NULL;
996
997    if (_policy_border_is_dialog(bd))
998      {
999         return;
1000      }
1001    else if (e_illume_border_is_fixed_size(bd))
1002      {
1003         return;
1004      }
1005    else if (!bd->borderless)
1006      {
1007         bd->borderless = 1;
1008         bd->client.border.changed = 1;
1009      }
1010 }
1011
1012 void
1013 _policy_border_post_assign(E_Border *bd)
1014 {
1015    if (!bd) return;
1016
1017    bd->internal_no_remember = 1;
1018
1019    if (_policy_border_is_dialog(bd) ||
1020        e_illume_border_is_fixed_size(bd))
1021      return;
1022
1023    /* do not allow client to change these properties */
1024    bd->lock_client_size = 1;
1025    bd->lock_client_shade = 1;
1026    bd->lock_client_maximize = 1;
1027    bd->lock_client_location = 1;
1028    bd->lock_client_stacking = 1;
1029
1030    /* do not allow the user to change these properties */
1031    /* bd->lock_user_location = 1;
1032     * bd->lock_user_size = 1;
1033     * bd->lock_user_shade = 1; */
1034
1035    /* clear any centered states */
1036    /* NB: this is mainly needed for E's main config dialog */
1037    bd->client.e.state.centered = 0;
1038
1039    /* lock the border type so user/client cannot change */
1040    bd->lock_border = 1;
1041
1042    /* disable e's placement (and honoring of icccm.request_pos) */
1043    bd->placed = 1;
1044 }
1045
1046 void
1047 _policy_border_show(E_Border *bd)
1048 {
1049    if (!bd) return;
1050
1051    /* printf("_policy_border_show %s\n", e_border_name_get(bd)); */
1052
1053    if (!bd->client.icccm.name) return;
1054
1055    //   printf("Border Show: %s\n", bd->client.icccm.class);
1056
1057    /* trap for special windows so we can ignore hides below them */
1058    if (e_illume_border_is_indicator(bd)) return;
1059    if (e_illume_border_is_softkey(bd)) return;
1060    if (e_illume_border_is_quickpanel(bd)) return;
1061    if (e_illume_border_is_keyboard(bd)) return;
1062
1063    _policy_border_hide_below(bd);
1064 }
1065
1066 /* called on E_BORDER_HOOK_CONTAINER_LAYOUT (after e_border/eval0) */
1067 void
1068 _policy_zone_layout(E_Zone *zone)
1069 {
1070    E_Illume_Config_Zone *cz;
1071    Eina_List *l;
1072    E_Border *bd;
1073
1074    if (!zone) return;
1075
1076    cz = e_illume_zone_config_get(zone->num);
1077
1078    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1079      {
1080         if (e_object_is_del(E_OBJECT(bd))) continue;
1081
1082         if (bd->zone != zone) continue;
1083
1084         if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
1085             (!bd->changes.visible) && (!bd->pending_move_resize) &&
1086             (!bd->need_shape_export) && (!bd->need_shape_merge)) continue;
1087
1088         if (e_illume_border_is_indicator(bd))
1089           _policy_zone_layout_indicator(bd, cz);
1090
1091         else if (e_illume_border_is_quickpanel(bd))
1092           _policy_zone_layout_quickpanel(bd);
1093
1094         else if (e_illume_border_is_softkey(bd))
1095           _policy_zone_layout_softkey(bd, cz);
1096
1097         else if (e_illume_border_is_keyboard(bd))
1098           _policy_zone_layout_keyboard(bd, cz);
1099
1100         else if (e_illume_border_is_home(bd))
1101           _policy_zone_layout_home_single(bd, cz);
1102
1103         else if ((bd->fullscreen) || (bd->need_fullscreen))
1104           _policy_zone_layout_fullscreen(bd);
1105
1106         else if (e_illume_border_is_splash(bd))
1107           _policy_zone_layout_splash(bd, cz);
1108
1109         else if (_policy_border_is_dialog(bd))
1110           _policy_zone_layout_dialog(bd, cz);
1111
1112         else if (e_illume_border_is_conformant(bd))
1113           _policy_zone_layout_conformant_single(bd, cz);
1114
1115         else if (e_illume_border_is_fixed_size(bd))
1116           _policy_zone_layout_dialog(bd, cz);
1117
1118         else if (bd->internal && bd->client.icccm.class &&
1119                  (!strcmp(bd->client.icccm.class, "everything-window")))
1120           {
1121              if (bd->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_ON)
1122                _policy_zone_layout_app_single(bd, cz);
1123              /* else
1124               *   _policy_zone_layout_app_dual_left(bd, cz, EINA_TRUE); */
1125              if (bd->layer != POL_ACTIVATE_LAYER)
1126                e_border_layer_set(bd, POL_ACTIVATE_LAYER);
1127              
1128              /* if (bd->layer != POL_SPLASH_LAYER)
1129               *   e_border_layer_set(bd, POL_SPLASH_LAYER); */
1130           }
1131         else if (bd->client.e.state.centered)
1132           _policy_zone_layout_dialog(bd, cz);
1133         else if (!cz->mode.dual)
1134           _policy_zone_layout_app_single(bd, cz);
1135         else
1136           {
1137              if (cz->mode.side == 0)
1138                {
1139                   int ty;
1140
1141                   /* grab the indicator position so we can tell if it
1142                    * is in a custom position or not (user dragged it) */
1143                   e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1144                   if (ty <= bd->zone->y)
1145                     _policy_zone_layout_app_dual_top(bd, cz);
1146                   else
1147                     _policy_zone_layout_app_dual_custom(bd, cz);
1148                }
1149              else
1150                _policy_zone_layout_app_dual_left(bd, cz, EINA_FALSE);
1151           }
1152      }
1153 }
1154
1155 void
1156 _policy_zone_move_resize(E_Zone *zone)
1157 {
1158    Eina_List *l;
1159    E_Border *bd;
1160
1161    if (!zone) return;
1162
1163    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1164      {
1165         if (bd->zone != zone) continue;
1166
1167         bd->changes.pos = 1;
1168         bd->changed = 1;
1169      }
1170 }
1171
1172 void
1173 _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
1174 {
1175    E_Illume_Config_Zone *cz;
1176    /* Eina_List *homes = NULL; */
1177    E_Border *bd;
1178    /* int count; */
1179
1180    if (!zone) return;
1181
1182    cz = e_illume_zone_config_get(zone->num);
1183
1184    if (mode == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE)
1185      cz->mode.dual = 0;
1186    else
1187      {
1188         cz->mode.dual = 1;
1189         if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP)
1190           cz->mode.side = 0;
1191         else if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT)
1192           cz->mode.side = 1;
1193      }
1194    e_config_save_queue();
1195
1196    /* lock indicator window from dragging if we need to */
1197    bd = e_illume_border_indicator_get(zone);
1198    if (bd)
1199      {
1200         /* only dual-top mode can drag */
1201         if ((cz->mode.dual == 1) && (cz->mode.side == 0))
1202           {
1203              /* only set locked if we need to */
1204              if (bd->client.illume.drag.locked != 0)
1205                ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
1206           }
1207         else
1208           {
1209              /* only set locked if we need to */
1210              if (bd->client.illume.drag.locked != 1)
1211                ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
1212           }
1213      }
1214 #if 0 /* split home window? wtf?! go home! */
1215    if (!(homes = e_illume_border_home_borders_get(zone))) return;
1216
1217    count = eina_list_count(homes);
1218
1219    /* create a new home window (if needed) for dual mode */
1220    if (cz->mode.dual == 1)
1221      {
1222         if (count < 2)
1223           ecore_x_e_illume_home_new_send(zone->black_win);
1224      }
1225    else if (cz->mode.dual == 0)
1226      {
1227         /* if we went to single mode, delete any extra home windows */
1228         if (count >= 2)
1229           {
1230              E_Border *home;
1231
1232              /* try to get a home window on this zone and remove it */
1233              if ((home = e_illume_border_home_get(zone)))
1234                ecore_x_e_illume_home_del_send(home->client.win);
1235           }
1236      }
1237 #endif
1238
1239    _policy_zone_layout_update(zone);
1240 }
1241
1242 void
1243 _policy_zone_close(E_Zone *zone)
1244 {
1245    E_Border *bd;
1246
1247    if (!zone) return;
1248
1249    if (!(bd = e_border_focused_get())) return;
1250
1251    if (bd->zone != zone) return;
1252
1253    /* close this border */
1254    e_border_act_close_begin(bd);
1255 }
1256
1257 void
1258 _policy_drag_start(E_Border *bd)
1259 {
1260    if (!bd) return;
1261
1262    if (bd->stolen) return;
1263
1264    ecore_x_e_illume_drag_set(bd->client.win, 1);
1265    ecore_x_e_illume_drag_set(bd->zone->black_win, 1);
1266 }
1267
1268 void
1269 _policy_drag_end(E_Border *bd)
1270 {
1271    //   printf("Drag end\n");
1272
1273    if (!bd) return;
1274
1275    if (bd->stolen) return;
1276
1277    /* set property on this border to say we are done dragging */
1278    ecore_x_e_illume_drag_set(bd->client.win, 0);
1279
1280    /* set property on zone window that a drag is finished */
1281    ecore_x_e_illume_drag_set(bd->zone->black_win, 0);
1282 }
1283
1284 void
1285 _policy_focus_back(E_Zone *zone)
1286 {
1287    Eina_List *l, *fl = NULL;
1288    E_Border *bd, *fbd;
1289
1290    if (!zone) return;
1291    if (eina_list_count(_pol_focus_stack) < 1) return;
1292
1293    //   printf("Focus back\n");
1294
1295    EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, bd)
1296      {
1297         if (bd->zone != zone) continue;
1298         fl = eina_list_append(fl, bd);
1299      }
1300
1301    if (!(fbd = e_border_focused_get())) return;
1302    if (fbd->parent) return;
1303
1304    EINA_LIST_REVERSE_FOREACH(fl, l, bd)
1305      {
1306         if ((fbd) && (bd == fbd))
1307           {
1308              E_Border *b;
1309
1310              if ((l->next) && (b = l->next->data))
1311                {
1312                   _policy_border_set_focus(b);
1313                   break;
1314                }
1315              else
1316                {
1317                   /* we've reached the end of the list. Set focus to first */
1318                   if ((b = eina_list_nth(fl, 0)))
1319                     {
1320                        _policy_border_set_focus(b);
1321                        break;
1322                     }
1323                }
1324           }
1325      }
1326    eina_list_free(fl);
1327 }
1328
1329 void
1330 _policy_focus_forward(E_Zone *zone)
1331 {
1332    Eina_List *l, *fl = NULL;
1333    E_Border *bd, *fbd;
1334
1335    if (!zone) return;
1336    if (eina_list_count(_pol_focus_stack) < 1) return;
1337
1338    //   printf("Focus forward\n");
1339
1340    EINA_LIST_FOREACH(_pol_focus_stack, l, bd)
1341      {
1342         if (bd->zone != zone) continue;
1343         fl = eina_list_append(fl, bd);
1344      }
1345
1346    if (!(fbd = e_border_focused_get())) return;
1347    if (fbd->parent) return;
1348
1349    EINA_LIST_FOREACH(fl, l, bd)
1350      {
1351         if ((fbd) && (bd == fbd))
1352           {
1353              E_Border *b;
1354
1355              if ((l->next) && (b = l->next->data))
1356                {
1357                   _policy_border_set_focus(b);
1358                   break;
1359                }
1360              else
1361                {
1362                   /* we've reached the end of the list. Set focus to first */
1363                   if ((b = eina_list_nth(fl, 0)))
1364                     {
1365                        _policy_border_set_focus(b);
1366                        break;
1367                     }
1368                }
1369           }
1370      }
1371    eina_list_free(fl);
1372 }
1373
1374 void
1375 _policy_focus_home(E_Zone *zone)
1376 {
1377    E_Border *bd;
1378
1379    if (!zone) return;
1380    if (!(bd = e_illume_border_home_get(zone))) return;
1381    _policy_border_set_focus(bd);
1382 }
1383
1384 void
1385 _policy_property_change(Ecore_X_Event_Window_Property *event)
1386 {
1387    if (event->atom == ECORE_X_ATOM_NET_WM_STATE)
1388      {
1389         E_Border *bd, *ind;
1390
1391         if (!(bd = e_border_find_by_client_window(event->win))) return;
1392
1393         /* not interested in stolen or invisible borders */
1394         if ((bd->stolen) || (!bd->visible)) return;
1395
1396         /* make sure the border has a name or class */
1397         /* NB: this check is here because some E borders get State Changes
1398          * but do not have a name/class associated with them. Not entirely sure
1399          * which ones they are, but I would guess Managers, Containers, or Zones.
1400          * At any rate, we're not interested in those types of borders */
1401         if ((!bd->client.icccm.name) || (!bd->client.icccm.class)) return;
1402
1403         /* NB: If we have reached this point, then it should be a fullscreen
1404          * border that has toggled fullscreen on/off */
1405
1406         /* try to get the Indicator on this zone */
1407         if (!(ind = e_illume_border_indicator_get(bd->zone))) return;
1408
1409         /* if we are fullscreen, hide the indicator...else we show it */
1410         /* NB: we could use the e_illume_border_is_fullscreen function here
1411          * but we save ourselves a function call this way */
1412         if ((bd->fullscreen) || (bd->need_fullscreen))
1413           {
1414              if (ind->visible)
1415                {
1416                   e_illume_border_hide(ind);
1417                   _policy_zone_layout_update(bd->zone);
1418                }
1419           }
1420         else
1421           {
1422              if (!ind->visible)
1423                {
1424                   e_illume_border_show(ind);
1425                   _policy_zone_layout_update(bd->zone);
1426                }
1427           }
1428      }
1429    else if (event->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
1430      {
1431         Eina_List *l;
1432         E_Zone *zone;
1433         E_Border *bd;
1434         int x, y, w, h;
1435
1436         if (!(zone = e_util_zone_window_find(event->win))) return;
1437
1438         if (!(bd = e_illume_border_indicator_get(zone))) return;
1439         x = bd->x;
1440         y = bd->y;
1441         w = bd->w;
1442         h = bd->h;
1443
1444         EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1445           {
1446              if (bd->zone != zone) continue;
1447              if (!e_illume_border_is_conformant(bd)) continue;
1448              /* set indicator geometry on conformant window */
1449              /* NB: This is needed so that conformant apps get told about
1450               * the indicator size/position...else they have no way of
1451               * knowing that the geometry has been updated */
1452              ecore_x_e_illume_indicator_geometry_set(bd->client.win, x, y, w, h);
1453           }
1454      }
1455    else if (event->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
1456      {
1457         Eina_List *l;
1458         E_Zone *zone;
1459         E_Border *bd;
1460         int x, y, w, h;
1461
1462         if (!(zone = e_util_zone_window_find(event->win))) return;
1463
1464         if (!(bd = e_illume_border_softkey_get(zone))) return;
1465         x = bd->x;
1466         y = bd->y;
1467         w = bd->w;
1468         h = bd->h;
1469
1470         EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1471           {
1472              if (bd->zone != zone) continue;
1473              if (!e_illume_border_is_conformant(bd)) continue;
1474              /* set softkey geometry on conformant window */
1475              /* NB: This is needed so that conformant apps get told about
1476               * the softkey size/position...else they have no way of
1477               * knowing that the geometry has been updated */
1478              ecore_x_e_illume_softkey_geometry_set(bd->client.win, x, y, w, h);
1479           }
1480      }
1481    else if (event->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
1482      {
1483         Eina_List *l;
1484         E_Zone *zone;
1485         E_Illume_Keyboard *kbd;
1486         E_Border *bd;
1487         int x, y, w, h;
1488
1489         if (!(zone = e_util_zone_window_find(event->win))) return;
1490
1491         if (!(kbd = e_illume_keyboard_get())) return;
1492         if (!kbd->border) return;
1493
1494         x = kbd->border->x;
1495         w = kbd->border->w;
1496         h = kbd->border->h;
1497
1498         /* adjust Y for keyboard visibility because keyboard uses fx_offset */
1499         y = 0;
1500         if (kbd->border->fx.y <= 0) y = kbd->border->y;
1501
1502         /* look for conformant borders */
1503         EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1504           {
1505              if (bd->zone != zone) continue;
1506              if (!e_illume_border_is_conformant(bd)) continue;
1507              /* set keyboard geometry on conformant window */
1508              /* NB: This is needed so that conformant apps get told about
1509               * the keyboard size/position...else they have no way of
1510               * knowing that the geometry has been updated */
1511              ecore_x_e_illume_keyboard_geometry_set(bd->client.win, x, y, w, h);
1512           }
1513      }
1514    else if (event->atom == ATM_ENLIGHTENMENT_SCALE)
1515      {
1516         Eina_List *ml;
1517         E_Manager *man;
1518
1519         EINA_LIST_FOREACH(e_manager_list(), ml, man)
1520           {
1521              Eina_List *cl;
1522              E_Container *con;
1523
1524              if (event->win != man->root) continue;
1525              EINA_LIST_FOREACH(man->containers, cl, con)
1526                {
1527                   Eina_List *zl;
1528                   E_Zone *zone;
1529
1530                   EINA_LIST_FOREACH(con->zones, zl, zone)
1531                     _policy_zone_layout_update(zone);
1532                }
1533           }
1534      }
1535 }