98bf297eba641fdb5a9f497e7bb6decd466894cd
[platform/core/uifw/e-mod-tizen-wm-policy.git] / src / splitscreen / e_mod_split_screen_manager.c
1 #include "e.h"
2 #include "e_mod_split_screen_manager_log.h"
3 #include "e_mod_split_screen_manager.h"
4 #include "e_mod_split_screen_region.h"
5 #include "e_mod_appinfo_ext.h"
6
7 typedef Eina_Bool (*E_Mod_Split_Screen_Manager_Hint_Func)(E_Client *ec, const char *name, const char *value);
8 struct _E_Mod_Split_Screen_Manager_Hint_Handler
9 {
10    int type;
11    const char *name;
12    E_Mod_Split_Screen_Manager_Hint_Func func;
13 };
14
15 typedef struct _E_Mod_Split_Screen_Manager_Hint_Handler E_Mod_Split_Screen_Manager_Hint_Handler;
16
17 enum _E_Mod_Split_Screen_Manager_Hint_Type
18 {
19    E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION = 0,
20    E_MOD_SPLIT_SCREEN_MANAGER_HINT_LAUNCHER_ROLE_SET,
21    E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION_SUB1,
22    E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION_SUB2,
23    E_MOD_SPLIT_SCREEN_MANAGER_HINT_ACTIVATE,
24    E_MOD_SPLIT_SCREEN_MANAGER_HINT_DEACTIVATE,
25    E_MOD_SPLIT_SCREEN_MANAGER_HINT_MAX,
26 };
27
28 static Eina_List *_e_mod_split_screen_manager_ec_hook_handlers = NULL;
29 static Eina_List *_e_mod_split_screen_manager_ec_event_handlers = NULL;
30 static Eina_List *_e_mod_split_screen_manager_desk_area_hook_handlers = NULL;
31 static Eina_List *_e_mod_split_screen_manager_zone_hook_handlers = NULL;
32
33 static Eina_List *_e_mod_split_screen_region_list = NULL;
34 static E_Client *_e_mod_split_screen_launcher_ec = NULL;
35
36 /* e_client hooks */
37 static void _e_mod_split_screen_manager_cb_hook_aux_hint_change(void *data, E_Client *ec);
38
39 /* e_client events */
40 static Eina_Bool _e_mod_split_screen_manager_cb_ec_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
41 static Eina_Bool _e_mod_split_screen_manager_cb_ec_remove(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
42
43 /* Aux hint handlers */
44 static Eina_Bool     _e_mod_split_screen_manager_hint_launcher_role_set(E_Client *ec, const char *name, const char *value);
45 static Eina_Bool     _e_mod_split_screen_manager_hint_assign_region(E_Client *ec, const char *name, const char *value);
46 static Eina_Bool     _e_mod_split_screen_manager_hint_assign_region_sub1(E_Client *ec, const char *name, const char *value);
47 static Eina_Bool     _e_mod_split_screen_manager_hint_assign_region_sub2(E_Client *ec, const char *name, const char *value);
48 static Eina_Bool     _e_mod_split_screen_manager_hint_activate(E_Client *ec, const char *name, const char *value);
49 static Eina_Bool     _e_mod_split_screen_manager_hint_deactivate(E_Client *ec, const char *name, const char *value);
50
51 /* e_mod_split_screen_manager internal functions */
52 static void          _e_mod_split_screen_manager_client_manager_role_set(E_Client *ec, Eina_Bool set);
53 static Eina_Bool     _e_mod_split_screen_activate(E_Zone *zone);
54 static Eina_Bool     _e_mod_split_screen_deactivate(E_Zone *zone);
55 static void          _e_mod_split_screen_launcher_ec_set(E_Client *ec);
56 static E_Client *    _e_mod_split_screen_launcher_ec_get(void);
57 static E_Mod_Split_Screen_Region *_e_mod_split_screen_manager_find_region_by_name(const char *name);
58 static E_Mod_Split_Screen_Region *_e_mod_split_screen_manager_find_region_by_desk_area(E_Desk_Area *eda);
59 static void          _e_mod_split_screen_manager_appid_assign(E_Mod_Split_Screen_Region *emssr, const char *appid);
60 static Eina_Bool     _e_mod_split_screen_manager_ec_assign_to_region_name(E_Client *ec, const char *region_name);
61 static Eina_Bool     _e_mod_split_screen_manager_ec_relocate(E_Client *ec);
62 static Eina_Bool     _e_mod_split_screen_manager_ec_relocate_to_region(E_Client *ec, E_Mod_Split_Screen_Region *emssr);
63
64 /* initializer */
65 static Eina_Bool _e_mod_split_screen_manager_handler_init(void);
66 static Eina_Bool _e_mod_split_screen_manager_aux_hint_handler_init(void);
67 static void      _e_mod_split_screen_manager_handler_shutdown(void);
68 static void      _e_mod_split_screen_manager_aux_hint_handler_shutdown(void);
69 static Eina_Bool _e_mod_split_screen_manager_region_init(void);
70 static void      _e_mod_split_screen_manager_region_shutdown(void);
71
72 static const E_Mod_Split_Screen_Manager_Hint_Handler _e_mod_split_screen_manager_hint_handler[] =
73 {
74      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION, "wm.splitscreen.win.assign_region", _e_mod_split_screen_manager_hint_assign_region},
75      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_LAUNCHER_ROLE_SET, "wm.splitscreen.win.launcher.role_set", _e_mod_split_screen_manager_hint_launcher_role_set},
76      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION_SUB1, "wm.splitscreen.win.split_screen_manager.assign_region.sub1", _e_mod_split_screen_manager_hint_assign_region_sub1},
77      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_ASSIGN_REGION_SUB2, "wm.splitscreen.win.split_screen_manager.assign_region.sub2", _e_mod_split_screen_manager_hint_assign_region_sub2},
78      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_ACTIVATE, "wm.splitscreen.win.split_screen_manager.activate", _e_mod_split_screen_manager_hint_activate},
79      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_DEACTIVATE, "wm.splitscreen.win.split_screen_manager.deactivate", _e_mod_split_screen_manager_hint_deactivate},
80      {E_MOD_SPLIT_SCREEN_MANAGER_HINT_MAX, NULL, NULL},
81 };
82
83 /* Hook handlers */
84 static void
85 _e_mod_split_screen_manager_cb_hook_aux_hint_change(void *data, E_Client *ec)
86 {
87    const char *hint, *val;
88
89    if (!ec)
90      {
91         SSMINF("ec is NULL", NULL);
92         return;
93      }
94
95    for (int i=0 ; i<E_MOD_SPLIT_SCREEN_MANAGER_HINT_MAX ; i++)
96      {
97         hint = _e_mod_split_screen_manager_hint_handler[i].name;
98         val = e_hints_aux_hint_value_get(ec, hint);
99         if (!val) continue;
100
101         _e_mod_split_screen_manager_hint_handler[i].func(ec, hint, val);
102      }
103
104    return;
105 }
106
107 static void
108 _e_mod_split_screen_manager_cb_hook_eval_fetch(void *data, E_Client *ec)
109 {
110    if (!ec)
111      {
112         SSMINF("ec is NULL", NULL);
113         return;
114      }
115    // TODO: FIX blinking issue while launching child window
116    _e_mod_split_screen_manager_ec_relocate(ec);
117
118    return;
119 }
120
121 static void
122 _e_mod_split_screen_manager_cb_hook_assign_appid(void *data EINA_UNUSED, E_Desk_Area *eda, void *appid_ptr)
123 {
124    E_Mod_Split_Screen_Region *emssr;
125    Eina_Stringshare *appid;
126
127    EINA_SAFETY_ON_NULL_RETURN(eda);
128    EINA_SAFETY_ON_NULL_RETURN(appid_ptr);
129
130    appid = eina_stringshare_add(appid_ptr);
131    emssr = _e_mod_split_screen_manager_find_region_by_desk_area(eda);
132    if (!emssr)
133      {
134         SSMERR("Failed to find region for desk area %p", NULL, eda);
135         return;
136      }
137
138    _e_mod_split_screen_manager_appid_assign(emssr, appid);
139
140    return;
141 }
142
143 static void
144 _e_mod_split_screen_manager_cb_hook_activate(void *data, E_Zone *zone)
145 {
146    if (!zone) return;
147    _e_mod_split_screen_activate(zone);
148 }
149
150 static void
151 _e_mod_split_screen_manager_cb_hook_deactivate(void *data, E_Zone *zone)
152 {
153    if (!zone) return;
154    _e_mod_split_screen_deactivate(zone);
155 }
156
157
158 /* e_client events */
159 static Eina_Bool
160 _e_mod_split_screen_manager_cb_ec_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
161 {
162    E_Event_Client *ev;
163
164    ev = event;
165    if (!ev) return ECORE_CALLBACK_PASS_ON;
166
167    _e_mod_split_screen_manager_ec_relocate(ev->ec);
168
169    return ECORE_CALLBACK_PASS_ON;
170 }
171
172 static Eina_Bool
173 _e_mod_split_screen_manager_cb_ec_remove(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
174 {
175    E_Event_Client *ev;
176
177    ev = event;
178    if (!ev) return ECORE_CALLBACK_PASS_ON;
179
180    e_mod_split_screen_region_ec_dismiss(ev->ec);
181
182    return ECORE_CALLBACK_PASS_ON;
183 }
184
185 /* Aux hint handlers */
186 static Eina_Bool
187 _e_mod_split_screen_manager_hint_launcher_role_set(E_Client *ec, const char *name, const char *value)
188 {
189    if (!strncmp(value, "1", 1))
190      {
191         _e_mod_split_screen_manager_client_manager_role_set(ec, EINA_TRUE);
192      }
193    else
194      {
195         _e_mod_split_screen_manager_client_manager_role_set(ec, EINA_FALSE);
196      }
197
198    return EINA_TRUE;
199 }
200
201 static Eina_Bool
202 _e_mod_split_screen_manager_hint_assign_region(E_Client *ec, const char *name, const char *value)
203 {
204    E_Mod_Split_Screen_Region *emssr;
205    Eina_Stringshare *appid;
206
207    char _region_name[10] = {0,};
208    char _appid[255] = {0,};
209
210    EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
211
212    // hint value format: region_name/appid
213    sscanf(value, "%[^/]/%s", _region_name, _appid);
214    SSMINF("client appid(%s) -> assign to region:%s", ec, _appid, _region_name);
215
216    if ((strlen(_region_name) <= 0) || strlen(_region_name) > 10)
217      {
218         SSMERR("invalid region name:%s", ec, _region_name);
219         return EINA_FALSE;
220      }
221
222    if ((strlen(_appid) <= 0) || (strlen(_appid) > 255))
223      {
224         SSMERR("invalid app id:%s", ec, _appid);
225         return EINA_FALSE;
226      }
227
228    emssr = _e_mod_split_screen_manager_find_region_by_name(_region_name);
229    if (!emssr)
230      {
231         SSMERR("invalid region name:%s", ec, _region_name);
232         return EINA_FALSE;
233      }
234
235    appid = eina_stringshare_add(_appid);
236
237    _e_mod_split_screen_manager_appid_assign(emssr, appid);
238
239    return EINA_TRUE;
240 }
241
242 static Eina_Bool
243 _e_mod_split_screen_manager_hint_assign_region_sub1(E_Client *ec, const char *name, const char *value)
244 {
245    E_Mod_Split_Screen_Region *emssr;
246    Eina_Stringshare *appid;
247
248    EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
249
250    if ((strlen(value) <= 0) || strlen(value) > 255)
251      {
252         SSMERR("invalid app id:%s", ec, value);
253         return EINA_FALSE;
254      }
255
256    appid = eina_stringshare_add(value);
257
258    emssr = _e_mod_split_screen_manager_find_region_by_name("sub1");
259    if (!emssr)
260      {
261         SSMERR("invalid region name:%s", ec, "sub1");
262         return EINA_FALSE;
263      }
264
265    _e_mod_split_screen_manager_appid_assign(emssr, appid);
266
267    return EINA_TRUE;
268 }
269
270 static Eina_Bool
271 _e_mod_split_screen_manager_hint_assign_region_sub2(E_Client *ec, const char *name, const char *value)
272 {
273    E_Mod_Split_Screen_Region *emssr;
274    Eina_Stringshare *appid;
275
276    EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
277
278    if ((strlen(value) <= 0) || strlen(value) > 255)
279      {
280         SSMERR("invalid app id:%s", ec, value);
281         return EINA_FALSE;
282      }
283
284    appid = eina_stringshare_add(value);
285
286    emssr = _e_mod_split_screen_manager_find_region_by_name("sub2");
287    if (!emssr)
288      {
289         SSMERR("invalid region name:%s", ec, "sub2");
290         return EINA_FALSE;
291      }
292
293    _e_mod_split_screen_manager_appid_assign(emssr, appid);
294
295    return EINA_TRUE;
296 }
297
298 static Eina_Bool
299 _e_mod_split_screen_manager_hint_activate(E_Client *ec, const char *name, const char *value)
300 {
301    return _e_mod_split_screen_activate(e_zone_current_get());
302 }
303
304 static Eina_Bool
305 _e_mod_split_screen_manager_hint_deactivate(E_Client *ec, const char *name, const char *value)
306 {
307    return _e_mod_split_screen_deactivate(e_zone_current_get());
308 }
309
310 /* internal functions */
311
312 static void
313 _e_mod_split_screen_manager_client_manager_role_set(E_Client *ec, Eina_Bool set)
314 {
315    if (!ec) return;
316    if (ec->floating == set) return;
317
318    ec->floating = set;
319
320    if (ec->frame)
321      {
322         if (set)
323           {
324              _e_mod_split_screen_launcher_ec_set(ec);
325              ec->floating_saved_layer = ec->layer;
326              e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
327              ec->netwm.type = E_WINDOW_TYPE_UTILITY;
328              _e_mod_split_screen_manager_ec_assign_to_region_name(ec, "above");
329           }
330         else
331           {
332              e_client_layer_set(ec, ec->floating_saved_layer);
333              ec->netwm.type = E_WINDOW_TYPE_NORMAL;
334              e_mod_split_screen_region_ec_dismiss(ec);
335           }
336      }
337
338    e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
339    e_comp_object_dirty(ec->frame);
340    e_comp_object_render(ec->frame);
341
342    EC_CHANGED(ec);
343 }
344
345 static Eina_Bool
346 _e_mod_split_screen_activate(E_Zone *zone)
347 {
348    E_Desk *desk;
349    E_Client *ec, *launcher;
350    Eina_Bool ret = EINA_FALSE;
351
352    SSMINF("ACTIVATE split screen", NULL);
353
354    desk = e_desk_current_get(zone);
355    ret = e_desk_desk_area_enable(desk);
356
357    // relocate all e clients
358    E_CLIENT_FOREACH(ec)
359      {
360         _e_mod_split_screen_manager_ec_relocate(ec);
361      }
362
363    // launcher window must be above desk group to unobscured by other windows
364    launcher = _e_mod_split_screen_launcher_ec_get();
365    if (launcher)
366      _e_mod_split_screen_manager_ec_assign_to_region_name(launcher, "above");
367
368    return ret;
369 }
370
371 static Eina_Bool
372 _e_mod_split_screen_deactivate(E_Zone *zone)
373 {
374    E_Desk *desk;
375    Eina_Bool ret = EINA_FALSE;
376
377    SSMINF("DEACTIVATE split screen", NULL);
378
379    desk = e_desk_current_get(zone);
380    ret = e_desk_desk_area_disable(desk);
381
382    return ret;
383 }
384
385 static void
386 _e_mod_split_screen_launcher_ec_set(E_Client *ec)
387 {
388    _e_mod_split_screen_launcher_ec = ec;
389 }
390
391 static E_Client *
392 _e_mod_split_screen_launcher_ec_get(void)
393 {
394    return _e_mod_split_screen_launcher_ec;
395 }
396
397 static E_Mod_Split_Screen_Region *
398 _e_mod_split_screen_manager_find_region_by_name(const char *name)
399 {
400    E_Mod_Split_Screen_Region *emssr = NULL;
401    Eina_List *l;
402    const char *region_name;
403
404    EINA_LIST_FOREACH(_e_mod_split_screen_region_list, l, emssr)
405      {
406         region_name = e_mod_split_screen_region_name_get(emssr);
407         if (region_name && !strncmp(region_name, name, strlen(region_name))) break;
408      }
409
410    return emssr;
411 }
412
413 static E_Mod_Split_Screen_Region *
414 _e_mod_split_screen_manager_find_region_by_desk_area(E_Desk_Area *eda)
415 {
416    E_Mod_Split_Screen_Region *emssr = NULL;
417    Eina_List *l;
418
419    EINA_LIST_FOREACH(_e_mod_split_screen_region_list, l, emssr)
420      {
421         if (e_mod_split_screen_region_desk_area_get(emssr) == eda) break;
422      }
423
424    return emssr;
425 }
426
427 static void
428 _e_mod_split_screen_manager_appid_assign(E_Mod_Split_Screen_Region *emssr, const char *appid)
429 {
430    E_Mod_Split_Screen_Region *emssr_iter;
431    E_Client *ec;
432    Eina_Stringshare *region_name;
433    Eina_List *l;
434
435    // reassign AppID to Split screen region
436    EINA_LIST_FOREACH(_e_mod_split_screen_region_list, l, emssr_iter)
437      {
438         e_mod_split_screen_region_appid_dismiss(emssr_iter, appid);
439      }
440    e_mod_split_screen_region_appid_assign(emssr, appid);
441
442    // assign clients of appID to Split screen region
443    l = e_mod_appinfo_ext_find_clients_by_appid(appid);
444    EINA_LIST_FREE(l, ec)
445      {
446         e_mod_split_screen_region_ec_assign(emssr, ec);
447      }
448
449    region_name = e_mod_split_screen_region_name_get(emssr);
450    SSMINF("from now on, appid %s will be assign to region:%s", NULL, appid, region_name);
451 }
452
453 static Eina_Bool
454 _e_mod_split_screen_manager_util_client_special_check(E_Client *ec)
455 {
456    if (!ec) return EINA_FALSE;
457
458    if (_e_mod_split_screen_launcher_ec_get() == ec) return EINA_TRUE;
459
460    if ((e_policy_client_is_lockscreen(ec)) ||
461        (e_policy_client_is_keyboard(ec)) ||
462        (e_policy_client_is_keyboard_sub(ec)) ||
463        (e_policy_client_is_noti(ec)) ||
464        (e_policy_client_is_quickpanel(ec)) ||
465        (e_policy_client_is_volume(ec)) ||
466        (e_policy_client_is_cursor(ec)) ||
467        (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role)))
468      return EINA_TRUE;
469
470    return EINA_FALSE;
471 }
472
473 static Eina_Bool
474 _e_mod_split_screen_manager_ec_assign_to_region_name(E_Client *ec, const char *region_name)
475 {
476    E_Mod_Split_Screen_Region *emssr = NULL;
477
478    if (!ec) return ECORE_CALLBACK_PASS_ON;
479    if (!region_name) return ECORE_CALLBACK_PASS_ON;
480
481    emssr = _e_mod_split_screen_manager_find_region_by_name(region_name);
482    if (!emssr)
483      {
484         SSMERR("invalid region name:%s", ec, region_name);
485         return EINA_FALSE;
486      }
487    return e_mod_split_screen_region_ec_assign(emssr, ec);
488 }
489
490 static Eina_Bool
491 _e_mod_split_screen_manager_ec_relocate(E_Client *ec)
492 {
493    E_Mod_Split_Screen_Region *emssr = NULL;
494    E_Client *parent_ec = NULL;
495    Eina_Bool res = EINA_FALSE;
496    Eina_List *l;
497
498    if (!ec) return ECORE_CALLBACK_PASS_ON;
499
500    if (_e_mod_split_screen_manager_util_client_special_check(ec))
501      {
502         // special prupose windows.
503         _e_mod_split_screen_manager_ec_assign_to_region_name(ec, "above");
504         return EINA_TRUE;
505      }
506
507    EINA_LIST_FOREACH(_e_mod_split_screen_region_list, l, emssr)
508      {
509         res |= _e_mod_split_screen_manager_ec_relocate_to_region(ec, emssr);
510      }
511
512    if (!res)
513      {
514         // find the parent ec that is in the region
515         for (parent_ec = ec->parent;
516              parent_ec != NULL;
517              parent_ec = parent_ec->parent)
518           {
519              EINA_LIST_FOREACH(_e_mod_split_screen_region_list, l, emssr)
520                {
521                   res |= _e_mod_split_screen_manager_ec_relocate_to_region(parent_ec, emssr);
522                }
523           }
524      }
525
526    return res;
527 }
528
529 static Eina_Bool
530 _e_mod_split_screen_manager_ec_relocate_to_region(E_Client *ec, E_Mod_Split_Screen_Region *emssr)
531 {
532    Eina_Stringshare *appid;
533    Eina_List *appid_list, *l;
534    Eina_Bool res = EINA_FALSE;
535
536    if (!ec || !emssr) return EINA_FALSE;
537
538    appid_list = e_mod_split_screen_region_appid_list_get(emssr);
539
540    EINA_LIST_FOREACH(appid_list, l, appid)
541        if (ec->netwm.pid == e_mod_appinfo_ext_find_pid_by_appid(appid))
542          {
543             Eina_Stringshare *region_name = e_mod_split_screen_region_name_get(emssr);
544             SSMINF("client(%p):%s rearrange to region:%s",
545                    ec, ec, ec ? ec->icccm.name : "NULL", region_name);
546             res |= e_mod_split_screen_region_ec_assign(emssr, ec);
547          }
548
549    return res;
550 }
551
552 /* split screen initializer */
553
554 static Eina_Bool
555 _e_mod_split_screen_manager_handler_init(void)
556 {
557    E_Desk_Area_Hook *eda_hook;
558    E_Zone_Hook *ez_hook;
559
560    E_LIST_HANDLER_APPEND(_e_mod_split_screen_manager_ec_event_handlers, E_EVENT_CLIENT_ADD, _e_mod_split_screen_manager_cb_ec_add, NULL);
561    E_LIST_HANDLER_APPEND(_e_mod_split_screen_manager_ec_event_handlers, E_EVENT_CLIENT_REMOVE, _e_mod_split_screen_manager_cb_ec_remove, NULL);
562
563    E_LIST_HOOK_APPEND(_e_mod_split_screen_manager_ec_hook_handlers, E_CLIENT_HOOK_EVAL_FETCH, _e_mod_split_screen_manager_cb_hook_eval_fetch, NULL);
564
565    eda_hook = e_desk_area_hook_add(E_DESK_AREA_HOOK_SET_APPID, _e_mod_split_screen_manager_cb_hook_assign_appid, NULL);
566    if (eda_hook) _e_mod_split_screen_manager_desk_area_hook_handlers = eina_list_append(_e_mod_split_screen_manager_desk_area_hook_handlers, eda_hook);
567
568    ez_hook = e_zone_hook_add(E_ZONE_HOOK_SPLISCREEN_ACTIVATE, _e_mod_split_screen_manager_cb_hook_activate, NULL);
569    if (ez_hook) _e_mod_split_screen_manager_zone_hook_handlers = eina_list_append(_e_mod_split_screen_manager_zone_hook_handlers, ez_hook);
570
571    ez_hook = e_zone_hook_add(E_ZONE_HOOK_SPLISCREEN_DEACTIVATE, _e_mod_split_screen_manager_cb_hook_deactivate, NULL);
572    if (ez_hook) _e_mod_split_screen_manager_zone_hook_handlers = eina_list_append(_e_mod_split_screen_manager_zone_hook_handlers, ez_hook);
573
574    if (!_e_mod_split_screen_manager_ec_event_handlers ||
575        !_e_mod_split_screen_manager_ec_hook_handlers ||
576        !_e_mod_split_screen_manager_desk_area_hook_handlers)
577      return EINA_FALSE;
578
579    return EINA_TRUE;
580 }
581
582 static Eina_Bool
583 _e_mod_split_screen_manager_aux_hint_handler_init(void)
584 {
585    E_LIST_HOOK_APPEND(_e_mod_split_screen_manager_ec_hook_handlers, E_CLIENT_HOOK_AUX_HINT_CHANGE, _e_mod_split_screen_manager_cb_hook_aux_hint_change, NULL);
586
587    if (!_e_mod_split_screen_manager_ec_hook_handlers)
588      return EINA_FALSE;
589
590    for (int i=0 ; i<E_MOD_SPLIT_SCREEN_MANAGER_HINT_MAX ; i++)
591      {
592         e_hints_aux_hint_supported_add(_e_mod_split_screen_manager_hint_handler[i].name);
593      }
594
595    return EINA_TRUE;
596 }
597
598 static void
599 _e_mod_split_screen_manager_handler_shutdown(void)
600 {
601    E_FREE_LIST(_e_mod_split_screen_manager_ec_event_handlers, ecore_event_handler_del);
602    E_FREE_LIST(_e_mod_split_screen_manager_desk_area_hook_handlers, e_desk_area_hook_del);
603 }
604
605 static void
606 _e_mod_split_screen_manager_aux_hint_handler_shutdown(void)
607 {
608    E_FREE_LIST(_e_mod_split_screen_manager_ec_hook_handlers, e_client_hook_del);
609
610    for (int i=0 ; i<E_MOD_SPLIT_SCREEN_MANAGER_HINT_MAX ; i++)
611      {
612         e_hints_aux_hint_supported_del(_e_mod_split_screen_manager_hint_handler[i].name);
613      }
614 }
615
616 static Eina_Bool
617 _e_mod_split_screen_manager_region_init(void)
618 {
619    E_Desk *desk;
620    E_Mod_Split_Screen_Region *emssr_sub1, *emssr_sub2, *emssr_above;
621    int desk_x, desk_y, desk_w, desk_h;
622
623    desk = e_desk_current_get(e_zone_current_get());
624    EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
625
626    desk_x = desk->geom.x;
627    desk_y = desk->geom.y;
628    desk_w = desk->geom.w;
629    desk_h = desk->geom.h;
630
631    emssr_sub1 = e_mod_split_screen_region_new("sub1", desk_x, desk_y, desk_w, desk_h / 2);
632    if (!emssr_sub1) return EINA_FALSE;
633
634    _e_mod_split_screen_region_list = eina_list_append(_e_mod_split_screen_region_list, emssr_sub1);
635
636    emssr_sub2 = e_mod_split_screen_region_new("sub2", desk_x, desk_y + desk_h / 2, desk_w, desk_h / 2);
637    if (!emssr_sub2) return EINA_FALSE;
638
639    _e_mod_split_screen_region_list = eina_list_append(_e_mod_split_screen_region_list, emssr_sub2);
640
641    emssr_above = e_mod_split_screen_region_new("above", desk_x, desk_y, desk_w, desk_h);
642    if (!emssr_above) return EINA_FALSE;
643
644    _e_mod_split_screen_region_list = eina_list_append(_e_mod_split_screen_region_list, emssr_above);
645
646    return EINA_TRUE;
647 }
648
649 static void
650 _e_mod_split_screen_manager_region_shutdown(void)
651 {
652    E_Mod_Split_Screen_Region *emssr;
653
654    if (!_e_mod_split_screen_region_list) return;
655
656    EINA_LIST_FREE(_e_mod_split_screen_region_list, emssr)
657      {
658         e_mod_split_screen_region_del(emssr);
659      }
660 }
661
662 EINTERN Eina_Bool
663 e_mod_split_screen_manager_init(void)
664 {
665    Eina_Bool res;
666
667    SSMDBG("SPLIT_SCREEN_MANAGER module init", NULL);
668
669    e_zone_screen_splitscreen_enable(e_zone_current_get());
670
671    res = _e_mod_split_screen_manager_region_init();
672    EINA_SAFETY_ON_FALSE_GOTO(res, err);
673
674    res = _e_mod_split_screen_manager_handler_init();
675    EINA_SAFETY_ON_FALSE_GOTO(res, err);
676
677    res = _e_mod_split_screen_manager_aux_hint_handler_init();
678    EINA_SAFETY_ON_FALSE_GOTO(res, err);
679
680    return EINA_TRUE;
681
682 err:
683    SSMINF("FAILED TO module init!!!", NULL);
684    e_mod_split_screen_manager_shutdown();
685
686    return EINA_FALSE;
687 }
688
689 EINTERN void
690 e_mod_split_screen_manager_shutdown(void)
691 {
692    SSMDBG("SPLIT_SCREEN_MANAGER module shutdown", NULL);
693    _e_mod_split_screen_manager_aux_hint_handler_shutdown();
694    _e_mod_split_screen_manager_handler_shutdown();
695    _e_mod_split_screen_manager_region_shutdown();
696 }