Merge from TIZEN 2.3
[platform/core/uifw/e17.git] / src / bin / e_manager.c
1 #include "e.h"
2
3 /* local subsystem functions */
4 static void _e_manager_free(E_Manager *man);
5
6 static Eina_Bool _e_manager_cb_window_show_request(void *data, int ev_type, void *ev);
7 static Eina_Bool _e_manager_cb_window_configure(void *data, int ev_type, void *ev);
8 static Eina_Bool _e_manager_cb_key_up(void *data, int ev_type, void *ev);
9 static Eina_Bool _e_manager_cb_key_down(void *data, int ev_type, void *ev);
10 static Eina_Bool _e_manager_cb_frame_extents_request(void *data, int ev_type, void *ev);
11 static Eina_Bool _e_manager_cb_ping(void *data, int ev_type, void *ev);
12 static Eina_Bool _e_manager_cb_screensaver_notify(void *data, int ev_type, void *ev);
13 static Eina_Bool _e_manager_cb_client_message(void *data, int ev_type, void *ev);
14
15 static Eina_Bool _e_manager_frame_extents_free_cb(const Eina_Hash *hash __UNUSED__,
16                                                   const void *key __UNUSED__,
17                                                   void *data, void *fdata __UNUSED__);
18 static E_Manager *_e_manager_get_for_root(Ecore_X_Window root);
19 static Eina_Bool _e_manager_clear_timer(void *data);
20 #if 0 /* use later - maybe */
21 static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev);
22 static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev);
23 static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev);
24 static int _e_manager_cb_window_create(void *data, int ev_type, void *ev);
25 static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev);
26 static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev);
27 static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev);
28 static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev);
29 static int _e_manager_cb_window_property(void *data, int ev_type, void *ev);
30 static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev);
31 static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev);
32 static int _e_manager_cb_client_message(void *data, int ev_type, void *ev);
33 #endif
34
35 /* local subsystem globals */
36
37 typedef struct _Frame_Extents Frame_Extents;
38
39 struct _Frame_Extents
40 {
41    int l, r, t, b;
42 };
43
44 static Eina_List *managers = NULL;
45 static Eina_Hash *frame_extents = NULL;
46 static Ecore_Timer *timer_post_screensaver_lock = NULL;
47
48 /* externally accessible functions */
49 EINTERN int
50 e_manager_init(void)
51 {
52    ecore_x_screensaver_event_listen_set(1);
53    frame_extents = eina_hash_string_superfast_new(NULL);
54    return 1;
55 }
56
57 EINTERN int
58 e_manager_shutdown(void)
59 {
60    E_FREE_LIST(managers, e_object_del);
61
62    if (frame_extents)
63      {
64         eina_hash_foreach(frame_extents, _e_manager_frame_extents_free_cb, NULL);
65         eina_hash_free(frame_extents);
66         frame_extents = NULL;
67      }
68
69    if (timer_post_screensaver_lock)
70      {
71         ecore_timer_del(timer_post_screensaver_lock);
72         timer_post_screensaver_lock = NULL;
73      }
74
75    return 1;
76 }
77
78 EAPI Eina_List *
79 e_manager_list(void)
80 {
81    return managers;
82 }
83
84 EAPI E_Manager *
85 e_manager_new(Ecore_X_Window root, int num)
86 {
87    E_Manager *man;
88
89    if (!ecore_x_window_manage(root)) return NULL;
90    man = E_OBJECT_ALLOC(E_Manager, E_MANAGER_TYPE, _e_manager_free);
91    if (!man) return NULL;
92    managers = eina_list_append(managers, man);
93    man->root = root;
94    man->num = num;
95    ecore_x_window_size_get(man->root, &(man->w), &(man->h));
96    man->win = man->root;
97
98    man->handlers =
99      eina_list_append(man->handlers,
100                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST,
101                                               _e_manager_cb_window_show_request,
102                                               man));
103    man->handlers =
104      eina_list_append(man->handlers,
105                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE,
106                                               _e_manager_cb_window_configure,
107                                               man));
108    man->handlers =
109      eina_list_append(man->handlers,
110                       ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
111                                               _e_manager_cb_key_down,
112                                               man));
113    man->handlers =
114      eina_list_append(man->handlers,
115                       ecore_event_handler_add(ECORE_EVENT_KEY_UP,
116                                               _e_manager_cb_key_up,
117                                               man));
118    man->handlers =
119      eina_list_append(man->handlers,
120                       ecore_event_handler_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST,
121                                               _e_manager_cb_frame_extents_request,
122                                               man));
123    man->handlers =
124      eina_list_append(man->handlers,
125                       ecore_event_handler_add(ECORE_X_EVENT_PING,
126                                               _e_manager_cb_ping,
127                                               man));
128    man->handlers =
129      eina_list_append(man->handlers,
130                       ecore_event_handler_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY,
131                                               _e_manager_cb_screensaver_notify,
132                                               man));
133    man->handlers =
134      eina_list_append(man->handlers,
135                       ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
136                                               _e_manager_cb_client_message,
137                                               man));
138
139    man->pointer = e_pointer_window_new(man->root, 1);
140
141    ecore_x_window_background_color_set(man->root, 0, 0, 0);
142
143    man->clear_timer = ecore_timer_add(10.0, _e_manager_clear_timer, man);
144    return man;
145 }
146
147 EAPI void
148 e_manager_manage_windows(E_Manager *man)
149 {
150    Ecore_X_Window *windows;
151    int wnum;
152
153    /* a manager is designated for each root. lets get all the windows in
154       the managers root */
155    windows = ecore_x_window_children_get(man->root, &wnum);
156    if (windows)
157      {
158         int i;
159         const char *atom_names[] =
160           {
161              "_XEMBED_INFO",
162                "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
163                "KWM_DOCKWINDOW"
164           };
165         Ecore_X_Atom atoms[3];
166         Ecore_X_Atom atom_xmbed, atom_kde_netwm_systray, atom_kwm_dockwindow;
167         unsigned char *data = NULL;
168         int count;
169
170         ecore_x_atoms_get(atom_names, 3, atoms);
171         atom_xmbed = atoms[0];
172         atom_kde_netwm_systray = atoms[1];
173         atom_kwm_dockwindow = atoms[2];
174         for (i = 0; i < wnum; i++)
175           {
176              Ecore_X_Window_Attributes att;
177              unsigned int ret_val, deskxy[2];
178              int ret;
179
180              if (e_border_find_by_client_window(windows[i]))
181                continue;
182              ecore_x_window_attributes_get(windows[i], &att);
183              if ((att.override) || (att.input_only))
184                {
185                   if (att.override)
186                     {
187                        char *wname = NULL, *wclass = NULL;
188
189                        ecore_x_icccm_name_class_get(windows[i],
190                                                     &wname, &wclass);
191                        if ((wname) && (wclass) &&
192                            (!strcmp(wname, "E")) &&
193                            (!strcmp(wclass, "Init_Window")))
194                          {
195                             free(wname);
196                             free(wclass);
197                             man->initwin = windows[i];
198                          }
199                        else
200                          {
201                             if (wname) free(wname);
202                             if (wclass) free(wclass);
203                             continue;
204                          }
205                     }
206                   else
207                     continue;
208                }
209              /* XXX manage xembed windows as long as they are not override_redirect..
210               * if (!ecore_x_window_prop_property_get(windows[i],
211               *                                    atom_xmbed,
212               *                                    atom_xmbed, 32,
213               *                                    &data, &count))
214               *   data = NULL;
215               * if (!data) */
216                {
217                   if (!ecore_x_window_prop_property_get(windows[i],
218                                                         atom_kde_netwm_systray,
219                                                         atom_xmbed, 32,
220                                                         &data, &count))
221                     data = NULL;
222                }
223              if (!data)
224                {
225                   if (!ecore_x_window_prop_property_get(windows[i],
226                                                         atom_kwm_dockwindow,
227                                                         atom_kwm_dockwindow, 32,
228                                                         &data, &count))
229                     data = NULL;
230                }
231              if (data)
232                {
233                   free(data);
234                   data = NULL;
235                   continue;
236                }
237              ret = ecore_x_window_prop_card32_get(windows[i],
238                                                   E_ATOM_MANAGED,
239                                                   &ret_val, 1);
240
241              /* we have seen this window before */
242              if ((ret > -1) && (ret_val == 1))
243                {
244                   E_Container  *con = NULL;
245                   E_Zone       *zone = NULL;
246                   E_Desk       *desk = NULL;
247                   E_Border     *bd = NULL;
248                   unsigned int  id;
249                   char *path;
250                   Efreet_Desktop *desktop = NULL;
251
252                   /* get all information from window before it is
253                    * reset by e_border_new */
254                   ret = ecore_x_window_prop_card32_get(windows[i],
255                                                        E_ATOM_CONTAINER,
256                                                        &id, 1);
257                   if (ret == 1)
258                     con = e_container_number_get(man, id);
259                   if (!con)
260                     con = e_container_current_get(man);
261
262                   ret = ecore_x_window_prop_card32_get(windows[i],
263                                                        E_ATOM_ZONE,
264                                                        &id, 1);
265                   if (ret == 1)
266                     zone = e_container_zone_number_get(con, id);
267                   if (!zone)
268                     zone = e_zone_current_get(con);
269                   ret = ecore_x_window_prop_card32_get(windows[i],
270                                                        E_ATOM_DESK,
271                                                        deskxy, 2);
272                   if (ret == 2)
273                     desk = e_desk_at_xy_get(zone,
274                                             deskxy[0],
275                                             deskxy[1]);
276
277                   path = ecore_x_window_prop_string_get(windows[i],
278                                                         E_ATOM_DESKTOP_FILE);
279                   if (path)
280                     {
281                        desktop = efreet_desktop_get(path);
282                        free(path);
283                     }
284
285                     {
286                        bd = e_border_new(con, windows[i], 1, 0);
287                        if (bd)
288                          {
289                             bd->ignore_first_unmap = 1;
290                             /* FIXME:
291                              * It's enough to set the desk, the zone will
292                              * be set according to the desk */
293 //                          if (zone) e_border_zone_set(bd, zone);
294                             if (desk) e_border_desk_set(bd, desk);
295                             bd->desktop = desktop;
296                          }
297                     }
298                }
299              else if ((att.visible) && (!att.override) &&
300                       (!att.input_only))
301                {
302                   /* We have not seen this window, and X tells us it
303                    * should be seen */
304                   E_Container *con;
305                   E_Border *bd;
306
307                   con = e_container_current_get(man);
308                   bd = e_border_new(con, windows[i], 1, 0);
309                   if (bd)
310                     {
311                        bd->ignore_first_unmap = 1;
312                        e_border_show(bd);
313                     }
314                }
315           }
316         free(windows);
317      }
318 }
319
320 EAPI void
321 e_manager_show(E_Manager *man)
322 {
323    Eina_List *l;
324    E_Container *con;
325
326    E_OBJECT_CHECK(man);
327    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
328    if (man->visible) return;
329    EINA_LIST_FOREACH(man->containers, l, con)
330      {
331         e_container_show(con);
332      }
333    if (man->root != man->win)
334      {
335         Ecore_X_Window mwin;
336
337         mwin = e_menu_grab_window_get();
338         if (!mwin) mwin = man->initwin;
339         if (!mwin)
340           ecore_x_window_raise(man->win);
341         else
342           ecore_x_window_configure(man->win,
343                                    ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
344                                    ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
345                                    0, 0, 0, 0, 0,
346                                    mwin, ECORE_X_WINDOW_STACK_BELOW);
347         ecore_x_window_show(man->win);
348      }
349    man->visible = 1;
350 }
351
352 EAPI void
353 e_manager_hide(E_Manager *man)
354 {
355    Eina_List *l;
356    E_Container *con;
357
358    E_OBJECT_CHECK(man);
359    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
360    if (!man->visible) return;
361    EINA_LIST_FOREACH(man->containers, l, con)
362      {
363         e_container_hide(con);
364      }
365    if (man->root != man->win)
366      ecore_x_window_hide(man->win);
367    man->visible = 0;
368 }
369
370 EAPI void
371 e_manager_move(E_Manager *man, int x, int y)
372 {
373    E_OBJECT_CHECK(man);
374    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
375    if ((x == man->x) && (y == man->y)) return;
376    if (man->root != man->win)
377      {
378         man->x = x;
379         man->y = y;
380         ecore_x_window_move(man->win, man->x, man->y);
381      }
382 }
383
384 EAPI void
385 e_manager_resize(E_Manager *man, int w, int h)
386 {
387    Eina_List *l;
388    E_Container *con;
389
390    E_OBJECT_CHECK(man);
391    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
392    man->w = w;
393    man->h = h;
394    if (man->root != man->win)
395      ecore_x_window_resize(man->win, man->w, man->h);
396
397    EINA_LIST_FOREACH(man->containers, l, con)
398      {
399         e_container_resize(con, man->w, man->h);
400      }
401
402    ecore_x_netwm_desk_size_set(man->root, man->w, man->h);
403 }
404
405 EAPI void
406 e_manager_move_resize(E_Manager *man, int x, int y, int w, int h)
407 {
408    Eina_List *l;
409    E_Container *con;
410
411    E_OBJECT_CHECK(man);
412    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
413    if (man->root != man->win)
414      {
415         man->x = x;
416         man->y = y;
417      }
418    man->w = w;
419    man->h = h;
420    ecore_x_window_move_resize(man->win, man->x, man->y, man->w, man->h);
421
422    EINA_LIST_FOREACH(man->containers, l, con)
423      {
424         e_container_resize(con, man->w, man->h);
425      }
426 }
427
428 EAPI void
429 e_manager_raise(E_Manager *man)
430 {
431    E_OBJECT_CHECK(man);
432    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
433    if (man->root != man->win)
434      {
435         Ecore_X_Window mwin;
436
437         mwin = e_menu_grab_window_get();
438         if (!mwin) mwin = man->initwin;
439         if (!mwin)
440           ecore_x_window_raise(man->win);
441         else
442           ecore_x_window_configure(man->win,
443                                    ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
444                                    ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
445                                    0, 0, 0, 0, 0,
446                                    mwin, ECORE_X_WINDOW_STACK_BELOW);
447      }
448 }
449
450 EAPI void
451 e_manager_lower(E_Manager *man)
452 {
453    E_OBJECT_CHECK(man);
454    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
455    if (man->root != man->win)
456      ecore_x_window_lower(man->win);
457 }
458
459 EAPI E_Manager *
460 e_manager_current_get(void)
461 {
462    Eina_List *l;
463    E_Manager *man;
464    int x, y;
465
466    if (!managers) return NULL;
467    EINA_LIST_FOREACH(managers, l, man)
468      {
469         ecore_x_pointer_xy_get(man->win, &x, &y);
470         if (x == -1 && y == -1)
471           continue;
472         if (E_INSIDE(x, y, man->x, man->y, man->w, man->h))
473           return man;
474      }
475    return eina_list_data_get(managers);
476 }
477
478 EAPI E_Manager *
479 e_manager_number_get(int num)
480 {
481    Eina_List *l;
482    E_Manager *man;
483
484    if (!managers) return NULL;
485    EINA_LIST_FOREACH(managers, l, man)
486      {
487         if (man->num == num)
488           return man;
489      }
490    return NULL;
491 }
492
493 EAPI void
494 e_managers_keys_grab(void)
495 {
496    Eina_List *l;
497    E_Manager *man;
498
499    EINA_LIST_FOREACH(managers, l, man)
500      {
501         e_bindings_key_grab(E_BINDING_CONTEXT_ANY, man->root);
502      }
503 }
504
505 EAPI void
506 e_managers_keys_ungrab(void)
507 {
508    Eina_List *l;
509    E_Manager *man;
510
511    EINA_LIST_FOREACH(managers, l, man)
512      {
513         e_bindings_key_ungrab(E_BINDING_CONTEXT_ANY, man->root);
514      }
515 }
516
517 EAPI void
518 e_manager_comp_set(E_Manager *man, E_Manager_Comp *comp)
519 {
520    E_OBJECT_CHECK(man);
521    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
522    man->comp = comp;
523    e_msg_send("comp.manager", "change.comp", // name + info
524               0, // val
525               E_OBJECT(man), // obj
526               NULL, // msgdata
527               NULL, NULL); // afterfunc + afterdata
528 }
529
530 EAPI Evas *
531 e_manager_comp_evas_get(E_Manager *man)
532 {
533    E_OBJECT_CHECK_RETURN(man, NULL);
534    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
535    if (!man->comp) return NULL;
536    if (!man->comp->func.evas_get) return NULL;
537    return man->comp->func.evas_get(man->comp->data, man);
538 }
539
540 EAPI void
541 e_manager_comp_evas_update(E_Manager *man)
542 {
543    E_OBJECT_CHECK(man);
544    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
545    if (!man->comp) return;
546    if (!man->comp->func.update) return;
547    return man->comp->func.update(man->comp->data, man);
548 }
549
550 EAPI const Eina_List *
551 e_manager_comp_src_list(E_Manager *man)
552 {
553    E_OBJECT_CHECK_RETURN(man, NULL);
554    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
555    if (!man->comp) return NULL;
556    if (!man->comp->func.src_list_get) return NULL;
557    return man->comp->func.src_list_get(man->comp->data, man);
558 }
559
560 EAPI E_Manager_Comp_Source*
561 e_manager_comp_border_src_get(E_Manager *man, Ecore_X_Window win)
562 {
563    E_OBJECT_CHECK_RETURN(man, NULL);
564    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
565    if (!man->comp) return NULL;
566    if (!man->comp->func.border_src_get) return NULL;
567    return man->comp->func.border_src_get(man->comp->data, man, win);
568 }
569
570 EAPI E_Manager_Comp_Source*
571 e_manager_comp_src_get(E_Manager *man, Ecore_X_Window win)
572 {
573    E_OBJECT_CHECK_RETURN(man, NULL);
574    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
575    if (!man->comp) return NULL;
576    if (!man->comp->func.src_get) return NULL;
577    return man->comp->func.src_get(man->comp->data, man, win);
578 }
579
580 EAPI Evas_Object *
581 e_manager_comp_src_image_get(E_Manager *man, E_Manager_Comp_Source *src)
582 {
583    E_OBJECT_CHECK_RETURN(man, NULL);
584    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
585    if (!man->comp) return NULL;
586    if (!man->comp->func.src_image_get) return NULL;
587    return man->comp->func.src_image_get(man->comp->data, man, src);
588 }
589
590 EAPI Evas_Object *
591 e_manager_comp_src_shadow_get(E_Manager *man, E_Manager_Comp_Source *src)
592 {
593    E_OBJECT_CHECK_RETURN(man, NULL);
594    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
595    if (!man->comp) return NULL;
596    if (!man->comp->func.src_shadow_get) return NULL;
597    return man->comp->func.src_shadow_get(man->comp->data, man, src);
598 }
599
600 EAPI Evas_Object *
601 e_manager_comp_src_image_mirror_add(E_Manager *man, E_Manager_Comp_Source *src)
602 {
603    E_OBJECT_CHECK_RETURN(man, NULL);
604    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
605    if (!man->comp) return NULL;
606    if (!man->comp->func.src_image_mirror_add) return NULL;
607    return man->comp->func.src_image_mirror_add(man->comp->data, man, src);
608 }
609
610 EAPI Eina_Bool
611 e_manager_comp_src_visible_get(E_Manager *man, E_Manager_Comp_Source *src)
612 {
613    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
614    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
615    if (!man->comp) return EINA_FALSE;
616    if (!man->comp->func.src_visible_get) return EINA_FALSE;
617    return man->comp->func.src_visible_get(man->comp->data, man, src);
618 }
619
620 EAPI void
621 e_manager_comp_src_hidden_set(E_Manager *man, E_Manager_Comp_Source *src, Eina_Bool hidden)
622 {
623    E_OBJECT_CHECK(man);
624    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
625    if (!man->comp) return;
626    if (!man->comp->func.src_hidden_set) return;
627    return man->comp->func.src_hidden_set(man->comp->data, man, src, hidden);
628 }
629
630 EAPI Eina_Bool
631 e_manager_comp_src_hidden_get(E_Manager *man, E_Manager_Comp_Source *src)
632 {
633    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
634    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
635    if (!man->comp) return EINA_FALSE;
636    if (!man->comp->func.src_hidden_get) return EINA_FALSE;
637    return man->comp->func.src_hidden_get(man->comp->data, man, src);
638 }
639
640 EAPI Ecore_X_Window
641 e_manager_comp_src_window_get(E_Manager *man, E_Manager_Comp_Source *src)
642 {
643    E_OBJECT_CHECK_RETURN(man, 0);
644    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, 0);
645    if (!man->comp) return 0;
646    if (!man->comp->func.src_window_get) return 0;
647    return man->comp->func.src_window_get(man->comp->data, man, src);
648 }
649
650 EAPI E_Popup *
651 e_manager_comp_src_popup_get(E_Manager *man, E_Manager_Comp_Source *src)
652 {
653    E_OBJECT_CHECK_RETURN(man, NULL);
654    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
655    if (!man->comp) return NULL;
656    if (!man->comp->func.src_popup_get) return NULL;
657    return man->comp->func.src_popup_get(man->comp->data, man, src);
658 }
659
660 EAPI E_Border *
661 e_manager_comp_src_border_get(E_Manager *man, E_Manager_Comp_Source *src)
662 {
663    E_OBJECT_CHECK_RETURN(man, NULL);
664    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
665    if (!man->comp) return NULL;
666    if (!man->comp->func.src_border_get) return NULL;
667    return man->comp->func.src_border_get(man->comp->data, man, src);
668 }
669
670 #ifdef _F_COMP_SCREEN_LOCK_
671 EAPI void
672 e_manager_comp_screen_lock(E_Manager *man)
673 {
674    E_OBJECT_CHECK(man);
675    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
676    if (!man->comp) return;
677    if (!man->comp->func.screen_lock) return;
678    ELB(ELBT_MNG, ">> SCREEN LOCK", 0);
679    return man->comp->func.screen_lock(man->comp->data, man);
680 }
681
682 EAPI void
683 e_manager_comp_screen_unlock(E_Manager *man)
684 {
685    E_OBJECT_CHECK(man);
686    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
687    if (!man->comp) return;
688    if (!man->comp->func.screen_unlock) return;
689    ELB(ELBT_MNG, "<< SCREEN UNLOCK", 0);
690    return man->comp->func.screen_unlock(man->comp->data, man);
691 }
692 #endif
693
694 #ifdef _F_COMP_INPUT_REGION_SET_
695 EAPI Eina_Bool
696 e_manager_comp_src_input_region_set(E_Manager *man, E_Manager_Comp_Source *src, int x, int y, int w, int h)
697 {
698    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
699    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
700    if (!man->comp) return EINA_FALSE;
701    if (!man->comp->func.src_input_region_set) return EINA_FALSE;
702    return man->comp->func.src_input_region_set(man->comp->data, man, src, x, y, w, h);
703 }
704
705 EAPI int
706 e_manager_comp_input_region_new(E_Manager *man)
707 {
708    E_OBJECT_CHECK_RETURN(man, 0);
709    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, 0);
710    if (!man->comp) return 0;
711    if (!man->comp->func.input_region_new) return 0;
712    return man->comp->func.input_region_new(man->comp->data, man);
713 }
714
715 EAPI Eina_Bool
716 e_manager_comp_input_region_set(E_Manager *man, int id, int x, int y, int w, int h)
717 {
718    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
719    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
720    if (id <= 0) return EINA_FALSE;
721    if (!man->comp) return EINA_FALSE;
722    if (!man->comp->func.input_region_set) return EINA_FALSE;
723    return man->comp->func.input_region_set(man->comp->data, man, id, x, y, w, h);
724 }
725
726 EAPI Eina_Bool
727 e_manager_comp_input_region_del(E_Manager *man, int id)
728 {
729    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
730    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
731    if (id <= 0) return EINA_FALSE;
732    if (!man->comp) return EINA_FALSE;
733    if (!man->comp->func.input_region_del) return EINA_FALSE;
734    return man->comp->func.input_region_del(man->comp->data, man, id);
735 }
736
737 EAPI int
738 e_manager_comp_input_region_id_new(E_Manager *man)
739 {
740    E_OBJECT_CHECK_RETURN(man, 0);
741    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, 0);
742    if (!man->comp) return 0;
743    if (!man->comp->func.input_region_new) return 0;
744    return man->comp->func.input_region_new(man->comp->data, man);
745 }
746
747 EAPI Eina_Bool
748 e_manager_comp_input_region_id_set(E_Manager *man, int id, int x, int y, int w, int h)
749 {
750    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
751    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
752    if (id <= 0) return EINA_FALSE;
753    if (!man->comp) return EINA_FALSE;
754    if (!man->comp->func.input_region_set) return EINA_FALSE;
755    return man->comp->func.input_region_set(man->comp->data, man, id, x, y, w, h);
756 }
757
758 EAPI Eina_Bool
759 e_manager_comp_input_region_id_del(E_Manager *man, int id)
760 {
761    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
762    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
763    if (id <= 0) return EINA_FALSE;
764    if (!man->comp) return EINA_FALSE;
765    if (!man->comp->func.input_region_del) return EINA_FALSE;
766    return man->comp->func.input_region_del(man->comp->data, man, id);
767 }
768 #endif
769
770 #ifdef _F_COMP_MOVE_LOCK_
771 EAPI Eina_Bool
772 e_manager_comp_src_move_lock(E_Manager *man, E_Manager_Comp_Source *src)
773 {
774    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
775    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
776    if (!man->comp) return EINA_FALSE;
777    if (!man->comp->func.src_move_lock) return EINA_FALSE;
778    return man->comp->func.src_move_lock(man->comp->data, man, src);
779 }
780
781 EAPI Eina_Bool
782 e_manager_comp_src_move_unlock(E_Manager *man, E_Manager_Comp_Source *src)
783 {
784    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
785    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
786    if (!man->comp) return EINA_FALSE;
787    if (!man->comp->func.src_move_unlock) return EINA_FALSE;
788    return man->comp->func.src_move_unlock(man->comp->data, man, src);
789 }
790 #endif
791
792 #ifdef _F_COMP_COMPOSITE_MODE_
793 EAPI void
794 e_manager_comp_composite_mode_set(E_Manager *man, E_Zone *zone, Eina_Bool set)
795 {
796    E_OBJECT_CHECK(man);
797    E_OBJECT_CHECK(zone);
798    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
799    E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
800    if (!man->comp) return;
801    if (!man->comp->func.composite_mode_set) return;
802    man->comp->func.composite_mode_set(man->comp->data, man, zone, set);
803 }
804
805 EAPI Eina_Bool
806 e_manager_comp_composite_mode_get(E_Manager *man, E_Zone *zone)
807 {
808    E_OBJECT_CHECK_RETURN(man, EINA_FALSE);
809    E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
810    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, EINA_FALSE);
811    E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
812    if (!man->comp) return EINA_FALSE;
813    if (!man->comp->func.composite_mode_get) return EINA_FALSE;
814    return man->comp->func.composite_mode_get(man->comp->data, man, zone);
815 }
816 #endif /* _F_COMP_COMPOSITE_MODE_ */
817
818 EAPI void
819 e_manager_comp_event_resize_send(E_Manager *man)
820 {
821    E_OBJECT_CHECK(man);
822    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
823    e_msg_send("comp.manager", "resize.comp", // name + info
824               0, // val
825               E_OBJECT(man), // obj
826               NULL, // msgdata
827               NULL, NULL); // afterfunc + afterdata
828 }
829
830 EAPI void
831 e_manager_comp_event_src_add_send(E_Manager *man, E_Manager_Comp_Source *src,
832                                   void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
833                                   void *data)
834 {
835    E_OBJECT_CHECK(man);
836    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
837    e_msg_send("comp.manager", "add.src", // name + info
838               0, // val
839               E_OBJECT(man), // obj
840               src, // msgdata
841               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
842 }
843
844 EAPI void
845 e_manager_comp_event_src_del_send(E_Manager *man, E_Manager_Comp_Source *src,
846                                   void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
847                                   void *data)
848 {
849    E_OBJECT_CHECK(man);
850    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
851    e_msg_send("comp.manager", "del.src", // name + info
852               0, // val
853               E_OBJECT(man), // obj
854               src, // msgdata
855               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
856 }
857
858 EAPI void
859 e_manager_comp_event_src_config_send(E_Manager *man, E_Manager_Comp_Source *src,
860                                      void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
861                                      void *data)
862 {
863    E_OBJECT_CHECK(man);
864    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
865    e_msg_send("comp.manager", "config.src", // name + info
866               0, // val
867               E_OBJECT(man), // obj
868               src, // msgdata
869               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
870 }
871
872 EAPI void
873 e_manager_comp_event_src_visibility_send(E_Manager *man, E_Manager_Comp_Source *src,
874                                          void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
875                                          void *data)
876 {
877    E_OBJECT_CHECK(man);
878    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
879    e_msg_send("comp.manager", "visibility.src", // name + info
880               0, // val
881               E_OBJECT(man), // obj
882               src, // msgdata
883               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
884 }
885
886 #ifdef _F_USE_EXTENDED_ICONIFY_
887 EAPI void
888 e_manager_comp_src_shadow_show(E_Manager *man, E_Manager_Comp_Source *src)
889 {
890    E_OBJECT_CHECK(man);
891    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
892    if (!man->comp) return;
893    if (!man->comp->func.src_shadow_show) return;
894    return man->comp->func.src_shadow_show(man->comp->data, man, src);
895 }
896
897 EAPI void
898 e_manager_comp_src_shadow_hide(E_Manager *man, E_Manager_Comp_Source *src)
899 {
900    E_OBJECT_CHECK(man);
901    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
902    if (!man->comp) return;
903    if (!man->comp->func.src_shadow_show) return;
904    return man->comp->func.src_shadow_hide(man->comp->data, man, src);
905 }
906 #endif
907
908 #ifdef _F_COMP_LAYER_
909 EAPI Evas_Object *
910 e_manager_comp_layer_get(E_Manager *man, E_Zone *zone, const char *name)
911 {
912    E_OBJECT_CHECK_RETURN(man, NULL);
913    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
914    E_OBJECT_CHECK_RETURN(zone, NULL);
915    E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
916    if (!name) return NULL;
917    if (!man->comp) return NULL;
918    if (!man->comp->func.layer_get) return NULL;
919    return man->comp->func.layer_get(man->comp->data, man, zone, name);
920 }
921 #endif
922
923 /* local subsystem functions */
924 static void
925 _e_manager_free(E_Manager *man)
926 {
927    Eina_List *l;
928
929    E_FREE_LIST(man->handlers, ecore_event_handler_del);
930    l = man->containers;
931    man->containers = NULL;
932    E_FREE_LIST(l, e_object_del);
933    if (man->root != man->win)
934      {
935         ecore_x_window_free(man->win);
936      }
937    if (man->pointer) e_object_del(E_OBJECT(man->pointer));
938    managers = eina_list_remove(managers, man);
939    if (man->clear_timer) ecore_timer_del(man->clear_timer);
940    free(man);
941 }
942
943 static Eina_Bool
944 _e_manager_cb_window_show_request(void *data, int ev_type __UNUSED__, void *ev)
945 {
946    E_Manager *man;
947    Ecore_X_Event_Window_Show_Request *e;
948
949    man = data;
950    e = ev;
951    if (e_stolen_win_get(e->win)) return 1;
952    if (ecore_x_window_parent_get(e->win) != man->root)
953      return ECORE_CALLBACK_PASS_ON;  /* try other handlers for this */
954
955      {
956         E_Container *con;
957         E_Border *bd;
958
959         con = e_container_current_get(man);
960         if (!e_border_find_by_client_window(e->win))
961           {
962              bd = e_border_new(con, e->win, 0, 0);
963              if (!bd)
964                {
965                   /* the wm shows only valid input_only window.
966                    * it doesn't need to deal with invalid window and
967                    * override_redirect window.
968                    */
969                   Ecore_X_Window_Attributes att;
970                   if ((ecore_x_window_attributes_get(e->win, &att)) &&
971                       (!att.override))
972                     {
973                        ecore_x_window_show(e->win);
974                     }
975                   else
976                     {
977                        ELB(ELBT_MNG, "show request of invalid win", e->win);
978                     }
979                }
980           }
981      }
982    return ECORE_CALLBACK_PASS_ON;
983 }
984
985 static Eina_Bool
986 _e_manager_cb_window_configure(void *data, int ev_type __UNUSED__, void *ev)
987 {
988    E_Manager *man;
989    Ecore_X_Event_Window_Configure *e;
990
991    man = data;
992    e = ev;
993    if (e->win != man->root) return ECORE_CALLBACK_PASS_ON;
994    if ((man->w != e->w) || (man->h != e->h))
995      e_manager_resize(man, e->w, e->h);
996    return ECORE_CALLBACK_PASS_ON;
997 }
998
999 static Eina_Bool
1000 _e_manager_cb_key_down(void *data, int ev_type __UNUSED__, void *ev)
1001 {
1002    E_Manager *man;
1003    Ecore_Event_Key *e;
1004
1005    man = data;
1006    e = ev;
1007
1008    if (e->event_window != man->root) return ECORE_CALLBACK_PASS_ON;
1009    if (e->root_window != man->root) man = _e_manager_get_for_root(e->root_window);
1010    if (e_bindings_key_down_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev))
1011      return ECORE_CALLBACK_DONE;
1012    return ECORE_CALLBACK_PASS_ON;
1013 }
1014
1015 static Eina_Bool
1016 _e_manager_cb_key_up(void *data, int ev_type __UNUSED__, void *ev)
1017 {
1018    E_Manager *man;
1019    Ecore_Event_Key *e;
1020
1021    man = data;
1022    e = ev;
1023
1024    if (e->event_window != man->root) return ECORE_CALLBACK_PASS_ON;
1025    if (e->root_window != man->root) man = _e_manager_get_for_root(e->root_window);
1026    if (e_bindings_key_up_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev))
1027      return ECORE_CALLBACK_DONE;
1028    return ECORE_CALLBACK_PASS_ON;
1029 }
1030
1031 static Eina_Bool
1032 _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev)
1033 {
1034    E_Manager *man;
1035    E_Container *con;
1036    Ecore_X_Event_Frame_Extents_Request *e;
1037    Ecore_X_Window_Type type;
1038    Ecore_X_MWM_Hint_Decor decor;
1039    Ecore_X_Window_State *state;
1040    Frame_Extents *extents;
1041    const char *border, *sig, *key;
1042    int ok;
1043    unsigned int i, num;
1044
1045    man = data;
1046    con = e_container_current_get(man);
1047    e = ev;
1048
1049    if (ecore_x_window_parent_get(e->win) != man->root) return ECORE_CALLBACK_PASS_ON;
1050
1051    /* TODO:
1052     * * We need to check if we remember this window, and border locking is set
1053     */
1054    border = "default";
1055    key = border;
1056    ok = ecore_x_mwm_hints_get(e->win, NULL, &decor, NULL);
1057    if ((ok) &&
1058        (!(decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
1059        (!(decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
1060        (!(decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
1061      {
1062         border = "borderless";
1063         key = border;
1064      }
1065
1066    ok = ecore_x_netwm_window_type_get(e->win, &type);
1067    if ((ok) &&
1068        ((type == ECORE_X_WINDOW_TYPE_DESKTOP) ||
1069         (type == ECORE_X_WINDOW_TYPE_DOCK)))
1070      {
1071         border = "borderless";
1072         key = border;
1073      }
1074
1075    sig = NULL;
1076    ecore_x_netwm_window_state_get(e->win, &state, &num);
1077    if (state)
1078      {
1079         int maximized = 0;
1080
1081         for (i = 0; i < num; i++)
1082           {
1083              switch (state[i])
1084                {
1085                 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
1086                   maximized++;
1087                   break;
1088                 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
1089                   maximized++;
1090                   break;
1091                 case ECORE_X_WINDOW_STATE_FULLSCREEN:
1092                   border = "borderless";
1093                   key = border;
1094                   break;
1095                 case ECORE_X_WINDOW_STATE_SHADED:
1096                 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
1097                 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
1098                 case ECORE_X_WINDOW_STATE_HIDDEN:
1099                 case ECORE_X_WINDOW_STATE_ICONIFIED:
1100                 case ECORE_X_WINDOW_STATE_MODAL:
1101                 case ECORE_X_WINDOW_STATE_STICKY:
1102                 case ECORE_X_WINDOW_STATE_ABOVE:
1103                 case ECORE_X_WINDOW_STATE_BELOW:
1104                 case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
1105                 case ECORE_X_WINDOW_STATE_UNKNOWN:
1106                   break;
1107                }
1108           }
1109         if ((maximized == 2) &&
1110             (e_config->maximize_policy == E_MAXIMIZE_FULLSCREEN))
1111           {
1112              sig = "e,action,maximize,fullscreen";
1113              key = "maximize,fullscreen";
1114           }
1115         free(state);
1116      }
1117
1118    extents = eina_hash_find(frame_extents, key);
1119    if (!extents)
1120      {
1121         extents = E_NEW(Frame_Extents, 1);
1122         if (extents)
1123           {
1124              Evas_Object *o;
1125              char buf[1024];
1126
1127              o = edje_object_add(con->bg_evas);
1128              snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", border);
1129              ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
1130              if (ok)
1131                {
1132                   Evas_Coord x, y, w, h;
1133
1134                   if (sig)
1135                     {
1136                        edje_object_signal_emit(o, sig, "e");
1137                        edje_object_message_signal_process(o);
1138                     }
1139
1140                   evas_object_resize(o, 1000, 1000);
1141                   edje_object_calc_force(o);
1142                   edje_object_part_geometry_get(o, "e.swallow.client",
1143                                                 &x, &y, &w, &h);
1144                   extents->l = x;
1145                   extents->r = 1000 - (x + w);
1146                   extents->t = y;
1147                   extents->b = 1000 - (y + h);
1148                }
1149              else
1150                {
1151                   extents->l = 0;
1152                   extents->r = 0;
1153                   extents->t = 0;
1154                   extents->b = 0;
1155                }
1156              evas_object_del(o);
1157              eina_hash_add(frame_extents, key, extents);
1158           }
1159      }
1160
1161    if (extents)
1162      ecore_x_netwm_frame_size_set(e->win, extents->l, extents->r, extents->t, extents->b);
1163
1164    return ECORE_CALLBACK_PASS_ON;
1165 }
1166
1167 static Eina_Bool
1168 _e_manager_cb_ping(void *data, int ev_type __UNUSED__, void *ev)
1169 {
1170    E_Manager *man;
1171    E_Border *bd;
1172    Ecore_X_Event_Ping *e;
1173
1174    man = data;
1175    e = ev;
1176
1177    if (e->win != man->root) return ECORE_CALLBACK_PASS_ON;
1178
1179    bd = e_border_find_by_client_window(e->event_win);
1180    if (!bd) return ECORE_CALLBACK_PASS_ON;
1181
1182    bd->ping_ok = 1;
1183    return ECORE_CALLBACK_PASS_ON;
1184 }
1185
1186 static Eina_Bool
1187 _e_manager_cb_timer_post_screensaver_lock(void *data __UNUSED__)
1188 {
1189    e_desklock_show_autolocked();
1190    timer_post_screensaver_lock = NULL;
1191    return ECORE_CALLBACK_CANCEL;
1192 }
1193
1194 static Eina_Bool
1195 _e_manager_cb_screensaver_notify(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1196 {
1197    Ecore_X_Event_Screensaver_Notify *e = ev;
1198
1199    if (timer_post_screensaver_lock)
1200      {
1201         ecore_timer_del(timer_post_screensaver_lock);
1202         timer_post_screensaver_lock = NULL;
1203      }
1204
1205    if (e->on)
1206      {
1207         if (e_config->desklock_autolock_screensaver)
1208           {
1209              if (e_config->desklock_post_screensaver_time <= 1.0)
1210                {
1211                   e_desklock_show_autolocked();
1212                }
1213              else
1214                {
1215                   timer_post_screensaver_lock = ecore_timer_add
1216                     (e_config->desklock_post_screensaver_time,
1217                      _e_manager_cb_timer_post_screensaver_lock, NULL);
1218                }
1219           }
1220      }
1221    return ECORE_CALLBACK_PASS_ON;
1222 }
1223
1224
1225 #ifdef _F_WINDOW_GROUP_RAISE_
1226 static void
1227 _e_manager_windows_group_raise (E_Border* bd)
1228 {
1229    Ecore_X_Window leader_win;
1230    
1231    if (!bd) return;
1232
1233    if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
1234       (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
1235       ((bd->parent) && 
1236       ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
1237       ((bd->parent->focused) &&
1238       (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
1239      {
1240         leader_win = bd->client.icccm.client_leader;
1241         if (leader_win)
1242           {
1243              Eina_List* restack_list;
1244              E_Border *temp_bd;
1245              E_Border *top_bd;
1246              E_Border_List *bl;
1247
1248              restack_list = NULL;
1249              top_bd = NULL;
1250              bl = e_container_border_list_last(bd->zone->container);
1251              while ((temp_bd = e_container_border_list_prev(bl)))
1252                {
1253                   if (temp_bd->client.icccm.client_leader == leader_win)
1254                     {
1255                        restack_list = eina_list_prepend(restack_list, temp_bd);
1256                     }
1257                }
1258              e_container_border_list_free(bl);
1259
1260              if (restack_list)
1261                {
1262                   EINA_LIST_FREE (restack_list, temp_bd)
1263                     {
1264                        if (temp_bd->iconic)
1265                          {
1266                             if (e_config->clientlist_warp_to_iconified_desktop == 1)
1267                                e_desk_show(temp_bd->desk);
1268
1269                             if (!temp_bd->lock_user_iconify)
1270                                e_border_uniconify(temp_bd);
1271                          }
1272
1273                        if (!temp_bd->iconic) e_desk_show(temp_bd->desk);
1274                        if (!temp_bd->lock_user_stacking) e_border_raise(temp_bd);
1275
1276                        // set focus to top window
1277                        if (!temp_bd->lock_focus_out)
1278                          {
1279                             top_bd = temp_bd;
1280
1281                             if (e_config->focus_policy != E_FOCUS_CLICK)
1282                                ecore_x_pointer_warp(top_bd->zone->container->win, top_bd->x + (top_bd->w / 2), top_bd->y + (top_bd->h / 2));
1283                             
1284                             if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1285                                e_border_focus_set(top_bd, 1, 1);
1286                             else
1287                               {
1288                                  Eina_List* l2;
1289                                  E_Border* temp_bd2;
1290                                  l2 = NULL;
1291                                  temp_bd2 = NULL;
1292
1293                                  bl = e_container_border_list_last(bd->zone->container);
1294                                  while ((temp_bd2 = e_container_border_list_prev(bl)))
1295                                    {
1296                                       if ((!temp_bd2->iconic) && (temp_bd2->visible) && (temp_bd2->desk == top_bd->desk) &&
1297                                          (temp_bd2->client.icccm.accepts_focus || temp_bd2->client.icccm.take_focus) &&
1298                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
1299                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
1300                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
1301                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
1302                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
1303                                         {
1304                                            if (top_bd == temp_bd2)
1305                                              {
1306                                                 e_border_focus_set(top_bd, 1, 1);
1307                                              }
1308                                             break;
1309                                         }
1310                                    }
1311                                  e_container_border_list_free(bl);
1312                               }
1313                          }
1314                     }
1315                }
1316           }
1317      }
1318 }
1319 #endif // group raise
1320
1321 static Eina_Bool
1322 _e_manager_cb_client_message(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1323 {
1324    Ecore_X_Event_Client_Message *e;
1325    E_Border *bd;
1326
1327    e = ev;
1328
1329    if (e->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW)
1330      {
1331         bd = e_border_find_by_client_window(e->win);
1332         if (bd)
1333           {
1334 #if 0 /* notes */
1335              if (e->data.l[0] == 0 /* 0 == old, 1 == client, 2 == pager */)
1336                {
1337                   // FIXME: need config for the below - what to do given each
1338                   //  request (either do nothng, make app look urgent/want
1339                   //  attention or actiually flip to app as below is the
1340                   //  current default)
1341                   // if 0 == just make app demand attention somehow
1342                   // if 1 == just make app demand attention somehow
1343                   // if 2 == activate window as below
1344                }
1345              timestamp = e->data.l[1];
1346              requestor_id e->data.l[2];
1347 #endif
1348
1349 #ifdef _F_WINDOW_GROUP_RAISE_
1350              if (e->data.l[0] == 3) // 'e->data.l[0] == 3' means group raise
1351                {
1352                   if (bd->client.icccm.client_leader)
1353                     {
1354                        _e_manager_windows_group_raise (bd);
1355                        return ECORE_CALLBACK_PASS_ON;
1356                     }
1357                }
1358 #endif
1359
1360 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1361              if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
1362                  (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
1363                  ((bd->parent) &&
1364                   ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
1365                    ((bd->parent->focused) &&
1366                     (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
1367                {
1368                   if (bd->iconic)
1369                     {
1370                        if (e_config->clientlist_warp_to_iconified_desktop == 1)
1371                          e_desk_show(bd->desk);
1372
1373                        if (!bd->lock_user_iconify)
1374                          e_border_uniconify(bd);
1375                     }
1376                   if ((!bd->iconic) && (!bd->sticky))
1377                     e_desk_show(bd->desk);
1378 #ifdef _F_DEICONIFY_APPROVE_
1379                   if (!bd->iconic)
1380                     {
1381                        if (!bd->lock_user_stacking) e_border_raise(bd);
1382                     }
1383 #else
1384                   if (!bd->lock_user_stacking) e_border_raise(bd);
1385 #endif
1386                   if (!bd->lock_focus_out)
1387                     {
1388                        /* XXX ooffice does send this request for
1389                           config dialogs when the main window gets focus.
1390                           causing the pointer to jump back and forth.  */
1391                        if ((e_config->focus_policy != E_FOCUS_CLICK) &&
1392                            !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
1393                          ecore_x_pointer_warp(bd->zone->container->win,
1394                                               bd->x + (bd->w / 2), bd->y + (bd->h / 2));
1395
1396                        if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1397                          e_border_focus_set(bd, 1, 1);
1398                        else
1399                          {
1400                             E_Border* temp_bd = NULL;
1401                             E_Border_List *bl;
1402                             E_Border *cur_focus;
1403
1404                             cur_focus = e_border_focused_get();
1405                             bl = e_container_border_list_last(bd->zone->container);
1406                             while ((temp_bd = e_container_border_list_prev(bl)))
1407                               {
1408                                  if (temp_bd == cur_focus) break;
1409
1410                                  if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
1411                                  if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
1412                                  if ((temp_bd != bd) &&
1413                                      (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING))
1414                                    continue;
1415
1416                                  if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
1417                                      (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
1418                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
1419                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
1420                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
1421                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
1422                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
1423                                    {
1424                                       e_border_focus_set(temp_bd, 1, 1);
1425                                       break;
1426                                    }
1427                               }
1428                             e_container_border_list_free(bl);
1429                          }
1430                     }
1431                }
1432 #else // original
1433              if (!bd->focused) e_border_activate(bd, EINA_FALSE);
1434              else e_border_raise(bd);
1435 #endif
1436           }
1437      }
1438
1439    return ECORE_CALLBACK_PASS_ON;
1440 }
1441
1442 static Eina_Bool
1443 _e_manager_frame_extents_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__,
1444                                  void *data, void *fdata __UNUSED__)
1445 {
1446    free(data);
1447    return EINA_TRUE;
1448 }
1449
1450 static E_Manager *
1451 _e_manager_get_for_root(Ecore_X_Window root)
1452 {
1453    Eina_List *l;
1454    E_Manager *man;
1455
1456    if (!managers) return NULL;
1457    EINA_LIST_FOREACH(managers, l, man)
1458      {
1459         if (man->root == root)
1460           return man;
1461      }
1462    return eina_list_data_get(managers);
1463 }
1464
1465 static Eina_Bool
1466 _e_manager_clear_timer(void *data)
1467 {
1468    E_Manager *man = data;
1469    ecore_x_window_background_color_set(man->root, 0, 0, 0);
1470    man->clear_timer = NULL;
1471    return EINA_FALSE;
1472 }
1473
1474 #if 0 /* use later - maybe */
1475 static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev){return 1;}
1476 static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev){return 1;}
1477 static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev){return 1;}
1478 static int _e_manager_cb_window_create(void *data, int ev_type, void *ev){return 1;}
1479 static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev){return 1;}
1480 static int _e_manager_cb_window_configure(void *data, int ev_type, void *ev){return 1;}
1481 static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev){return 1;}
1482 static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev){return 1;}
1483 static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev){return 1;}
1484 static int _e_manager_cb_window_property(void *data, int ev_type, void *ev){return 1;}
1485 static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev){return 1;}
1486 static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev){return 1;}
1487 #endif