e73eb588a2796bcd6b3cbba449033f444cb48d3f
[framework/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 #if 0 /* use later - maybe */
20 static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev);
21 static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev);
22 static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev);
23 static int _e_manager_cb_window_create(void *data, int ev_type, void *ev);
24 static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev);
25 static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev);
26 static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev);
27 static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev);
28 static int _e_manager_cb_window_property(void *data, int ev_type, void *ev);
29 static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev);
30 static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev);
31 static int _e_manager_cb_client_message(void *data, int ev_type, void *ev);
32 #endif
33
34 /* local subsystem globals */
35
36 typedef struct _Frame_Extents Frame_Extents;
37
38 struct _Frame_Extents
39 {
40    int l, r, t, b;
41 };
42
43 static Eina_List *managers = NULL;
44 static Eina_Hash *frame_extents = NULL;
45 static Ecore_Timer *timer_post_screensaver_lock = NULL;
46
47 /* externally accessible functions */
48 EINTERN int
49 e_manager_init(void)
50 {
51    ecore_x_screensaver_event_listen_set(1);
52    frame_extents = eina_hash_string_superfast_new(NULL);
53    return 1;
54 }
55
56 EINTERN int
57 e_manager_shutdown(void)
58 {
59    E_FREE_LIST(managers, e_object_del);
60
61    if (frame_extents)
62      {
63         eina_hash_foreach(frame_extents, _e_manager_frame_extents_free_cb, NULL);
64         eina_hash_free(frame_extents);
65         frame_extents = NULL;
66      }
67
68    if (timer_post_screensaver_lock)
69      {
70         ecore_timer_del(timer_post_screensaver_lock);
71         timer_post_screensaver_lock = NULL;
72      }
73
74    return 1;
75 }
76
77 EAPI Eina_List *
78 e_manager_list(void)
79 {
80    return managers;
81 }
82
83 EAPI E_Manager *
84 e_manager_new(Ecore_X_Window root, int num)
85 {
86    E_Manager *man;
87    Ecore_Event_Handler *h;
88
89    if (!ecore_x_window_manage(root)) return NULL;
90    ecore_x_window_background_color_set(root, 0, 0, 0);
91    man = E_OBJECT_ALLOC(E_Manager, E_MANAGER_TYPE, _e_manager_free);
92    if (!man) return NULL;
93    managers = eina_list_append(managers, man);
94    man->root = root;
95    man->num = num;
96    ecore_x_window_size_get(man->root, &(man->w), &(man->h));
97    if (e_config->use_virtual_roots)
98      {
99         man->win = ecore_x_window_override_new(man->root, man->x, man->y, man->w, man->h);
100         ecore_x_icccm_title_set(man->win, "Enlightenment Manager");
101         ecore_x_netwm_name_set(man->win, "Enlightenment Manager");
102         ecore_x_window_raise(man->win);
103      }
104    else
105      {
106         man->win = man->root;
107      }
108
109    h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_manager_cb_window_show_request, man);
110    if (h) man->handlers = eina_list_append(man->handlers, h);
111    h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_manager_cb_window_configure, man);
112    if (h) man->handlers = eina_list_append(man->handlers, h);
113    h = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_manager_cb_key_down, man);
114    if (h) man->handlers = eina_list_append(man->handlers, h);
115    h = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _e_manager_cb_key_up, man);
116    if (h) man->handlers = eina_list_append(man->handlers, h);
117    h = ecore_event_handler_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, _e_manager_cb_frame_extents_request, man);
118    if (h) man->handlers = eina_list_append(man->handlers, h);
119    h = ecore_event_handler_add(ECORE_X_EVENT_PING, _e_manager_cb_ping, man);
120    if (h) man->handlers = eina_list_append(man->handlers, h);
121    h = ecore_event_handler_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, _e_manager_cb_screensaver_notify, man);
122    if (h) man->handlers = eina_list_append(man->handlers, h);
123    h = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_manager_cb_client_message, man);
124    if (h) man->handlers = eina_list_append(man->handlers, h);
125
126    man->pointer = e_pointer_window_new(man->root, 1);
127
128    return man;
129 }
130
131 EAPI void
132 e_manager_manage_windows(E_Manager *man)
133 {
134    Ecore_X_Window *windows;
135    int wnum;
136
137    /* a manager is designated for each root. lets get all the windows in
138       the managers root */
139    windows = ecore_x_window_children_get(man->root, &wnum);
140    if (windows)
141      {
142         int i;
143         const char *atom_names[] =
144           {
145              "_XEMBED_INFO",
146                "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
147                "KWM_DOCKWINDOW"
148           };
149         Ecore_X_Atom atoms[3];
150         Ecore_X_Atom atom_xmbed, atom_kde_netwm_systray, atom_kwm_dockwindow;
151         unsigned char *data = NULL;
152         int count;
153
154         ecore_x_atoms_get(atom_names, 3, atoms);
155         atom_xmbed = atoms[0];
156         atom_kde_netwm_systray = atoms[1];
157         atom_kwm_dockwindow = atoms[2];
158         for (i = 0; i < wnum; i++)
159           {
160              Ecore_X_Window_Attributes att;
161              unsigned int ret_val, deskxy[2];
162              int ret;
163
164              if (e_border_find_by_client_window(windows[i]))
165                continue;
166              ecore_x_window_attributes_get(windows[i], &att);
167              if ((att.override) || (att.input_only))
168                {
169                   if (att.override)
170                     {
171                        char *wname = NULL, *wclass = NULL;
172
173                        ecore_x_icccm_name_class_get(windows[i],
174                                                     &wname, &wclass);
175                        if ((wname) && (wclass) &&
176                            (!strcmp(wname, "E")) &&
177                            (!strcmp(wclass, "Init_Window")))
178                          {
179                             free(wname);
180                             free(wclass);
181                             man->initwin = windows[i];
182                          }
183                        else
184                          {
185                             if (wname) free(wname);
186                             if (wclass) free(wclass);
187                             continue;
188                          }
189                     }
190                   else
191                     continue;
192                }
193              /* XXX manage xembed windows as long as they are not override_redirect..
194               * if (!ecore_x_window_prop_property_get(windows[i],
195               *                                            atom_xmbed,
196               *                                            atom_xmbed, 32,
197               *                                            &data, &count))
198               *   data = NULL;
199               * if (!data) */
200                {
201                   if (!ecore_x_window_prop_property_get(windows[i],
202                                                         atom_kde_netwm_systray,
203                                                         atom_xmbed, 32,
204                                                         &data, &count))
205                     data = NULL;
206                }
207              if (!data)
208                {
209                   if (!ecore_x_window_prop_property_get(windows[i],
210                                                         atom_kwm_dockwindow,
211                                                         atom_kwm_dockwindow, 32,
212                                                         &data, &count))
213                     data = NULL;
214                }
215              if (data)
216                {
217                   free(data);
218                   data = NULL;
219                   continue;
220                }
221              ret = ecore_x_window_prop_card32_get(windows[i],
222                                                   E_ATOM_MANAGED,
223                                                   &ret_val, 1);
224
225              /* we have seen this window before */
226              if ((ret > -1) && (ret_val == 1))
227                {
228                   E_Container  *con = NULL;
229                   E_Zone       *zone = NULL;
230                   E_Desk       *desk = NULL;
231                   E_Border     *bd = NULL;
232                   unsigned int  id;
233                   char *path;
234                   Efreet_Desktop *desktop = NULL;
235
236                   /* get all information from window before it is
237                    * reset by e_border_new */
238                   ret = ecore_x_window_prop_card32_get(windows[i],
239                                                        E_ATOM_CONTAINER,
240                                                        &id, 1);
241                   if (ret == 1)
242                     con = e_container_number_get(man, id);
243                   if (!con)
244                     con = e_container_current_get(man);
245
246                   ret = ecore_x_window_prop_card32_get(windows[i],
247                                                        E_ATOM_ZONE,
248                                                        &id, 1);
249                   if (ret == 1)
250                     zone = e_container_zone_number_get(con, id);
251                   if (!zone)
252                     zone = e_zone_current_get(con);
253                   ret = ecore_x_window_prop_card32_get(windows[i],
254                                                        E_ATOM_DESK,
255                                                        deskxy, 2);
256                   if (ret == 2)
257                     desk = e_desk_at_xy_get(zone,
258                                             deskxy[0],
259                                             deskxy[1]);
260
261                   path = ecore_x_window_prop_string_get(windows[i],
262                                                         E_ATOM_DESKTOP_FILE);
263                   if (path)
264                     {
265                        desktop = efreet_desktop_get(path);
266                        free(path);
267                     }
268
269                     {
270                        bd = e_border_new(con, windows[i], 1, 0);
271                        if (bd)
272                          {
273                             bd->ignore_first_unmap = 1;
274                             /* FIXME:
275                              * It's enough to set the desk, the zone will
276                              * be set according to the desk */
277 //                          if (zone) e_border_zone_set(bd, zone);
278                             if (desk) e_border_desk_set(bd, desk);
279                             bd->desktop = desktop;
280                          }
281                     }
282                }
283              else if ((att.visible) && (!att.override) &&
284                       (!att.input_only))
285                {
286                   /* We have not seen this window, and X tells us it
287                    * should be seen */
288                   E_Container *con;
289                   E_Border *bd;
290
291                   con = e_container_current_get(man);
292                   bd = e_border_new(con, windows[i], 1, 0);
293                   if (bd)
294                     {
295                        bd->ignore_first_unmap = 1;
296                        e_border_show(bd);
297                     }
298                }
299           }
300         free(windows);
301      }
302 }
303
304 EAPI void
305 e_manager_show(E_Manager *man)
306 {
307    Eina_List *l;
308    E_Container *con;
309
310    E_OBJECT_CHECK(man);
311    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
312    if (man->visible) return;
313    EINA_LIST_FOREACH(man->containers, l, con)
314      {
315         e_container_show(con);
316      }
317    if (man->root != man->win)
318      {
319         Ecore_X_Window mwin;
320
321         mwin = e_menu_grab_window_get();
322         if (!mwin) mwin = man->initwin;
323         if (!mwin)
324           ecore_x_window_raise(man->win);
325         else
326           ecore_x_window_configure(man->win,
327                                    ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
328                                    ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
329                                    0, 0, 0, 0, 0,
330                                    mwin, ECORE_X_WINDOW_STACK_BELOW);
331         ecore_x_window_show(man->win);
332      }
333    man->visible = 1;
334 }
335
336 EAPI void
337 e_manager_hide(E_Manager *man)
338 {
339    Eina_List *l;
340    E_Container *con;
341
342    E_OBJECT_CHECK(man);
343    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
344    if (!man->visible) return;
345    EINA_LIST_FOREACH(man->containers, l, con)
346      {
347         e_container_hide(con);
348      }
349    if (man->root != man->win)
350      ecore_x_window_hide(man->win);
351    man->visible = 0;
352 }
353
354 EAPI void
355 e_manager_move(E_Manager *man, int x, int y)
356 {
357    E_OBJECT_CHECK(man);
358    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
359    if ((x == man->x) && (y == man->y)) return;
360    if (man->root != man->win)
361      {
362         man->x = x;
363         man->y = y;
364         ecore_x_window_move(man->win, man->x, man->y);
365      }
366 }
367
368 EAPI void
369 e_manager_resize(E_Manager *man, int w, int h)
370 {
371    Eina_List *l;
372    E_Container *con;
373
374    E_OBJECT_CHECK(man);
375    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
376    if ((w == man->w) && (h == man->h)) return;
377    man->w = w;
378    man->h = h;
379    if (man->root != man->win)
380      ecore_x_window_resize(man->win, man->w, man->h);
381
382    EINA_LIST_FOREACH(man->containers, l, con)
383      {
384         e_container_resize(con, man->w, man->h);
385      }
386
387    ecore_x_netwm_desk_size_set(man->root, man->w, man->h);
388 }
389
390 EAPI void
391 e_manager_move_resize(E_Manager *man, int x, int y, int w, int h)
392 {
393    Eina_List *l;
394    E_Container *con;
395
396    E_OBJECT_CHECK(man);
397    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
398    if ((x == man->x) && (y == man->y) && (w == man->w) && (h == man->h)) return;
399    if (man->root != man->win)
400      {
401         man->x = x;
402         man->y = y;
403      }
404    man->w = w;
405    man->h = h;
406    ecore_x_window_move_resize(man->win, man->x, man->y, man->w, man->h);
407
408    EINA_LIST_FOREACH(man->containers, l, con)
409      {
410         e_container_resize(con, man->w, man->h);
411      }
412 }
413
414 EAPI void
415 e_manager_raise(E_Manager *man)
416 {
417    E_OBJECT_CHECK(man);
418    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
419    if (man->root != man->win)
420      {
421         Ecore_X_Window mwin;
422
423         mwin = e_menu_grab_window_get();
424         if (!mwin) mwin = man->initwin;
425         if (!mwin)
426           ecore_x_window_raise(man->win);
427         else
428           ecore_x_window_configure(man->win,
429                                    ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
430                                    ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
431                                    0, 0, 0, 0, 0,
432                                    mwin, ECORE_X_WINDOW_STACK_BELOW);
433      }
434 }
435
436 EAPI void
437 e_manager_lower(E_Manager *man)
438 {
439    E_OBJECT_CHECK(man);
440    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
441    if (man->root != man->win)
442      ecore_x_window_lower(man->win);
443 }
444
445 EAPI E_Manager *
446 e_manager_current_get(void)
447 {
448    Eina_List *l;
449    E_Manager *man;
450    int x, y;
451
452    if (!managers) return NULL;
453    EINA_LIST_FOREACH(managers, l, man)
454      {
455         ecore_x_pointer_xy_get(man->win, &x, &y);
456         if (x == -1 && y == -1)
457           continue;
458         if (E_INSIDE(x, y, man->x, man->y, man->w, man->h))
459           return man;
460      }
461    return eina_list_data_get(managers);
462 }
463
464 EAPI E_Manager *
465 e_manager_number_get(int num)
466 {
467    Eina_List *l;
468    E_Manager *man;
469
470    if (!managers) return NULL;
471    EINA_LIST_FOREACH(managers, l, man)
472      {
473         if (man->num == num)
474           return man;
475      }
476    return NULL;
477 }
478
479 EAPI void
480 e_managers_keys_grab(void)
481 {
482    Eina_List *l;
483    E_Manager *man;
484
485    EINA_LIST_FOREACH(managers, l, man)
486      {
487         e_bindings_key_grab(E_BINDING_CONTEXT_ANY, man->root);
488      }
489 }
490
491 EAPI void
492 e_managers_keys_ungrab(void)
493 {
494    Eina_List *l;
495    E_Manager *man;
496
497    EINA_LIST_FOREACH(managers, l, man)
498      {
499         e_bindings_key_ungrab(E_BINDING_CONTEXT_ANY, man->root);
500      }
501 }
502
503
504
505
506
507
508
509 EAPI void
510 e_manager_comp_set(E_Manager *man, E_Manager_Comp *comp)
511 {
512    E_OBJECT_CHECK(man);
513    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
514    man->comp = comp;
515    e_msg_send("comp.manager", "change.comp", // name + info
516               0, // val
517               E_OBJECT(man), // obj
518               NULL, // msgdata
519               NULL, NULL); // afterfunc + afterdata
520 }
521
522 EAPI Evas *
523 e_manager_comp_evas_get(E_Manager *man)
524 {
525    E_OBJECT_CHECK(man);
526    E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
527    if (!man->comp) return NULL;
528    return man->comp->func.evas_get(man->comp->data, man);
529 }
530
531 EAPI void
532 e_manager_comp_evas_update(E_Manager *man)
533 {
534    E_OBJECT_CHECK(man);
535    E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE);
536    if (!man->comp) return;
537    return man->comp->func.update(man->comp->data, man);
538 }
539
540 EAPI const Eina_List *
541 e_manager_comp_src_list(E_Manager *man)
542 {
543    return man->comp->func.src_list_get(man->comp->data, man);
544 }
545
546 EAPI Evas_Object *
547 e_manager_comp_src_image_get(E_Manager *man, E_Manager_Comp_Source *src)
548 {
549    return man->comp->func.src_image_get(man->comp->data, man, src);
550 }
551
552 EAPI Evas_Object *
553 e_manager_comp_src_shadow_get(E_Manager *man, E_Manager_Comp_Source *src)
554 {
555    return man->comp->func.src_shadow_get(man->comp->data, man, src);
556 }
557
558 EAPI Evas_Object *
559 e_manager_comp_src_image_mirror_add(E_Manager *man, E_Manager_Comp_Source *src)
560 {
561    return man->comp->func.src_image_mirror_add(man->comp->data, man, src);
562 }
563
564 EAPI Eina_Bool
565 e_manager_comp_src_visible_get(E_Manager *man, E_Manager_Comp_Source *src)
566 {
567    return man->comp->func.src_visible_get(man->comp->data, man, src);
568 }
569
570 EAPI void
571 e_manager_comp_src_hidden_set(E_Manager *man, E_Manager_Comp_Source *src, Eina_Bool hidden)
572 {
573    return man->comp->func.src_hidden_set(man->comp->data, man, src, hidden);
574 }
575
576 EAPI Eina_Bool
577 e_manager_comp_src_hidden_get(E_Manager *man, E_Manager_Comp_Source *src)
578 {
579    return man->comp->func.src_hidden_get(man->comp->data, man, src);
580 }
581
582 EAPI void
583 e_manager_comp_event_resize_send(E_Manager *man)
584 {
585    e_msg_send("comp.manager", "resize.comp", // name + info
586               0, // val
587               E_OBJECT(man), // obj
588               NULL, // msgdata
589               NULL, NULL); // afterfunc + afterdata
590 }
591
592 EAPI void
593 e_manager_comp_event_src_add_send(E_Manager *man, E_Manager_Comp_Source *src,
594                                   void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
595                                   void *data)
596 {
597    e_msg_send("comp.manager", "add.src", // name + info
598               0, // val
599               E_OBJECT(man), // obj
600               src, // msgdata
601               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
602 }
603
604 EAPI void
605 e_manager_comp_event_src_del_send(E_Manager *man, E_Manager_Comp_Source *src,
606                                   void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
607                                   void *data)
608 {
609    e_msg_send("comp.manager", "del.src", // name + info
610               0, // val
611               E_OBJECT(man), // obj
612               src, // msgdata
613               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
614 }
615
616 EAPI void
617 e_manager_comp_event_src_config_send(E_Manager *man, E_Manager_Comp_Source *src,
618                                      void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
619                                      void *data)
620 {
621    e_msg_send("comp.manager", "config.src", // name + info
622               0, // val
623               E_OBJECT(man), // obj
624               src, // msgdata
625               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
626 }
627
628 EAPI void
629 e_manager_comp_event_src_visibility_send(E_Manager *man, E_Manager_Comp_Source *src,
630                                          void (*afterfunc) (void *data, E_Manager *man, E_Manager_Comp_Source *src),
631                                          void *data)
632 {
633    e_msg_send("comp.manager", "visibility.src", // name + info
634               0, // val
635               E_OBJECT(man), // obj
636               src, // msgdata
637               (void (*)(void *, E_Object *, void *))afterfunc, data); // afterfunc + afterdata
638 }
639
640
641
642
643
644 /* local subsystem functions */
645 static void
646 _e_manager_free(E_Manager *man)
647 {
648    Eina_List *l;
649
650    E_FREE_LIST(man->handlers, ecore_event_handler_del);
651    l = man->containers;
652    man->containers = NULL;
653    E_FREE_LIST(l, e_object_del);
654    if (man->root != man->win)
655      {
656         ecore_x_window_free(man->win);
657      }
658    if (man->pointer) e_object_del(E_OBJECT(man->pointer));
659    managers = eina_list_remove(managers, man);
660    free(man);
661 }
662
663 static Eina_Bool
664 _e_manager_cb_window_show_request(void *data, int ev_type __UNUSED__, void *ev)
665 {
666    E_Manager *man;
667    Ecore_X_Event_Window_Show_Request *e;
668
669    man = data;
670    e = ev;
671    if (e_stolen_win_get(e->win)) return 1;
672    if (ecore_x_window_parent_get(e->win) != man->root)
673      return ECORE_CALLBACK_PASS_ON;  /* try other handlers for this */
674
675      {
676         E_Container *con;
677         E_Border *bd;
678
679         con = e_container_current_get(man);
680         if (!e_border_find_by_client_window(e->win))
681           {
682              bd = e_border_new(con, e->win, 0, 0);
683              if (!bd)
684                ecore_x_window_show(e->win);
685           }
686      }
687    return ECORE_CALLBACK_PASS_ON;
688 }
689
690 static Eina_Bool
691 _e_manager_cb_window_configure(void *data, int ev_type __UNUSED__, void *ev)
692 {
693    E_Manager *man;
694    Ecore_X_Event_Window_Configure *e;
695
696    man = data;
697    e = ev;
698    if (e->win != man->root) return ECORE_CALLBACK_PASS_ON;
699    e_manager_resize(man, e->w, e->h);
700    return ECORE_CALLBACK_PASS_ON;
701 }
702
703 static Eina_Bool
704 _e_manager_cb_key_down(void *data, int ev_type __UNUSED__, void *ev)
705 {
706    E_Manager *man;
707    Ecore_Event_Key *e;
708
709    man = data;
710    e = ev;
711
712    if (e->event_window != man->root) return ECORE_CALLBACK_PASS_ON;
713    if (e->root_window != man->root) man = _e_manager_get_for_root(e->root_window);
714    if (e_bindings_key_down_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev))
715      return ECORE_CALLBACK_DONE;
716    return ECORE_CALLBACK_PASS_ON;
717 }
718
719 static Eina_Bool
720 _e_manager_cb_key_up(void *data, int ev_type __UNUSED__, void *ev)
721 {
722    E_Manager *man;
723    Ecore_Event_Key *e;
724
725    man = data;
726    e = ev;
727
728    if (e->event_window != man->root) return ECORE_CALLBACK_PASS_ON;
729    if (e->root_window != man->root) man = _e_manager_get_for_root(e->root_window);
730    if (e_bindings_key_up_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev))
731      return ECORE_CALLBACK_DONE;
732    return ECORE_CALLBACK_PASS_ON;
733 }
734
735 static Eina_Bool
736 _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev)
737 {
738    E_Manager *man;
739    E_Container *con;
740    Ecore_X_Event_Frame_Extents_Request *e;
741    Ecore_X_Window_Type type;
742    Ecore_X_MWM_Hint_Decor decor;
743    Ecore_X_Window_State *state;
744    Frame_Extents *extents;
745    const char *border, *signal, *key;
746    int ok;
747    unsigned int i, num;
748
749    man = data;
750    con = e_container_current_get(man);
751    e = ev;
752
753    if (ecore_x_window_parent_get(e->win) != man->root) return ECORE_CALLBACK_PASS_ON;
754
755    /* TODO:
756     * * We need to check if we remember this window, and border locking is set
757     */
758    border = "default";
759    key = border;
760    ok = ecore_x_mwm_hints_get(e->win, NULL, &decor, NULL);
761    if ((ok) &&
762        (!(decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
763        (!(decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
764        (!(decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
765      {
766         border = "borderless";
767         key = border;
768      }
769
770    ok = ecore_x_netwm_window_type_get(e->win, &type);
771    if ((ok) &&
772        ((type == ECORE_X_WINDOW_TYPE_DESKTOP) ||
773         (type == ECORE_X_WINDOW_TYPE_DOCK)))
774      {
775         border = "borderless";
776         key = border;
777      }
778
779    signal = NULL;
780    ecore_x_netwm_window_state_get(e->win, &state, &num);
781    if (state)
782      {
783         int maximized = 0;
784
785         for (i = 0; i < num; i++)
786           {
787              switch (state[i])
788                {
789                 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
790                   maximized++;
791                   break;
792                 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
793                   maximized++;
794                   break;
795                 case ECORE_X_WINDOW_STATE_FULLSCREEN:
796                   border = "borderless";
797                   key = border;
798                   break;
799                 case ECORE_X_WINDOW_STATE_SHADED:
800                 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
801                 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
802                 case ECORE_X_WINDOW_STATE_HIDDEN:
803                 case ECORE_X_WINDOW_STATE_ICONIFIED:
804                 case ECORE_X_WINDOW_STATE_MODAL:
805                 case ECORE_X_WINDOW_STATE_STICKY:
806                 case ECORE_X_WINDOW_STATE_ABOVE:
807                 case ECORE_X_WINDOW_STATE_BELOW:
808                 case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
809                 case ECORE_X_WINDOW_STATE_UNKNOWN:
810                   break;
811                }
812           }
813         if ((maximized == 2) &&
814             (e_config->maximize_policy == E_MAXIMIZE_FULLSCREEN))
815           {
816              signal = "e,action,maximize,fullscreen";
817              key = "maximize,fullscreen";
818           }
819         free(state);
820      }
821
822    extents = eina_hash_find(frame_extents, key);
823    if (!extents)
824      {
825         extents = E_NEW(Frame_Extents, 1);
826         if (extents)
827           {
828              Evas_Object *o;
829              char buf[1024];
830
831              o = edje_object_add(con->bg_evas);
832              snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", border);
833              ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
834              if (ok)
835                {
836                   Evas_Coord x, y, w, h;
837
838                   if (signal)
839                     {
840                        edje_object_signal_emit(o, signal, "e");
841                        edje_object_message_signal_process(o);
842                     }
843
844                   evas_object_resize(o, 1000, 1000);
845                   edje_object_calc_force(o);
846                   edje_object_part_geometry_get(o, "e.swallow.client",
847                                                 &x, &y, &w, &h);
848                   extents->l = x;
849                   extents->r = 1000 - (x + w);
850                   extents->t = y;
851                   extents->b = 1000 - (y + h);
852                }
853              else
854                {
855                   extents->l = 0;
856                   extents->r = 0;
857                   extents->t = 0;
858                   extents->b = 0;
859                }
860              evas_object_del(o);
861              eina_hash_add(frame_extents, key, extents);
862           }
863      }
864
865    if (extents)
866      ecore_x_netwm_frame_size_set(e->win, extents->l, extents->r, extents->t, extents->b);
867
868    return ECORE_CALLBACK_PASS_ON;
869 }
870
871 static Eina_Bool
872 _e_manager_cb_ping(void *data, int ev_type __UNUSED__, void *ev)
873 {
874    E_Manager *man;
875    E_Border *bd;
876    Ecore_X_Event_Ping *e;
877
878    man = data;
879    e = ev;
880
881    if (e->win != man->root) return ECORE_CALLBACK_PASS_ON;
882
883    bd = e_border_find_by_client_window(e->event_win);
884    if (!bd) return ECORE_CALLBACK_PASS_ON;
885
886    bd->ping_ok = 1;
887    return ECORE_CALLBACK_PASS_ON;
888 }
889
890 static Eina_Bool
891 _e_manager_cb_timer_post_screensaver_lock(void *data __UNUSED__)
892 {
893    e_desklock_show_autolocked();
894    timer_post_screensaver_lock = NULL;
895    return ECORE_CALLBACK_CANCEL;
896 }
897
898 static Eina_Bool
899 _e_manager_cb_screensaver_notify(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
900 {
901    Ecore_X_Event_Screensaver_Notify *e = ev;
902
903    if (timer_post_screensaver_lock)
904      {
905         ecore_timer_del(timer_post_screensaver_lock);
906         timer_post_screensaver_lock = NULL;
907      }
908
909    if (e->on)
910      {
911         if (e_config->desklock_autolock_screensaver)
912           {
913              if (e_config->desklock_post_screensaver_time <= 1.0)
914                {
915                   e_desklock_show_autolocked();
916                }
917              else
918                {
919                   timer_post_screensaver_lock = ecore_timer_add
920                     (e_config->desklock_post_screensaver_time,
921                      _e_manager_cb_timer_post_screensaver_lock, NULL);
922                }
923           }
924      }
925    return ECORE_CALLBACK_PASS_ON;
926 }
927
928
929 #ifdef _F_WINDOW_GROUP_RAISE_
930 static void
931 _e_manager_windows_group_raise (E_Border* bd)
932 {
933    Ecore_X_Window leader_win;
934    
935    if (!bd) return;
936
937    if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
938       (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
939       ((bd->parent) && 
940       ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
941       ((bd->parent->focused) &&
942       (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
943      {
944         leader_win = bd->client.icccm.client_leader;
945         if (leader_win)
946           {
947              Eina_List* border_list;
948              Eina_List* restack_list;
949              Eina_List *l;   
950              E_Border *temp_bd;
951              E_Border *top_bd;
952              E_Border_List *bl;
953
954              restack_list = NULL;
955              top_bd = NULL;
956              bl = e_container_border_list_last(bd->zone->container);
957              while ((temp_bd = e_container_border_list_prev(bl)))
958                {
959                   if (temp_bd->client.icccm.client_leader == leader_win)
960                     {
961                        restack_list = eina_list_prepend(restack_list, temp_bd);
962                     }
963                }
964              e_container_border_list_free(bl);
965
966              if (restack_list)
967                {
968                   EINA_LIST_FREE (restack_list, temp_bd)
969                     {
970                        if (temp_bd->iconic)
971                          {
972                             if (e_config->clientlist_warp_to_iconified_desktop == 1)
973                                e_desk_show(temp_bd->desk);
974
975                             if (!temp_bd->lock_user_iconify)
976                                e_border_uniconify(temp_bd);
977                          }
978
979                        if (!temp_bd->iconic) e_desk_show(temp_bd->desk);
980                        if (!temp_bd->lock_user_stacking) e_border_raise(temp_bd);
981
982                        // set focus to top window
983                        if (!temp_bd->lock_focus_out)
984                          {
985                             top_bd = temp_bd;
986
987                             if (e_config->focus_policy != E_FOCUS_CLICK)
988                                ecore_x_pointer_warp(top_bd->zone->container->win, top_bd->x + (top_bd->w / 2), top_bd->y + (top_bd->h / 2));
989                             
990                             if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
991                                e_border_focus_set(top_bd, 1, 1);
992                             else
993                               {
994                                  Eina_List* l2;
995                                  E_Border* temp_bd2;
996                                  l2 = NULL;
997                                  temp_bd2 = NULL;
998
999                                  bl = e_container_border_list_last(bd->zone->container);
1000                                  while ((temp_bd2 = e_container_border_list_prev(bl)))
1001                                    {
1002                                       if ((!temp_bd2->iconic) && (temp_bd2->visible) && (temp_bd2->desk == top_bd->desk) &&
1003                                          (temp_bd2->client.icccm.accepts_focus || temp_bd2->client.icccm.take_focus) &&
1004                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
1005                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
1006                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
1007                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
1008                                          (temp_bd2->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
1009                                         {
1010                                            if (top_bd == temp_bd2)
1011                                              {
1012                                                 e_border_focus_set(top_bd, 1, 1);
1013                                              }
1014                                             break;
1015                                         }
1016                                    }
1017                                  e_container_border_list_free(bl);
1018                               }
1019                          }
1020                     }
1021                }
1022           }
1023      }
1024 }
1025 #endif // group raise
1026
1027 static Eina_Bool
1028 _e_manager_cb_client_message(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
1029 {
1030    Ecore_X_Event_Client_Message *e;
1031    E_Border *bd;
1032
1033    e = ev;
1034
1035    if (e->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW)
1036      {
1037         bd = e_border_find_by_client_window(e->win);
1038         if ((bd) && (!bd->focused))
1039           {
1040 #if 0 /* notes */
1041              if (e->data.l[0] == 0 /* 0 == old, 1 == client, 2 == pager */)
1042                {
1043                   // FIXME: need config for the below - what to do given each
1044                   //  request (either do nothng, make app look urgent/want
1045                   //  attention or actiually flip to app as below is the
1046                   //  current default)
1047                   // if 0 == just make app demand attention somehow
1048                   // if 1 == just make app demand attention somehow
1049                   // if 2 == activate window as below
1050                }
1051              timestamp = e->data.l[1];
1052              requestor_id e->data.l[2];
1053 #endif
1054
1055 #ifdef _F_WINDOW_GROUP_RAISE_
1056              if (e->data.l[0] == 3) // 'e->data.l[0] == 3' means group raise
1057                {
1058                   if (bd->client.icccm.client_leader)
1059                     {
1060                        _e_manager_windows_group_raise (bd);
1061                        return ECORE_CALLBACK_PASS_ON;
1062                     }
1063                }
1064 #endif
1065
1066
1067 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1068              if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
1069                  (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
1070                  ((bd->parent) &&
1071                   ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
1072                    ((bd->parent->focused) &&
1073                             (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
1074 #else // original
1075              if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
1076                  ((bd->parent) &&
1077                   ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
1078                    ((bd->parent->focused) &&
1079                     (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
1080 #endif
1081                {
1082                   if (bd->iconic)
1083                     {
1084                        if (e_config->clientlist_warp_to_iconified_desktop == 1)
1085                          e_desk_show(bd->desk);
1086
1087                        if (!bd->lock_user_iconify)
1088                          e_border_uniconify(bd);
1089                     }
1090                   if ((!bd->iconic) && (!bd->sticky))
1091                     e_desk_show(bd->desk);
1092                   if (!bd->lock_user_stacking) e_border_raise(bd);
1093                   if (!bd->lock_focus_out)
1094                     {
1095                        /* XXX ooffice does send this request for
1096                        config dialogs when the main window gets focus.
1097                        causing the pointer to jump back and forth.  */
1098                        if ((e_config->focus_policy != E_FOCUS_CLICK) &&
1099                            !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
1100                          ecore_x_pointer_warp(bd->zone->container->win,
1101                                               bd->x + (bd->w / 2), bd->y + (bd->h / 2));
1102 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1103                        if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1104                          e_border_focus_set(bd, 1, 1);
1105                        else
1106                          {
1107                             Eina_List* l = NULL;
1108                             E_Border* temp_bd = NULL;
1109                             E_Border_List *bl;
1110
1111                             bl = e_container_border_list_last(bd->zone->container);
1112                             while ((temp_bd = e_container_border_list_prev(bl)))
1113                               {
1114                                  if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
1115                                      (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
1116                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
1117                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
1118                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
1119                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
1120                                      (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
1121                                    {
1122                                       if (bd == temp_bd)
1123                                         {
1124                                            e_border_focus_set(bd, 1, 1);
1125                                         }
1126                                       break;
1127                                    }
1128                               }
1129                             e_container_border_list_free(bl);
1130                          }
1131 #else // original
1132                        e_border_focus_set(bd, 1, 1);
1133 #endif
1134                     }
1135                }
1136           }
1137      }
1138
1139    return ECORE_CALLBACK_PASS_ON;
1140 }
1141
1142 static Eina_Bool
1143 _e_manager_frame_extents_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__,
1144                                  void *data, void *fdata __UNUSED__)
1145 {
1146    free(data);
1147    return EINA_TRUE;
1148 }
1149
1150 static E_Manager *
1151 _e_manager_get_for_root(Ecore_X_Window root)
1152 {
1153    Eina_List *l;
1154    E_Manager *man;
1155
1156    if (!managers) return NULL;
1157    EINA_LIST_FOREACH(managers, l, man)
1158      {
1159         if (man->root == root)
1160           return man;
1161      }
1162    return eina_list_data_get(managers);
1163 }
1164
1165
1166 #if 0 /* use later - maybe */
1167 static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev){return 1;}
1168 static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev){return 1;}
1169 static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev){return 1;}
1170 static int _e_manager_cb_window_create(void *data, int ev_type, void *ev){return 1;}
1171 static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev){return 1;}
1172 static int _e_manager_cb_window_configure(void *data, int ev_type, void *ev){return 1;}
1173 static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev){return 1;}
1174 static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev){return 1;}
1175 static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev){return 1;}
1176 static int _e_manager_cb_window_property(void *data, int ev_type, void *ev){return 1;}
1177 static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev){return 1;}
1178 static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev){return 1;}
1179 #endif