Added a policy to support such as quickpanel to rotate based Window manager.
[platform/core/uifw/e17-extra-modules.git] / illume2-tizen / src / e_mod_policy.c
1 #include "e_illume_private.h"
2 #include "e_mod_policy.h"
3
4 /* local function prototypes */
5 static char *_e_mod_policy_find(void);
6 static int _e_mod_policy_load(char *file);
7 static void _e_mod_policy_handlers_add(void);
8 static void _e_mod_policy_hooks_add(void);
9 static void _e_mod_policy_cb_free(E_Illume_Policy *p);
10 static Eina_Bool _e_mod_policy_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event);
11 static Eina_Bool _e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event);
12 static Eina_Bool _e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
13 static Eina_Bool _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
14 static Eina_Bool _e_mod_policy_cb_border_show(void *data __UNUSED__, int type __UNUSED__, void *event);
15 static Eina_Bool _e_mod_policy_cb_border_move(void *data __UNUSED__, int type __UNUSED__, void *event);
16 static Eina_Bool _e_mod_policy_cb_border_iconify(void *data __UNUSED__, int type __UNUSED__, void *event);
17 static Eina_Bool _e_mod_policy_cb_border_uniconify(void *data __UNUSED__, int type __UNUSED__, void *event);
18 static Eina_Bool _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event);
19 static Eina_Bool _e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event);
20 static Eina_Bool _e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event);
21 static Eina_Bool _e_mod_policy_cb_policy_change(void *data __UNUSED__, int type, void *event __UNUSED__);
22 static Eina_Bool _e_mod_policy_cb_window_configure_request (void *data __UNUSED__, int type __UNUSED__, void *event);
23 static Eina_Bool _e_mod_policy_cb_window_move_resize_request(void *data __UNUSED__, int type __UNUSED__, void *event);
24 static Eina_Bool _e_mod_policy_cb_window_state_request(void *data __UNUSED__, int type __UNUSED__, void *event);
25
26 static void _e_mod_policy_cb_hook_post_fetch(void *data __UNUSED__, void *data2);
27 static void _e_mod_policy_cb_hook_post_assign(void *data __UNUSED__, void *data2);
28 static void _e_mod_policy_cb_hook_layout(void *data __UNUSED__, void *data2 __UNUSED__);
29 static void _e_mod_policy_cb_hook_post_new_border (void *data __UNUSED__, void *data2);
30 static void _e_mod_policy_cb_hook_pre_fetch(void *data __UNUSED__, void *data2);
31 static void _e_mod_policy_cb_hook_new_border(void *data __UNUSED__, void *data2);
32 #ifdef _F_BORDER_HOOK_PATCH_
33 static void _e_mod_policy_cb_hook_del_border(void *data __UNUSED__, void *data2);
34 #endif
35 static void _e_mod_policy_cb_hook_rotation_list_add(void *data __UNUSED__, void *data2);
36
37 static Eina_Bool _e_mod_policy_cb_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
38
39 static int _e_mod_policy_init_atom (void);
40 static Eina_Bool _e_mod_policy_cb_border_stack(void *data __UNUSED__, int type __UNUSED__, void *event);
41 static Eina_Bool _e_mod_policy_cb_border_zone_set(void *data __UNUSED__, int type __UNUSED__, void *event);
42
43 /* for visibility */
44 static Eina_Bool _e_mod_policy_cb_window_create (void *data __UNUSED__, int type __UNUSED__, void *event);
45 static Eina_Bool _e_mod_policy_cb_window_destroy (void *data __UNUSED__, int type __UNUSED__, void *event);
46 static Eina_Bool _e_mod_policy_cb_window_reparent (void *data __UNUSED__, int type __UNUSED__, void *event);
47 static Eina_Bool _e_mod_policy_cb_window_show (void *data __UNUSED__, int type __UNUSED__, void *event);
48 static Eina_Bool _e_mod_policy_cb_window_hide (void *data __UNUSED__, int type __UNUSED__, void *event);
49 static Eina_Bool _e_mod_policy_cb_window_configure (void *data __UNUSED__, int type __UNUSED__, void *event);
50
51 static Eina_Bool _e_mod_policy_zonelist_update(void);
52 static Eina_Bool _e_mod_policy_cb_zone_add(void *data __UNUSED__, int type __UNUSED__, void *event);
53 static Eina_Bool _e_mod_policy_cb_zone_del(void *data __UNUSED__, int type __UNUSED__, void *event);
54
55 static Eina_Bool _e_mod_policy_cb_module_update(void *data __UNUSED__, int type __UNUSED__, void *event);
56
57 static Eina_Bool _e_mod_policy_cb_idle_enterer(void *data __UNUSED__);
58
59 /* local variables */
60 static E_Illume_Policy *_policy = NULL;
61 static Eina_List *_policy_hdls = NULL, *_policy_hooks = NULL;
62 Ecore_X_Atom E_ILLUME_BORDER_WIN_RESTACK;
63 static Ecore_X_Atom E_ILLUME_USER_CREATED_WINDOW = 0;
64 static Ecore_X_Atom E_ILLUME_PARENT_BORDER_WINDOW = 0;
65 static Ecore_X_Atom E_ILLUME_ZONE_GEOMETRY = 0;
66
67 static Ecore_X_Atom E_ILLUME_ATOM_DESK_TOP_WIN_DESK_CHANGE = 0;
68 static Ecore_X_Atom E_ILLUME_ATOM_DESK_NEXT_SHOW = 0;
69
70 static Ecore_Idle_Enterer *_idle_enterer = NULL;
71
72 /* external variables */
73 int E_ILLUME_POLICY_EVENT_CHANGE = 0;
74
75 int
76 e_mod_policy_init(void)
77 {
78    Eina_List *ml;
79    E_Manager *man;
80    char *file;
81
82    if (!_e_mod_policy_init_atom())
83      {
84         /* creating atom failed, bail out */
85         printf ("Cannot create atom\n");
86         return 0;
87      }
88
89    /* try to find the policy specified in config */
90    if (!(file = _e_mod_policy_find()))
91      {
92         printf("Cannot find policy\n");
93         return 0;
94      }
95
96    /* attempt to load policy */
97    if (!_e_mod_policy_load(file))
98      {
99         /* loading policy failed, bail out */
100         printf("Cannot load policy: %s\n", file);
101         if (file) free(file);
102         return 0;
103      }
104
105    /* create new event for policy changes */
106    E_ILLUME_POLICY_EVENT_CHANGE = ecore_event_type_new();
107
108    /* add our event handlers */
109    _e_mod_policy_handlers_add();
110
111    /* add our border hooks */
112    _e_mod_policy_hooks_add();
113
114    _idle_enterer = ecore_idle_enterer_add(_e_mod_policy_cb_idle_enterer, NULL);
115
116    /* loop the root windows */
117    EINA_LIST_FOREACH(e_manager_list(), ml, man)
118      {
119         Eina_List *cl;
120         E_Container *con;
121
122         if (!man) continue;
123
124         /* loop the containers */
125         EINA_LIST_FOREACH(man->containers, cl, con)
126           {
127              Eina_List *zl;
128              E_Zone *zone;
129
130              if (!con) continue;
131
132              /* loop the zones */
133              EINA_LIST_FOREACH(con->zones, zl, zone)
134                {
135                   E_Illume_Config_Zone *cz;
136                   Ecore_X_Illume_Mode mode = ECORE_X_ILLUME_MODE_SINGLE;
137
138                   if (!zone) continue;
139
140                   /* check for zone config */
141                   if (!(cz = e_illume_zone_config_get(zone->id)))
142                     continue;
143
144                   /* set mode on this zone */
145                   if (cz->mode.dual == 0)
146                     mode = ECORE_X_ILLUME_MODE_SINGLE;
147                   else
148                     {
149                        if ((cz->mode.dual == 1) && (cz->mode.side == 0))
150                          mode = ECORE_X_ILLUME_MODE_DUAL_TOP;
151                        else if ((cz->mode.dual == 1) && (cz->mode.side == 1))
152                          mode = ECORE_X_ILLUME_MODE_DUAL_LEFT;
153                     }
154                   ecore_x_e_illume_mode_set(zone->black_win, mode);
155                }
156           }
157      }
158
159    if (file) free(file);
160    return 1;
161 }
162
163 int
164 e_mod_policy_shutdown(void)
165 {
166    Ecore_Event_Handler *hdl;
167    E_Border_Hook *hook;
168
169    /* remove the ecore event handlers */
170    EINA_LIST_FREE(_policy_hdls, hdl)
171      ecore_event_handler_del(hdl);
172
173    /* remove the border hooks */
174    EINA_LIST_FREE(_policy_hooks, hook)
175      e_border_hook_del(hook);
176
177    if (_idle_enterer) ecore_idle_enterer_del(_idle_enterer);
178    _idle_enterer = NULL;
179
180    /* destroy the policy if it exists */
181    if (_policy) e_object_del(E_OBJECT(_policy));
182
183    /* reset event type */
184    E_ILLUME_POLICY_EVENT_CHANGE = 0;
185
186    return 1;
187 }
188
189 /* local functions */
190 static char *
191 _e_mod_policy_find(void)
192 {
193    Eina_List *files;
194    char buff[PATH_MAX], dir[PATH_MAX], *file;
195
196    snprintf(buff, sizeof(buff), "%s.so", _e_illume_cfg->policy.name);
197    snprintf(dir, sizeof(dir), "%s/policies", _e_illume_mod_dir);
198
199    /* try to list all files in this directory */
200    if (!(files = ecore_file_ls(dir))) return NULL;
201
202    /* loop the returned files */
203    EINA_LIST_FREE(files, file)
204      {
205         /* compare file with needed .so */
206         if (!strcmp(file, buff))
207           {
208              snprintf(dir, sizeof(dir), "%s/policies/%s",
209                       _e_illume_mod_dir, file);
210              break;
211           }
212         free(file);
213      }
214    if (file) free(file);
215    else
216      {
217         /* if we did not find the requested policy, use a fallback */
218         snprintf(dir, sizeof(dir), "%s/policies/illume.so", _e_illume_mod_dir);
219      }
220
221    return strdup(dir);
222 }
223
224 static int
225 _e_mod_policy_load(char *file)
226 {
227    /* safety check */
228    if (!file) return 0;
229
230    /* delete existing policy first */
231    if (_policy) e_object_del(E_OBJECT(_policy));
232
233    /* try to create our new policy object */
234    _policy =
235      E_OBJECT_ALLOC(E_Illume_Policy, E_ILLUME_POLICY_TYPE,
236                     _e_mod_policy_cb_free);
237    if (!_policy)
238      {
239         printf("Failed to allocate new policy object\n");
240         return 0;
241      }
242
243    /* attempt to open the .so */
244    if (!(_policy->handle = dlopen(file, (RTLD_NOW | RTLD_GLOBAL))))
245      {
246         /* cannot open the .so file, bail out */
247         printf("Cannot open policy: %s\n", ecore_file_file_get(file));
248         printf("\tError: %s\n", dlerror());
249         e_object_del(E_OBJECT(_policy));
250         return 0;
251      }
252
253    /* clear any existing errors in dynamic loader */
254    dlerror();
255
256    /* try to link to the needed policy api functions */
257    _policy->api = dlsym(_policy->handle, "e_illume_policy_api");
258    _policy->funcs.init = dlsym(_policy->handle, "e_illume_policy_init");
259    _policy->funcs.shutdown = dlsym(_policy->handle, "e_illume_policy_shutdown");
260
261    /* check that policy supports needed functions */
262    if ((!_policy->api) || (!_policy->funcs.init) || (!_policy->funcs.shutdown))
263      {
264         /* policy doesn't support needed functions, bail out */
265         printf("Policy does not support needed functions: %s\n",
266                ecore_file_file_get(file));
267         printf("\tError: %s\n", dlerror());
268         e_object_del(E_OBJECT(_policy));
269         return 0;
270      }
271
272    /* check policy api version */
273    if (_policy->api->version < E_ILLUME_POLICY_API_VERSION)
274      {
275         /* policy is too old, bail out */
276         printf("Policy is too old: %s\n", ecore_file_file_get(file));
277         e_object_del(E_OBJECT(_policy));
278         return 0;
279      }
280
281    /* try to initialize the policy */
282    if (!_policy->funcs.init(_policy))
283      {
284         /* init failed, bail out */
285         printf("Policy failed to initialize: %s\n", ecore_file_file_get(file));
286         e_object_del(E_OBJECT(_policy));
287         return 0;
288      }
289
290    return 1;
291 }
292
293 static void
294 _e_mod_policy_handlers_add(void)
295 {
296    _policy_hdls =
297      eina_list_append(_policy_hdls,
298                       ecore_event_handler_add(E_EVENT_BORDER_ADD,
299                                               _e_mod_policy_cb_border_add, NULL));
300    _policy_hdls =
301      eina_list_append(_policy_hdls,
302                       ecore_event_handler_add(E_EVENT_BORDER_REMOVE,
303                                               _e_mod_policy_cb_border_del, NULL));
304    _policy_hdls =
305      eina_list_append(_policy_hdls,
306                       ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN,
307                                               _e_mod_policy_cb_border_focus_in,
308                                               NULL));
309    _policy_hdls =
310      eina_list_append(_policy_hdls,
311                       ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT,
312                                               _e_mod_policy_cb_border_focus_out,
313                                               NULL));
314    _policy_hdls =
315      eina_list_append(_policy_hdls,
316                       ecore_event_handler_add(E_EVENT_BORDER_SHOW,
317                                               _e_mod_policy_cb_border_show,
318                                               NULL));
319    _policy_hdls =
320      eina_list_append(_policy_hdls,
321                       ecore_event_handler_add(E_EVENT_BORDER_MOVE,
322                                               _e_mod_policy_cb_border_move,
323                                               NULL));
324
325    _policy_hdls =
326      eina_list_append(_policy_hdls,
327                       ecore_event_handler_add(E_EVENT_BORDER_STACK,
328                                               _e_mod_policy_cb_border_stack,
329                                               NULL));
330    _policy_hdls =
331      eina_list_append(_policy_hdls,
332                       ecore_event_handler_add(E_EVENT_BORDER_ZONE_SET,
333                                               _e_mod_policy_cb_border_zone_set, NULL));
334
335    _policy_hdls =
336      eina_list_append(_policy_hdls,
337                       ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
338                                               _e_mod_policy_cb_zone_move_resize,
339                                               NULL));
340    _policy_hdls =
341      eina_list_append(_policy_hdls,
342                       ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
343                                               _e_mod_policy_cb_client_message,
344                                               NULL));
345    _policy_hdls =
346      eina_list_append(_policy_hdls,
347                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
348                                               _e_mod_policy_cb_window_property,
349                                               NULL));
350    _policy_hdls =
351      eina_list_append(_policy_hdls,
352                       ecore_event_handler_add(E_ILLUME_POLICY_EVENT_CHANGE,
353                                               _e_mod_policy_cb_policy_change,
354                                               NULL));
355
356    _policy_hdls =
357      eina_list_append(_policy_hdls,
358                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN,
359                                               _e_mod_policy_cb_window_focus_in,
360                                               NULL));
361
362    /* for visibility */
363    _policy_hdls =
364      eina_list_append(_policy_hdls,
365                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE,
366                                               _e_mod_policy_cb_window_create,
367                                               NULL));
368    _policy_hdls =
369      eina_list_append(_policy_hdls,
370                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY,
371                                               _e_mod_policy_cb_window_destroy,
372                                               NULL));
373    _policy_hdls =
374      eina_list_append(_policy_hdls,
375                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT,
376                                               _e_mod_policy_cb_window_reparent,
377                                               NULL));
378    _policy_hdls =
379      eina_list_append(_policy_hdls,
380                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW,
381                                               _e_mod_policy_cb_window_show,
382                                               NULL));
383    _policy_hdls =
384      eina_list_append(_policy_hdls,
385                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE,
386                                               _e_mod_policy_cb_window_hide,
387                                               NULL));
388    _policy_hdls =
389      eina_list_append(_policy_hdls,
390                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE,
391                                               _e_mod_policy_cb_window_configure,
392                                               NULL));
393
394    _policy_hdls =
395      eina_list_append(_policy_hdls,
396                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST,
397                                               _e_mod_policy_cb_window_configure_request,
398                                               NULL));
399    _policy_hdls =
400      eina_list_append(_policy_hdls,
401                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST,
402                                               _e_mod_policy_cb_window_move_resize_request, NULL));
403    _policy_hdls =
404      eina_list_append(_policy_hdls,
405                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST,
406                                               _e_mod_policy_cb_window_state_request,
407                                               NULL));
408
409    _policy_hdls =
410      eina_list_append(_policy_hdls,
411                       ecore_event_handler_add(E_EVENT_ZONE_ADD,
412                                               _e_mod_policy_cb_zone_add, NULL));
413    _policy_hdls =
414      eina_list_append(_policy_hdls,
415                       ecore_event_handler_add(E_EVENT_ZONE_DEL,
416                                               _e_mod_policy_cb_zone_del, NULL));
417
418
419    _policy_hdls =
420      eina_list_append(_policy_hdls,
421                       ecore_event_handler_add(E_EVENT_BORDER_ICONIFY,
422                                               _e_mod_policy_cb_border_iconify,
423                                               NULL));
424
425    _policy_hdls =
426      eina_list_append(_policy_hdls,
427                       ecore_event_handler_add(E_EVENT_BORDER_UNICONIFY,
428                                               _e_mod_policy_cb_border_uniconify,
429                                               NULL));
430
431
432    _policy_hdls =
433      eina_list_append(_policy_hdls,
434                       ecore_event_handler_add(E_EVENT_MODULE_UPDATE,
435                                               _e_mod_policy_cb_module_update,
436                                               NULL));
437 }
438
439 static void
440 _e_mod_policy_hooks_add(void)
441 {
442    _policy_hooks =
443      eina_list_append(_policy_hooks,
444                       e_border_hook_add(E_BORDER_HOOK_EVAL_POST_FETCH,
445                                         _e_mod_policy_cb_hook_post_fetch, NULL));
446    _policy_hooks =
447      eina_list_append(_policy_hooks,
448                       e_border_hook_add(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN,
449                                         _e_mod_policy_cb_hook_post_assign, NULL));
450    _policy_hooks =
451      eina_list_append(_policy_hooks,
452                       e_border_hook_add(E_BORDER_HOOK_CONTAINER_LAYOUT,
453                                         _e_mod_policy_cb_hook_layout, NULL));
454    _policy_hooks =
455      eina_list_append(_policy_hooks,
456                       e_border_hook_add(E_BORDER_HOOK_EVAL_POST_NEW_BORDER,
457                                         _e_mod_policy_cb_hook_post_new_border, NULL));
458    _policy_hooks =
459      eina_list_append(_policy_hooks,
460                       e_border_hook_add(E_BORDER_HOOK_EVAL_PRE_FETCH,
461                                         _e_mod_policy_cb_hook_pre_fetch, NULL));
462    _policy_hooks =
463      eina_list_append(_policy_hooks,
464                       e_border_hook_add(E_BORDER_HOOK_NEW_BORDER,
465                                         _e_mod_policy_cb_hook_new_border, NULL));
466 #ifdef _F_BORDER_HOOK_PATCH_
467    _policy_hooks =
468      eina_list_append(_policy_hooks,
469                       e_border_hook_add(E_BORDER_HOOK_DEL_BORDER,
470                                         _e_mod_policy_cb_hook_del_border, NULL));
471 #endif
472    _policy_hooks =
473      eina_list_append(_policy_hooks,
474                       e_border_hook_add(E_BORDER_HOOK_ROTATION_LIST_ADD,
475                                         _e_mod_policy_cb_hook_rotation_list_add, NULL));
476 }
477
478 static void
479 _e_mod_policy_cb_free(E_Illume_Policy *p)
480 {
481    if (!p) return;
482
483    /* tell the policy to shutdown */
484    if (p->funcs.shutdown) p->funcs.shutdown(p);
485    p->funcs.shutdown = NULL;
486
487    p->funcs.init = NULL;
488    p->api = NULL;
489
490    /* close the linked .so */
491    if (p->handle) dlclose(p->handle);
492    p->handle = NULL;
493
494    E_FREE(p);
495 }
496
497 static Eina_Bool
498 _e_mod_policy_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event)
499 {
500    E_Event_Border_Add *ev;
501
502    ev = event;
503
504    if ((_policy) && (_policy->funcs.border_add))
505      _policy->funcs.border_add(ev->border);
506
507    return ECORE_CALLBACK_PASS_ON;
508 }
509
510 static Eina_Bool
511 _e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event)
512 {
513    E_Event_Border_Remove *ev;
514
515    ev = event;
516
517    ecore_x_window_prop_property_del(ev->border->client.win, E_ILLUME_PARENT_BORDER_WINDOW);
518
519    if ((_policy) && (_policy->funcs.border_del))
520      _policy->funcs.border_del(ev->border);
521
522    return ECORE_CALLBACK_PASS_ON;
523 }
524
525 static Eina_Bool
526 _e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
527 {
528    E_Event_Border_Focus_In *ev;
529
530    ev = event;
531    if ((_policy) && (_policy->funcs.border_focus_in))
532      _policy->funcs.border_focus_in(ev->border);
533
534    return ECORE_CALLBACK_PASS_ON;
535 }
536
537 static Eina_Bool
538 _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
539 {
540    E_Event_Border_Focus_Out *ev;
541
542    ev = event;
543    if ((_policy) && (_policy->funcs.border_focus_out))
544      _policy->funcs.border_focus_out(ev->border);
545
546    return ECORE_CALLBACK_PASS_ON;
547 }
548
549 static Eina_Bool
550 _e_mod_policy_cb_border_show(void *data __UNUSED__, int type __UNUSED__, void *event)
551 {
552    E_Event_Border_Show *ev;
553
554    ev = event;
555    if ((_policy) && (_policy->funcs.border_show))
556      _policy->funcs.border_show(ev->border);
557
558    return ECORE_CALLBACK_PASS_ON;
559 }
560
561 static Eina_Bool
562 _e_mod_policy_cb_border_move(void *data __UNUSED__, int type __UNUSED__, void *event)
563 {
564    E_Event_Border_Move *ev;
565
566    ev = event;
567    if ((_policy) && (_policy->funcs.border_move))
568      _policy->funcs.border_move(ev->border);
569
570    return ECORE_CALLBACK_PASS_ON;
571 }
572
573 static Eina_Bool
574 _e_mod_policy_cb_border_iconify(void *data __UNUSED__, int type __UNUSED__, void *event)
575 {
576    E_Event_Border_Iconify *ev;
577
578    ev = event;
579    if ((_policy) && (_policy->funcs.border_iconify_cb))
580      _policy->funcs.border_iconify_cb(ev->border);
581
582    return ECORE_CALLBACK_PASS_ON;
583 }
584
585 static Eina_Bool
586 _e_mod_policy_cb_border_uniconify(void *data __UNUSED__, int type __UNUSED__, void *event)
587 {
588    E_Event_Border_Uniconify *ev;
589
590    ev = event;
591    if ((_policy) && (_policy->funcs.border_uniconify_cb))
592      _policy->funcs.border_uniconify_cb(ev->border);
593
594    return ECORE_CALLBACK_PASS_ON;
595 }
596
597 static Eina_Bool
598 _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
599 {
600    E_Event_Zone_Move_Resize *ev;
601
602    ev = event;
603    if ((_policy) && (_policy->funcs.zone_move_resize))
604      _policy->funcs.zone_move_resize(ev->zone);
605
606    return ECORE_CALLBACK_PASS_ON;
607 }
608
609 static Eina_Bool
610 _e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event)
611 {
612    Ecore_X_Event_Client_Message *ev;
613
614    ev = event;
615    if (ev->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW)
616      {
617         E_Border *bd;
618
619         if (!(bd = e_border_find_by_client_window(ev->win))) return ECORE_CALLBACK_PASS_ON;
620         if ((_policy) && (_policy->funcs.border_activate))
621           _policy->funcs.border_activate(bd);
622      }
623    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_MODE)
624      {
625         E_Zone *zone;
626
627         if (!(zone = e_util_zone_window_find(ev->win))) return ECORE_CALLBACK_PASS_ON;
628         if ((_policy) && (_policy->funcs.zone_mode_change))
629           _policy->funcs.zone_mode_change(zone, ev->data.l[0]);
630      }
631    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_CLOSE)
632      {
633         E_Zone *zone;
634
635         if (!(zone = e_util_zone_window_find(ev->win))) return ECORE_CALLBACK_PASS_ON;
636         if ((_policy) && (_policy->funcs.zone_close))
637           _policy->funcs.zone_close(zone);
638      }
639    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_FOCUS_BACK)
640      {
641         E_Zone *zone;
642
643         if (!(zone = e_util_zone_window_find(ev->win))) return ECORE_CALLBACK_PASS_ON;
644         if ((_policy) && (_policy->funcs.focus_back))
645           _policy->funcs.focus_back(zone);
646      }
647    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD)
648      {
649         E_Zone *zone;
650
651         if (!(zone = e_util_zone_window_find(ev->win))) return ECORE_CALLBACK_PASS_ON;
652         if ((_policy) && (_policy->funcs.focus_forward))
653           _policy->funcs.focus_forward(zone);
654      }
655    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_DRAG_START)
656      {
657         E_Border *bd;
658
659         if (!(bd = e_border_find_by_client_window(ev->win))) return ECORE_CALLBACK_PASS_ON;
660         if ((_policy) && (_policy->funcs.drag_start))
661           _policy->funcs.drag_start(bd);
662      }
663    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_DRAG_END)
664      {
665         E_Border *bd;
666
667         if (!(bd = e_border_find_by_client_window(ev->win))) return ECORE_CALLBACK_PASS_ON;
668         if ((_policy) && (_policy->funcs.drag_end))
669           _policy->funcs.drag_end(bd);
670      }
671    else if (ev->message_type == E_ILLUME_BORDER_WIN_RESTACK)
672      {
673         E_Border *bd;
674         E_Border *bd_sibling;
675
676         if (!(bd = e_border_find_by_client_window(ev->win))) return 1;
677         if (!(bd_sibling = e_border_find_by_client_window((Ecore_X_Window) ev->data.l[0]))) return 1;
678
679         if ((_policy) && (_policy->funcs.border_restack_request))
680           _policy->funcs.border_restack_request(bd, bd_sibling, ev->data.l[1]);
681      }
682    else if (ev->message_type == ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE)
683      {
684         if ((_policy) && (_policy->funcs.window_sync_draw_done))
685           _policy->funcs.window_sync_draw_done(ev);
686      }
687    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
688      {
689         if ((_policy) && (_policy->funcs.quickpanel_state_change))
690           _policy->funcs.quickpanel_state_change(ev);
691      }
692    else if (ev->message_type == E_ILLUME_ATOM_DESK_TOP_WIN_DESK_CHANGE)
693      {
694         if ((_policy) && (_policy->funcs.window_desk_set))
695           _policy->funcs.window_desk_set(ev);
696      }
697    else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
698      {
699         if ((_policy) && (_policy->funcs.illume_win_state_change_request))
700           _policy->funcs.illume_win_state_change_request(ev);
701      }
702
703    return ECORE_CALLBACK_PASS_ON;
704 }
705
706 static Eina_Bool
707 _e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event)
708 {
709    Ecore_X_Event_Window_Property *ev;
710
711    ev = event;
712    if ((_policy) && (_policy->funcs.property_change))
713      _policy->funcs.property_change(ev);
714
715    return ECORE_CALLBACK_PASS_ON;
716 }
717
718 static Eina_Bool
719 _e_mod_policy_cb_policy_change(void *data __UNUSED__, int type, void *event __UNUSED__)
720 {
721    char *file;
722
723    if (type != E_ILLUME_POLICY_EVENT_CHANGE) return ECORE_CALLBACK_PASS_ON;
724
725    /* find policy specified in config */
726    if (!(file = _e_mod_policy_find())) return ECORE_CALLBACK_PASS_ON;
727
728    /* try to load the policy */
729    _e_mod_policy_load(file);
730
731    if (file) free(file);
732
733    return ECORE_CALLBACK_PASS_ON;
734 }
735
736 static void
737 _e_mod_policy_cb_hook_post_fetch(void *data __UNUSED__, void *data2)
738 {
739    E_Border *bd;
740
741    if (!(bd = data2)) return;
742    if ((_policy) && (_policy->funcs.border_post_fetch))
743      _policy->funcs.border_post_fetch(bd);
744 }
745
746 static void
747 _e_mod_policy_cb_hook_post_assign(void *data __UNUSED__, void *data2)
748 {
749    E_Border *bd;
750
751    if (!(bd = data2)) return;
752    if ((_policy) && (_policy->funcs.border_post_assign))
753      _policy->funcs.border_post_assign(bd);
754 }
755
756 static void
757 _e_mod_policy_cb_hook_post_new_border (void *data __UNUSED__, void *data2)
758 {
759    E_Border *bd;
760
761    if (!(bd = data2)) return;
762    if ((_policy) && (_policy->funcs.border_post_new_border))
763      _policy->funcs.border_post_new_border(bd);
764 }
765
766 static void _e_mod_policy_cb_hook_pre_fetch(void *data __UNUSED__, void *data2)
767 {
768    E_Border *bd;
769
770    if (!(bd = data2)) return;
771    if ((_policy) && (_policy->funcs.border_pre_fetch))
772      _policy->funcs.border_pre_fetch(bd);
773 }
774
775 static void
776 _e_mod_policy_cb_hook_new_border(void *data __UNUSED__, void *data2)
777 {
778    E_Border *bd;
779
780    if (!(bd = data2)) return;
781
782    ecore_x_window_prop_window_set(bd->win, E_ILLUME_USER_CREATED_WINDOW, &(bd->client.win), 1);
783    ecore_x_window_prop_window_set(bd->client.win, E_ILLUME_PARENT_BORDER_WINDOW, &(bd->win), 1);
784
785    if ((_policy) && (_policy->funcs.border_new_border))
786      _policy->funcs.border_new_border(bd);
787 }
788
789 #ifdef _F_BORDER_HOOK_PATCH_
790 static void
791 _e_mod_policy_cb_hook_del_border(void *data __UNUSED__, void *data2)
792 {
793    E_Border *bd;
794
795    if (!(bd = data2)) return;
796    if ((_policy) && (_policy->funcs.border_del_border))
797      _policy->funcs.border_del_border(bd);
798 }
799
800 #endif
801
802 static Eina_Bool
803 _e_mod_policy_cb_window_configure_request (void *data __UNUSED__, int type __UNUSED__, void *event)
804 {
805    Ecore_X_Event_Window_Configure_Request* ev = event;
806
807    if ((_policy) && (_policy->funcs.window_configure_request))
808      _policy->funcs.window_configure_request(ev);
809
810    return ECORE_CALLBACK_PASS_ON;
811 }
812
813 static Eina_Bool
814 _e_mod_policy_cb_window_move_resize_request(void *data __UNUSED__, int type __UNUSED__, void *event)
815 {
816    Ecore_X_Event_Window_Move_Resize_Request *ev = event;
817
818    if ((_policy) && (_policy->funcs.window_move_resize_request))
819      _policy->funcs.window_move_resize_request(ev);
820
821    return ECORE_CALLBACK_PASS_ON;
822 }
823
824 static Eina_Bool
825 _e_mod_policy_cb_window_state_request(void *data __UNUSED__, int type __UNUSED__, void *event)
826 {
827    Ecore_X_Event_Window_State_Request *ev = event;
828
829    if ((_policy) && (_policy->funcs.window_state_request))
830      _policy->funcs.window_state_request(ev);
831
832    return ECORE_CALLBACK_PASS_ON;
833 }
834
835 static void
836 _e_mod_policy_cb_hook_layout(void *data __UNUSED__, void *data2 __UNUSED__)
837 {
838    E_Zone *zone;
839    E_Border *bd;
840    Eina_List *zl = NULL, *l;
841
842    /* loop through border list and find what changed */
843    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
844      {
845         if (!bd) continue;
846         if ((bd->new_client) || (bd->pending_move_resize) ||
847             (bd->changes.pos) || (bd->changes.size) || (bd->changes.visible) ||
848             (bd->need_shape_export) || (bd->need_shape_merge))
849           {
850              /* NB: this border changed. add it's zone to list of what needs
851               * updating. This is done so we do not waste cpu cycles
852               * updating zones where nothing changed */
853              if (!eina_list_data_find(zl, bd->zone))
854                zl = eina_list_append(zl, bd->zone);
855           }
856      }
857
858    /* loop the zones that need updating and call the policy update function */
859    EINA_LIST_FREE(zl, zone)
860      {
861         if ((_policy) && (_policy->funcs.zone_layout))
862           _policy->funcs.zone_layout(zone);
863      }
864 }
865
866 static Eina_Bool
867 _e_mod_policy_cb_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
868 {
869    Ecore_X_Event_Window_Focus_In *ev;
870
871    ev = event;
872    if ((_policy) && (_policy->funcs.window_focus_in))
873      _policy->funcs.window_focus_in(ev);
874
875    return ECORE_CALLBACK_PASS_ON;
876 }
877
878 static int
879 _e_mod_policy_init_atom (void)
880 {
881    E_ILLUME_BORDER_WIN_RESTACK = ecore_x_atom_get ("_E_ILLUME_RESTACK_WINDOW");
882    if (!E_ILLUME_BORDER_WIN_RESTACK)
883      {
884         fprintf (stderr, "[ILLUME2] Critical Error!!! Cannot create _E_ILLUME_RESTACK_WINDOW Atom...\n");
885         return 0;
886      }
887
888    E_ILLUME_USER_CREATED_WINDOW = ecore_x_atom_get("_E_USER_CREATED_WINDOW");
889    if (!E_ILLUME_USER_CREATED_WINDOW)
890      {
891         fprintf(stderr,
892                 "[ILLUME2] cannot create _E_USER_CREATED_WINDOW atom.\n");
893         return 0;
894      }
895
896    E_ILLUME_PARENT_BORDER_WINDOW = ecore_x_atom_get("_E_PARENT_BORDER_WINDOW");
897    if (!E_ILLUME_PARENT_BORDER_WINDOW)
898      {
899         fprintf(stderr,
900                 "[ILLUME2] cannot create _E_PARENT_BORDER_WINDOW atom.\n");
901         return 0;
902      }
903
904    E_ILLUME_ZONE_GEOMETRY = ecore_x_atom_get("_E_ILLUME_ZONE_GEOMETRY");
905    if (!E_ILLUME_ZONE_GEOMETRY)
906      {
907         fprintf(stderr,
908                 "[ILLUME2] cannot create _E_ILLUME_ZONE_GEOMETRY atom.\n");
909         return 0;
910      }
911
912    E_ILLUME_ATOM_DESK_TOP_WIN_DESK_CHANGE =
913       ecore_x_atom_get ("_E_ILLUME_ATOM_DESK_TOP_WIN_DESK_CHANGE");
914    if(!E_ILLUME_ATOM_DESK_TOP_WIN_DESK_CHANGE)
915      {
916         fprintf (stderr, "[ILLUME2] Critical Error!!! Cannot create _E_COMP_ENABLE Atom...\n");
917         return 0;
918      }
919
920    E_ILLUME_ATOM_DESK_NEXT_SHOW =
921       ecore_x_atom_get ("_E_ILLUME_ATOM_DESK_NEXT_SHOW");
922    if(!E_ILLUME_ATOM_DESK_NEXT_SHOW)
923      {
924         fprintf (stderr, "[ILLUME2] Critical Error!!! Cannot create _E_COMP_ENABLE Atom...\n");
925         return 0;
926      }
927
928    return 1;
929 }
930
931 static Eina_Bool
932 _e_mod_policy_cb_border_stack(void *data __UNUSED__, int type __UNUSED__, void *event)
933 {
934    E_Event_Border_Stack *ev;
935
936    ev = event;
937    if ((_policy) && (_policy->funcs.border_stack))
938      _policy->funcs.border_stack(ev);
939
940    return ECORE_CALLBACK_PASS_ON;
941 }
942
943 static Eina_Bool
944 _e_mod_policy_cb_border_zone_set(void *data __UNUSED__, int type __UNUSED__, void *event)
945 {
946    E_Event_Border_Zone_Set *ev;
947    ev = event;
948
949    if ((_policy) && (_policy->funcs.border_zone_set))
950      _policy->funcs.border_zone_set(ev);
951
952    return ECORE_CALLBACK_PASS_ON;
953 }
954
955 /* for visibility */
956 static Eina_Bool
957 _e_mod_policy_cb_window_create (void *data __UNUSED__, int type __UNUSED__, void *event)
958 {
959    Ecore_X_Event_Window_Create* ev = event;
960
961    if ((_policy) && (_policy->funcs.window_create))
962      _policy->funcs.window_create(ev);
963
964    return ECORE_CALLBACK_PASS_ON;
965 }
966
967 static Eina_Bool
968 _e_mod_policy_cb_window_destroy (void *data __UNUSED__, int type __UNUSED__, void *event)
969 {
970    Ecore_X_Event_Window_Destroy* ev = event;
971
972    if ((_policy) && (_policy->funcs.window_destroy))
973      _policy->funcs.window_destroy(ev);
974
975    return ECORE_CALLBACK_PASS_ON;
976 }
977
978 static Eina_Bool
979 _e_mod_policy_cb_window_reparent (void *data __UNUSED__, int type __UNUSED__, void *event)
980 {
981    Ecore_X_Event_Window_Reparent* ev = event;
982
983    if ((_policy) && (_policy->funcs.window_reparent))
984      _policy->funcs.window_reparent(ev);
985
986    return ECORE_CALLBACK_PASS_ON;
987 }
988
989 static Eina_Bool
990 _e_mod_policy_cb_window_show (void *data __UNUSED__, int type __UNUSED__, void *event)
991 {
992    Ecore_X_Event_Window_Show* ev = event;
993
994    if ((_policy) && (_policy->funcs.window_show))
995      _policy->funcs.window_show(ev);
996
997    return ECORE_CALLBACK_PASS_ON;
998 }
999
1000 static Eina_Bool
1001 _e_mod_policy_cb_window_hide (void *data __UNUSED__, int type __UNUSED__, void *event)
1002 {
1003    Ecore_X_Event_Window_Hide* ev = event;
1004
1005    if ((_policy) && (_policy->funcs.window_hide))
1006      _policy->funcs.window_hide(ev);
1007
1008    return ECORE_CALLBACK_PASS_ON;
1009 }
1010
1011 static Eina_Bool
1012 _e_mod_policy_cb_window_configure (void *data __UNUSED__, int type __UNUSED__, void *event)
1013 {
1014    Ecore_X_Event_Window_Configure* ev = event;
1015
1016    if ((_policy) && (_policy->funcs.window_configure))
1017      _policy->funcs.window_configure(ev);
1018
1019    return ECORE_CALLBACK_PASS_ON;
1020 }
1021
1022 static Eina_Bool
1023 _e_mod_policy_zonelist_update(void)
1024 {
1025    Eina_List *ml, *cl, *zl;
1026    E_Manager *man;
1027    E_Container *con;
1028    E_Zone *zone;
1029    Ecore_X_Window *zones;
1030    int zcount = 0;
1031
1032    /* loop zones and get count */
1033    EINA_LIST_FOREACH(e_manager_list(), ml, man)
1034      {
1035         if (!man) continue;
1036         EINA_LIST_FOREACH(man->containers, cl, con)
1037           {
1038              if (!con) continue;
1039              EINA_LIST_FOREACH(con->zones, zl, zone)
1040                 zcount++;
1041           }
1042      }
1043
1044    /* allocate enough zones */
1045    zones = calloc(zcount, sizeof(Ecore_X_Window));
1046    if (!zones) return EINA_FALSE;
1047
1048    zcount = 0;
1049
1050    /* loop the zones and set zone list */
1051    EINA_LIST_FOREACH(e_manager_list(), ml, man)
1052      {
1053         if (!man) continue;
1054         EINA_LIST_FOREACH(man->containers, cl, con)
1055           {
1056              if (!con) continue;
1057              EINA_LIST_FOREACH(con->zones, zl, zone)
1058                {
1059                   if (!zone) continue;
1060
1061                   zones[zcount] = zone->black_win;
1062                   zcount++;
1063                }
1064           }
1065
1066         ecore_x_e_illume_zone_list_set(man->root, zones, zcount);
1067      }
1068
1069    free(zones);
1070    return EINA_TRUE;
1071 }
1072
1073 static Eina_Bool
1074 _e_mod_policy_cb_zone_add(void *data __UNUSED__, int type __UNUSED__, void *event)
1075 {
1076    E_Event_Zone_Add *ev;
1077    E_Zone *zone;
1078    unsigned int geom[4];
1079
1080    ev = event;
1081    zone = ev->zone;
1082
1083    geom[0] = zone->x;
1084    geom[1] = zone->y;
1085    geom[2] = zone->w;
1086    geom[3] = zone->h;
1087    ecore_x_window_prop_card32_set(zone->black_win, E_ILLUME_ZONE_GEOMETRY,
1088                                   geom, 4);
1089
1090    _e_mod_policy_zonelist_update();
1091
1092    return ECORE_CALLBACK_PASS_ON;
1093 }
1094
1095 static Eina_Bool
1096 _e_mod_policy_cb_zone_del(void *data __UNUSED__, int type __UNUSED__, void *event)
1097 {
1098    E_Event_Zone_Del *ev;
1099    E_Zone *zone;
1100
1101    ev = event;
1102    zone = ev->zone;
1103
1104    _e_mod_policy_zonelist_update();
1105
1106    return ECORE_CALLBACK_PASS_ON;
1107 }
1108
1109 static Eina_Bool
1110 _e_mod_policy_cb_module_update(void *data __UNUSED__, int type __UNUSED__, void *event)
1111 {
1112    E_Event_Module_Update *ev;
1113    ev = event;
1114
1115    if ((_policy) && (_policy->funcs.module_update))
1116      _policy->funcs.module_update(ev);
1117
1118    return ECORE_CALLBACK_PASS_ON;
1119 }
1120
1121 static Eina_Bool
1122 _e_mod_policy_cb_idle_enterer(void *data __UNUSED__)
1123 {
1124    if ((_policy) && (_policy->funcs.idle_enterer))
1125      _policy->funcs.idle_enterer();
1126
1127    return ECORE_CALLBACK_RENEW;
1128 }
1129
1130 static void
1131 _e_mod_policy_cb_hook_rotation_list_add(void *data __UNUSED__, void *data2)
1132 {
1133    E_Border *bd;
1134
1135    if (!(bd = data2)) return;
1136    if ((_policy) && (_policy->funcs.rotation_list_add))
1137      _policy->funcs.rotation_list_add(bd);
1138 }