0520202452c38c4943869a57c5db21d05a6c1c34
[platform/upstream/enlightenment.git] / src / bin / e_desk_area.c
1 #include "e.h"
2 #include "e_client_intern.h"
3 #include "e_comp_object_intern.h"
4
5 #include <libds-tizen/screen.h>
6
7 typedef struct _E_Desk_Area_Private         E_Desk_Area_Private;
8 typedef struct _E_Desk_Area_Private_Client  E_Desk_Area_Private_Client;
9
10 #define PRI(eda) ((E_Desk_Area_Private *)e_object_data_get(E_OBJECT(eda)))
11
12 #define API_ENTRY \
13    EINA_SAFETY_ON_NULL_RETURN(eda); \
14    E_Desk_Area_Private *priv = PRI(eda)
15
16 #define API_ENTRY_VAL(ret) \
17    EINA_SAFETY_ON_NULL_RETURN_VAL(eda, ret); \
18    E_Desk_Area_Private *priv = PRI(eda)
19
20 #ifdef REFACTOR_DESK_AREA
21 typedef struct _E_Desk_Area_Smart_Data E_Desk_Area_Smart_Data;
22 typedef void (*E_Desk_Area_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
23
24 #define E_DESK_AREA_SMART_DATA_GET(obj, ptr)                        \
25    E_Desk_Area_Smart_Data *ptr = evas_object_smart_data_get(obj);
26
27 #define E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, ptr)              \
28    E_DESK_AREA_SMART_DATA_GET(obj, ptr);                            \
29    if (!ptr) return
30 #endif
31
32 static int _e_desk_area_hooks_delete = 0;
33 static int _e_desk_area_hooks_walking = 0;
34
35 static Eina_Inlist *_e_desk_area_hooks[] =
36 {
37    [E_DESK_AREA_HOOK_SET_APPID] = NULL,
38 };
39
40 struct _E_Desk_Area_Private
41 {
42    E_Desk_Area *eda;
43
44    struct ds_tizen_splitscreen_region *splitscreen_region;
45    struct wl_listener splitscreen_region_destroy;
46    struct wl_listener splitscreen_region_assign_appid;
47 };
48
49 struct _E_Desk_Area_Private_Client
50 {
51    E_Desk_Area *eda;
52    E_Client *ec;
53
54    // client listeners
55    struct wl_listener client_get_above;
56    struct wl_listener client_get_below;
57    struct wl_listener client_subsurface_stack_update;
58
59    // comp_object listeners
60    struct wl_listener comp_object_raise;
61    struct wl_listener comp_object_lower;
62    struct wl_listener comp_object_set_layer;
63    struct wl_listener comp_object_stack_above;
64    struct wl_listener comp_object_stack_below;
65 };
66
67 #ifdef REFACTOR_DESK_AREA
68 struct _E_Desk_Area_Smart_Data
69 {
70    Evas_Object_Smart_Clipped_Data base;
71
72    E_Desk_Area *eda;
73
74    Eina_List      *clients;
75    Eina_List      *handlers;
76 };
77 #endif
78
79 struct _E_Desk_Area_Hook
80 {
81    EINA_INLIST;
82    E_Desk_Area_Hook_Point hookpoint;
83    E_Desk_Area_Hook_Cb    func;
84    void                   *data;
85    unsigned char           delete_me : 1;
86 };
87
88 static void        _e_desk_area_hooks_clean(void);
89 static Eina_Bool   _e_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *appid);
90
91 #ifdef REFACTOR_DESK_AREA
92 EVAS_SMART_SUBCLASS_NEW(E_DESK_AREA_SMART_OBJ_TYPE, _e_desk_area,
93                         Evas_Smart_Class, Evas_Smart_Class,
94                         evas_object_smart_clipped_class_get, NULL)
95 #endif
96
97 #ifdef REFACTOR_DESK_AREA
98 #else
99 static Eina_Bool
100 _check_desk_area_client_layer_validation(E_Desk_Area_Client_Layer edgc_layer)
101 {
102    if ((edgc_layer >= E_DESK_AREA_CLIENT_LAYER_DESKTOP) &&
103        (edgc_layer < E_DESK_AREA_CLIENT_LAYER_MAX))
104      return EINA_TRUE;
105    else
106      return EINA_FALSE;
107 }
108
109 static void
110 _e_desk_area_ec_prepend(E_Desk_Area *eda, E_Client *ec)
111 {
112    E_Desk_Area_Client_Layer edgc_layer;
113
114    edgc_layer = e_client_desk_area_client_layer_get(ec);
115    if (!_check_desk_area_client_layer_validation(edgc_layer)) return;
116
117    eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
118    eda->ec_lists[edgc_layer] = eina_list_prepend(eda->ec_lists[edgc_layer], ec);
119
120    e_client_desk_area_client_layer_set(ec, edgc_layer);
121 }
122
123 static void
124 _e_desk_area_ec_append(E_Desk_Area *eda, E_Client *ec)
125 {
126    E_Desk_Area_Client_Layer edgc_layer;
127
128    edgc_layer = e_client_desk_area_client_layer_get(ec);
129    if (!_check_desk_area_client_layer_validation(edgc_layer)) return;
130
131    eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
132    eda->ec_lists[edgc_layer] = eina_list_append(eda->ec_lists[edgc_layer], ec);
133
134    e_client_desk_area_client_layer_set(ec, edgc_layer);
135 }
136
137 static void
138 _e_desk_area_ec_prepend_relative(E_Desk_Area *eda, E_Client *ec, E_Client *above)
139 {
140    E_Desk_Area_Client_Layer edgc_layer;
141    E_Desk_Area_Client_Layer above_edgc_layer;
142
143    // update eda's ec_list order
144    edgc_layer = e_client_desk_area_client_layer_get(ec);
145    if (!_check_desk_area_client_layer_validation(edgc_layer)) return;
146    above_edgc_layer = e_client_desk_area_client_layer_get(above);
147    if (!_check_desk_area_client_layer_validation(above_edgc_layer)) return;
148
149    ELOGF("EDG", "STACK_ABOVE... eda:%p. layer:%d, above(win:%zx, ec:%p, layer:%d)", ec, eda, edgc_layer, e_client_util_win_get(above), above, above_edgc_layer);
150
151    if (edgc_layer == above_edgc_layer)
152      {
153         eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
154         eda->ec_lists[edgc_layer] = eina_list_prepend_relative(eda->ec_lists[edgc_layer], ec, above);
155      }
156    else
157      {
158         eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
159         eda->ec_lists[above_edgc_layer] = eina_list_prepend_relative(eda->ec_lists[above_edgc_layer], ec, above);
160      }
161
162    e_client_desk_area_client_layer_set(ec, above_edgc_layer);
163 }
164
165 static void
166 _e_desk_area_ec_append_relative(E_Desk_Area *eda, E_Client *ec, E_Client *below)
167 {
168    E_Desk_Area_Client_Layer edgc_layer;
169    E_Desk_Area_Client_Layer below_edgc_layer;
170
171    // update eda's ec_list order
172    edgc_layer = e_client_desk_area_client_layer_get(ec);
173    if (!_check_desk_area_client_layer_validation(edgc_layer)) return;
174    below_edgc_layer = e_client_desk_area_client_layer_get(below);
175    if (!_check_desk_area_client_layer_validation(below_edgc_layer)) return;
176
177    ELOGF("EDG", "STACK_BELOW... eda:%p. layer:%d, below(win:%zx, ec:%p, layer:%d)", ec, eda, edgc_layer, e_client_util_win_get(below), below, below_edgc_layer);
178
179    if (edgc_layer == below_edgc_layer)
180      {
181         eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
182         eda->ec_lists[edgc_layer] = eina_list_append_relative(eda->ec_lists[edgc_layer], ec, below);
183      }
184    else
185      {
186         eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
187         eda->ec_lists[below_edgc_layer] = eina_list_append_relative(eda->ec_lists[below_edgc_layer], ec, below);
188      }
189
190    e_client_desk_area_client_layer_set(ec, below_edgc_layer);
191 }
192 #endif
193
194 static void
195 _e_desk_geometry_info_set(E_Desk_Area *eda, int x, int y, int w, int h)
196 {
197    E_Desk *desk;
198
199    if (!eda) return;
200    if (!eda->desk) return;
201
202    desk = eda->desk;
203
204    eda->x = x;
205    eda->y = y;
206    eda->w = w;
207    eda->h = h;
208
209    eda->scale_w = (double)w / (double)desk->geom.w;
210    eda->scale_h = (double)h / (double)desk->geom.h;
211 }
212
213 static void
214 _e_desk_area_active_change(E_Desk_Area *eda, E_Desk *desk)
215 {
216    E_Desk_Area *prev_active_edg;
217
218    if (!desk) return;
219
220    prev_active_edg = e_desk_desk_area_active_get(desk);
221    if (prev_active_edg == eda) return;
222
223    // 1. reset current active eda info
224    if (prev_active_edg)
225      prev_active_edg->active = EINA_FALSE;
226
227    // 2. set new active eda info
228    if (eda)
229      {
230         eda->active = EINA_TRUE;
231         e_desk_desk_area_active_set(desk, eda);
232      }
233    else
234      {
235         e_desk_desk_area_active_set(desk, NULL);
236      }
237 }
238
239 static void
240 _e_desk_area_cb_hook_subsurface_create(void *data, E_Client *ec)
241 {
242    EINA_SAFETY_ON_NULL_RETURN(ec);
243
244    if (ec->desk_area.transform)
245      {
246         e_client_transform_core_remove(ec, ec->desk_area.transform);
247      }
248 }
249
250 EINTERN int
251 e_desk_area_init(void)
252 {
253    return 1;
254 }
255
256 EINTERN int
257 e_desk_area_shutdown(void)
258 {
259    return 1;
260 }
261
262 static Eina_Bool
263 _e_desk_area_private_init(E_Desk_Area *eda)
264 {
265    E_Desk_Area_Private *priv;
266
267    priv = E_NEW(E_Desk_Area_Private, 1);
268    if (!priv)
269      return EINA_FALSE;
270
271    priv->eda = eda;
272
273    e_object_data_set(E_OBJECT(eda), priv);
274
275    return EINA_TRUE;
276 }
277
278 static void
279 _e_desk_area_private_finish(E_Desk_Area *eda)
280 {
281    E_Desk_Area_Private *priv;
282
283    priv = PRI(eda);
284
285    wl_list_remove(&priv->splitscreen_region_assign_appid.link);
286    wl_list_remove(&priv->splitscreen_region_destroy.link);
287
288    e_object_data_set(E_OBJECT(eda), NULL);
289
290    priv->eda = NULL;
291
292    free(priv);
293 }
294
295 static void
296 _e_desk_area_free(E_Desk_Area *eda)
297 {
298 #ifdef REFACTOR_DESK_AREA
299 #else
300    for (int i = 0; i < E_DESK_AREA_CLIENT_LAYER_MAX; i++)
301      {
302         eina_list_free(eda->ec_lists[i]);
303      }
304
305    if (eda->active)
306      _e_desk_area_active_change(NULL, eda->desk);
307 #endif
308
309    E_FREE_FUNC(eda->hook_subsurf_create, e_comp_wl_hook_del);
310
311    _e_desk_area_private_finish(eda);
312    free(eda);
313 }
314
315 #ifdef REFACTOR_DESK_AREA
316 static void
317 _e_desk_area_smart_add(Evas_Object *obj)
318 {
319    EVAS_SMART_DATA_ALLOC(obj, E_Desk_Area_Smart_Data);
320
321    _e_desk_area_parent_sc->add(obj);
322 }
323
324 static void
325 _e_desk_area_smart_del(Evas_Object *obj)
326 {
327    _e_desk_area_parent_sc->del(obj);
328
329    E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
330
331    E_FREE_LIST(sd->handlers, ecore_event_handler_del);
332    eina_list_free(sd->clients);
333    free(sd);
334
335    evas_object_smart_data_set(obj, NULL);
336 }
337
338 static void
339 _e_desk_area_smart_member_add(Evas_Object *obj, Evas_Object *child)
340 {
341    _e_desk_area_parent_sc->member_add(obj, child);
342 }
343
344 static void
345 _e_desk_area_smart_member_del(Evas_Object *obj, Evas_Object *child)
346 {
347    _e_desk_area_parent_sc->member_del(obj, child);
348 }
349
350 static void
351 _e_desk_area_smart_set_user(Evas_Smart_Class *sc)
352 {
353    sc->add = _e_desk_area_smart_add;
354    sc->del = _e_desk_area_smart_del;
355    sc->member_add = _e_desk_area_smart_member_add;
356    sc->member_del = _e_desk_area_smart_member_del;
357 }
358
359 static void
360 _desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
361 {
362    E_Desk_Area_Private_Client *eda_client;
363    E_Client_Data_Get_Above *get_above_data = data;
364    E_Desk_Area *eda;
365    E_Client *ec, *ec2;
366    unsigned int x;
367
368    eda_client = wl_container_of(listener, eda_client, client_get_above);
369    ec = eda_client->ec;
370    eda = eda_client->eda;
371
372    if (EINA_INLIST_GET(ec)->next) //check current layer
373      {
374         EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
375           {
376              if (ec == ec2)
377                {
378                   ELOGF("FATAL", "CHECK the ec inlist next", ec);
379                   continue;
380                }
381              if (!e_object_is_del(E_OBJECT(ec2)))
382                {
383                   get_above_data->above_ec = ec2;
384                   return;
385                }
386           }
387      }
388
389    if (ec->layer == E_LAYER_CLIENT_CURSOR) return;
390    if (e_comp_canvas_client_layer_map(ec->layer) == 9999) return;
391
392    g_rec_mutex_lock(&e_comp->ec_list_mutex);
393
394    /* go up the layers until we find one */
395    for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
396      {
397         if (!e_comp->layers[x].clients) continue;
398
399         EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
400           {
401              if (ec == ec2)
402                {
403                   ELOGF("FATAL", "[eda:%p] EC exist above layer. ec layer_map:%d, cur layer_map:%d",
404                         ec, eda, e_comp_canvas_layer_map(ec->layer), x);
405                   continue;
406                }
407              if (!e_object_is_del(E_OBJECT(ec2)))
408                {
409                   get_above_data->above_ec = ec2;
410                   g_rec_mutex_unlock(&e_comp->ec_list_mutex);
411                   return;
412                }
413           }
414      }
415
416    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
417 }
418
419 static void
420 _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
421 {
422    E_Desk_Area_Private_Client *eda_client;
423    E_Client_Data_Get_Below *get_below_data = data;
424    E_Desk_Area *eda;
425    E_Client *ec, *ec2;
426    unsigned int x;
427    Eina_Inlist *l;
428    E_Layer ec_layer, ec_layer_cw;
429    int cw_layer;
430
431    eda_client = wl_container_of(listener, eda_client, client_get_below);
432    ec = eda_client->ec;
433    eda = eda_client->eda;
434
435    if (EINA_INLIST_GET(ec)->prev) //check current layer
436      {
437         for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
438           {
439              ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
440              if (ec == ec2)
441                {
442                   ELOGF("FATAL", "CHECK the ec inlist prev", ec);
443                   continue;
444                }
445              if (!e_object_is_del(E_OBJECT(ec2)))
446                {
447                   get_below_data->below_ec = ec2;
448                   return;
449                }
450           }
451      }
452
453    // check layer validation
454    ec_layer = ec->layer;
455    if (ec->layer_block || ec->layer_pending)
456      {
457         cw_layer = e_comp_object_layer_get(ec->frame);
458         if (cw_layer >= 0)
459           {
460              ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
461              if (ec_layer != ec_layer_cw)
462                {
463                   ELOGF("EDA", "[eda:%p] LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)",
464                         ec, eda, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
465                   ec_layer = ec_layer_cw;
466                }
467           }
468      }
469
470    if (ec_layer == E_LAYER_CLIENT_DESKTOP) return;
471    if (e_comp_canvas_client_layer_map(ec_layer) == 9999) return;
472
473    /* go down the layers until we find one */
474    x = e_comp_canvas_layer_map(ec_layer);
475    if (x > 0) x--;
476
477    g_rec_mutex_lock(&e_comp->ec_list_mutex);
478
479    for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
480      {
481         if (!e_comp->layers[x].clients) continue;
482
483         EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
484           {
485              if (ec == ec2)
486                {
487                   ELOGF("FATAL", "[eda:%p] EC exist below layer. ec layer_map:%d, cur layer_map:%d",
488                         ec, eda, e_comp_canvas_layer_map(ec_layer), x);
489                   continue;
490                }
491              if (!e_object_is_del(E_OBJECT(ec2)))
492                {
493                   get_below_data->below_ec = ec2;
494                   g_rec_mutex_unlock(&e_comp->ec_list_mutex);
495                   return;
496                }
497           }
498      }
499
500    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
501 }
502
503 static void
504 _desk_area_cb_client_subsurface_stack_update(struct wl_listener *listener, void *data)
505 {
506    // TODO:
507 }
508 static void
509 _desk_area_cb_comp_object_lower(struct wl_listener *listener, void *data)
510 {
511    // TODO:
512 }
513
514 static void
515 _desk_area_cb_comp_object_raise(struct wl_listener *listener, void *data)
516 {
517    // TODO:
518 }
519
520 static void
521 _desk_area_cb_comp_object_set_layer(struct wl_listener *listener, void *data)
522 {
523    // TODO:
524 }
525
526 static void
527 _desk_area_cb_comp_object_stack_above(struct wl_listener *listener, void *data)
528 {
529    // TODO:
530 }
531
532 static void
533 _desk_area_cb_comp_object_stack_below(struct wl_listener *listener, void *data)
534 {
535    // TODO:
536 }
537
538 static Eina_Bool
539 _desk_area_smart_client_find(E_Desk_Area_Smart_Data *sd, E_Client *ec)
540 {
541    Eina_List *l;
542    E_Client *temp_ec;
543
544    EINA_LIST_FOREACH(sd->clients, l, temp_ec)
545      {
546         if (temp_ec == ec) return EINA_TRUE;
547      }
548
549    return EINA_FALSE;
550 }
551
552 static void
553 _e_desk_area_smart_client_add(Evas_Object *obj, E_Client *ec)
554 {
555    E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
556
557    if (_desk_area_smart_client_find(sd, ec))
558      return;
559
560    sd->clients = eina_list_append(sd->clients, ec);
561
562    evas_object_smart_changed(obj);
563 }
564
565 static void
566 _e_desk_area_smart_client_del(Evas_Object *obj, E_Client *ec)
567 {
568    E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
569
570    if (!_desk_area_smart_client_find(sd, ec))
571      return;
572
573    sd->clients = eina_list_remove(sd->clients, ec);
574
575    evas_object_smart_member_del(ec->frame);
576
577    evas_object_smart_changed(obj);
578 }
579
580 static void
581 _e_desk_area_smart_init(E_Desk_Area *eda)
582 {
583    eda->smart_obj = evas_object_smart_add(e_comp->evas, _e_desk_area_smart_class_new());
584
585    E_DESK_AREA_SMART_DATA_GET_OR_RETURN(eda->smart_obj, sd);
586
587    sd->eda = eda;
588 }
589 #endif
590
591 EINTERN E_Desk_Area *
592 e_desk_area_new(E_Desk *desk, int id, int x, int y, int w, int h, E_Desk_Area_Layer eda_layer)
593 {
594    E_Desk_Area *eda;
595 #ifdef REFACTOR_DESK_AREA
596    Evas_Object *obj;
597    E_Layer ec_layer;
598 #endif
599
600    E_OBJECT_CHECK_RETURN(desk, NULL);
601    E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
602
603    eda = E_OBJECT_ALLOC(E_Desk_Area, E_DESK_AREA_TYPE, _e_desk_area_free);
604    if (!eda) return NULL;
605
606    if (!_e_desk_area_private_init(eda))
607      {
608         e_object_del(E_OBJECT(eda));
609         return NULL;
610      }
611
612    eda->desk = desk;
613    eda->id = id;
614
615    _e_desk_geometry_info_set(eda, x, y, w, h);
616
617    eda->layer = eda_layer;
618
619 #ifdef REFACTOR_DESK_AREA
620    /* init smart object */
621    _e_desk_area_smart_init(eda);
622
623    /* init client's layers */
624    for (ec_layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); ec_layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); ec_layer++)
625      {
626
627         obj = e_comp->layers[ec_layer].obj = evas_object_rectangle_add(e_comp->evas);
628         evas_object_layer_set(obj, e_comp_canvas_layer_map_to(ec_layer));
629         evas_object_name_set(obj, "layer_obj");
630      }
631 #endif
632
633    eda->hook_subsurf_create = e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE,
634                                                  _e_desk_area_cb_hook_subsurface_create,
635                                                  NULL);
636
637    return eda;
638 }
639
640 #ifdef REFACTOR_DESK_AREA
641 #else
642 void _e_desk_area_ec_geometry_apply(E_Desk_Area *eda, E_Client *ec)
643 {
644    E_Maximize max;
645    E_Util_Transform *transform;
646
647    if (e_comp_wl_subsurface_check(ec))
648      return;
649
650    transform = ec->desk_area.transform;
651
652    if (eda->transform_enabled)
653      {
654         if (!transform) return;
655
656         e_util_transform_move(transform, eda->x, eda->y, 0);
657         e_util_transform_scale(transform, eda->scale_w, eda->scale_h, 1.0);
658         e_client_transform_core_add(ec, transform);
659
660         e_client_transform_core_update(ec);
661      }
662    else
663      {
664         if (transform)
665           {
666             e_util_transform_move(transform, 0, 0, 0);
667             e_util_transform_scale(transform, 1.0, 1.0, 1.0);
668             e_client_transform_core_remove(ec, transform);
669
670             e_client_transform_core_update(ec);
671           }
672
673         if (ec->lock_client_size)
674           {
675              max = ec->maximized;
676              ec->maximized = E_MAXIMIZE_NONE;
677              e_client_maximize(ec, max);
678           }
679      }
680 }
681
682 void _e_desk_area_ec_geometry_restore(E_Desk_Area *eda, E_Client *ec)
683 {
684    e_client_transform_core_update(ec);
685 }
686
687 void _e_desk_area_enable(E_Desk_Area *eda)
688 {
689    int i;
690    E_Client *ec;
691    Eina_List *l;
692    Eina_List *list;
693
694    if (!eda) return;
695
696    for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
697      {
698         list = eina_list_clone(eda->ec_lists[i]);
699         EINA_LIST_REVERSE_FOREACH(list, l, ec)
700           {
701              e_desk_area_ec_enable_set(eda, ec, EINA_TRUE);
702           }
703         eina_list_free(list);
704         list = NULL;
705      }
706 }
707
708 void _e_desk_area_disable(E_Desk_Area *eda)
709 {
710    int i;
711    E_Client *ec;
712    Eina_List *l = NULL;
713    Eina_List *list = NULL;
714
715    for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
716      {
717         list = eina_list_clone(eda->ec_lists[i]);
718         EINA_LIST_REVERSE_FOREACH(list, l, ec)
719           {
720              // unset ec's desk_area enable flag
721              e_desk_area_ec_enable_set(eda, ec, EINA_FALSE);
722              // restore original ec->layer
723              e_client_desk_area_original_layer_restore(ec);
724              // restore ec's original geometry (changing real geometry or using transform)
725              _e_desk_area_ec_geometry_restore(eda, ec);
726
727              e_desk_area_ec_remove(eda, ec);
728          }
729         eina_list_free(list);
730         list = NULL;
731
732         eina_list_free(eda->ec_lists[i]);
733         eda->ec_lists[i] = NULL;
734      }
735 }
736
737 EINTERN Eina_Bool
738 e_desk_area_enable_set(E_Desk_Area *eda, Eina_Bool enable)
739 {
740    if (!eda) return EINA_FALSE;
741
742    eda->enable = enable;
743    if (enable)
744      {
745         _e_desk_area_enable(eda);
746      }
747    else
748      {
749         _e_desk_area_disable(eda);
750      }
751
752    return EINA_TRUE;
753 }
754 #endif
755
756 EINTERN const char *
757 e_desk_area_name_get(E_Desk_Area *eda)
758 {
759    E_OBJECT_CHECK_RETURN(eda, NULL);
760    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, NULL);
761
762    return eda->name;
763 }
764
765 E_API Eina_Bool
766 e_desk_area_geometry_set(E_Desk_Area *eda, int x, int y, int w, int h)
767 {
768    E_OBJECT_CHECK_RETURN(eda, EINA_FALSE);
769    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, EINA_FALSE);
770
771    _e_desk_geometry_info_set(eda, x, y, w, h);
772
773    return EINA_TRUE;
774 }
775
776 E_API Eina_Bool
777 e_desk_area_geometry_get(E_Desk_Area *eda, int *x, int *y, int *w, int *h)
778 {
779    E_OBJECT_CHECK_RETURN(eda, EINA_FALSE);
780    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, EINA_FALSE);
781
782    if (x) *x = eda->x;
783    if (y) *y = eda->y;
784    if (w) *w = eda->w;
785    if (h) *h = eda->h;
786
787    return EINA_TRUE;
788 }
789
790 EINTERN Eina_Bool
791 e_desk_area_layer_set(E_Desk_Area *eda, E_Desk_Area_Layer eda_layer)
792 {
793    E_OBJECT_CHECK_RETURN(eda, EINA_FALSE);
794    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, EINA_FALSE);
795
796    eda->layer = eda_layer;
797
798    return EINA_TRUE;
799 }
800
801 E_API E_Desk_Area_Layer
802 e_desk_area_layer_get(E_Desk_Area *eda)
803 {
804    E_OBJECT_CHECK_RETURN(eda, E_DESK_AREA_LAYER_NORMAL);
805    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, E_DESK_AREA_LAYER_NORMAL);
806
807    return eda->layer;
808 }
809
810 E_API void
811 e_desk_area_activate(E_Desk_Area *eda)
812 {
813    if (!eda) return;
814    if (!eda->desk) return;
815
816    e_desk_area_raise(eda);
817    _e_desk_area_active_change(eda, eda->desk);
818 }
819
820 E_API Eina_Bool
821 e_desk_area_is_activate(E_Desk_Area *eda)
822 {
823    if (!eda) return EINA_FALSE;
824    return eda->active;
825 }
826
827 E_API void
828 e_desk_area_raise(E_Desk_Area *eda)
829 {
830    int i;
831    E_Client *ec;
832    Eina_List *l = NULL;
833    Eina_List *ll = NULL;
834
835    if (!eda) return;
836
837    for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
838      {
839         EINA_LIST_REVERSE_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
840           {
841              evas_object_raise(ec->frame);
842           }
843      }
844 }
845
846 E_API void
847 e_desk_area_lower(E_Desk_Area *eda)
848 {
849    int i;
850    E_Client *ec;
851    Eina_List *l = NULL;
852    Eina_List *ll = NULL;
853
854    if (!eda) return;
855
856    for (i=E_DESK_AREA_CLIENT_LAYER_MAX-1; i>=0; i--)
857      {
858         //EINA_LIST_FOREACH(eda->ec_lists[i], l, ec)
859         EINA_LIST_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
860           {
861              evas_object_lower(ec->frame);
862           }
863      }
864 }
865
866 #ifdef REFACTOR_DESK_AREA
867 #else
868 static E_Desk_Area_Client_Layer
869 _e_desk_area_client_layer_convert_from_layer(E_Layer layer)
870 {
871    E_Desk_Area_Client_Layer edg_layer;
872
873    if (layer <= E_LAYER_CLIENT_DESKTOP)
874      edg_layer = E_DESK_AREA_CLIENT_LAYER_DESKTOP;
875    else if (layer <= E_LAYER_CLIENT_BELOW)
876      edg_layer = E_DESK_AREA_CLIENT_LAYER_BELOW;
877    else if (layer <= E_LAYER_CLIENT_NORMAL)
878      edg_layer = E_DESK_AREA_CLIENT_LAYER_NORMAL;
879    else if (layer <= E_LAYER_CLIENT_ABOVE)
880      edg_layer = E_DESK_AREA_CLIENT_LAYER_ABOVE;
881    else if (layer <= E_LAYER_CLIENT_NOTIFICATION_LOW)
882      edg_layer = E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_LOW;
883    else if (layer <= E_LAYER_CLIENT_NOTIFICATION_NORMAL)
884      edg_layer = E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_NORMAL;
885    else if (layer <= E_LAYER_CLIENT_NOTIFICATION_HIGH)
886      edg_layer = E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_HIGH;
887    else if (layer <= E_LAYER_CLIENT_NOTIFICATION_TOP)
888      edg_layer = E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_TOP;
889    else
890      edg_layer = E_DESK_AREA_CLIENT_LAYER_ALERT;
891
892    return edg_layer;
893 }
894 #endif
895
896 #ifdef REFACTOR_DESK_AREA
897 static E_Desk_Area_Private_Client *
898 _e_desk_area_ec_find_client(E_Desk_Area *eda, E_Client *ec)
899 {
900    Eina_List *l;
901    E_Desk_Area_Private_Client *eda_client;
902
903    EINA_LIST_FOREACH(eda->clients, l, eda_client)
904      {
905         if (eda_client->ec == ec)
906           return eda_client;
907      }
908
909    return NULL;
910 }
911 #endif
912
913 E_API Eina_Bool
914 e_desk_area_ec_add(E_Desk_Area *eda, E_Client *ec)
915 {
916 #ifdef REFACTOR_DESK_AREA
917 #else
918    E_Desk_Area_Client_Layer edgc_layer;
919    E_Layer layer;
920 #endif
921
922 #ifdef REFACTOR_DESK_AREA
923    E_Desk_Area_Private_Client *eda_client;
924
925    E_OBJECT_CHECK_RETURN(eda, EINA_FALSE);
926    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, EINA_FALSE);
927    E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
928    E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
929
930    if (_e_desk_area_ec_find_client(eda, ec)) return EINA_FALSE;
931
932    ELOGF("EAD", "CLIENT ADD", ec);
933
934    eda_client = E_NEW(E_Desk_Area_Private_Client, 1);
935    EINA_SAFETY_ON_NULL_RETURN_VAL(eda_client, EINA_FALSE);
936
937    eda_client->eda = eda;
938    eda_client->ec = ec;
939
940    // e_client listeners
941    eda_client->client_get_above.notify = _desk_area_cb_client_get_above;
942    e_client_get_above_listener_add(ec, &eda_client->client_get_above);
943    eda_client->client_get_below.notify = _desk_area_cb_client_get_below;
944    e_client_get_below_listener_add(ec, &eda_client->client_get_below);
945    eda_client->client_subsurface_stack_update.notify = _desk_area_cb_client_subsurface_stack_update;
946    e_client_subsurface_stack_update_listener_add(ec, &eda_client->client_subsurface_stack_update);
947
948    // e_comp_object listeners
949    eda_client->comp_object_lower.notify = _desk_area_cb_comp_object_lower;
950    e_comp_object_lower_listener_add(ec->frame, &eda_client->comp_object_lower);
951    eda_client->comp_object_raise.notify = _desk_area_cb_comp_object_raise;
952    e_comp_object_raise_listener_add(ec->frame, &eda_client->comp_object_raise);
953    eda_client->comp_object_set_layer.notify = _desk_area_cb_comp_object_set_layer;
954    e_comp_object_set_layer_listener_add(ec->frame, &eda_client->comp_object_set_layer);
955    eda_client->comp_object_stack_above.notify = _desk_area_cb_comp_object_stack_above;
956    e_comp_object_stack_above_listener_add(ec->frame, &eda_client->comp_object_stack_above);
957    eda_client->comp_object_stack_below.notify = _desk_area_cb_comp_object_stack_below;
958    e_comp_object_stack_below_listener_add(ec->frame, &eda_client->comp_object_stack_below);
959
960    eda->clients = eina_list_append(eda->clients, eda_client);
961
962    _e_desk_area_smart_client_add(eda->smart_obj, ec);
963 #else
964    layer = e_client_desk_area_original_layer_get(ec);
965    edgc_layer = _e_desk_area_client_layer_convert_from_layer(layer);
966
967    eda->ec_lists[edgc_layer] = eina_list_prepend(eda->ec_lists[edgc_layer], ec);
968
969    e_client_desk_area_client_layer_set(ec, edgc_layer);
970 #endif
971
972    return EINA_TRUE;
973 }
974
975 E_API void
976 e_desk_area_ec_remove(E_Desk_Area *eda, E_Client *ec)
977 {
978 #ifdef REFACTOR_DESK_AREA
979    E_Desk_Area_Private_Client *eda_client;
980
981    E_OBJECT_CHECK(eda);
982    E_OBJECT_TYPE_CHECK(eda, E_DESK_AREA_TYPE);
983    E_OBJECT_CHECK(ec);
984    E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
985
986    // TODO: this code has to be refactoring
987    e_util_transform_del(ec->desk_area.transform);
988    ec->desk_area.transform = NULL;
989
990    eda_client = _e_desk_area_ec_find_client(eda, ec);
991    if (!eda_client) return;
992
993    ELOGF("EDA", "CLIENT DEL", ec);
994
995    _e_desk_area_smart_client_del(eda->smart_obj, ec);
996
997    eda->clients = eina_list_remove(eda->clients, eda_client);
998
999    // wl_list remove
1000    wl_list_remove(&eda_client->comp_object_stack_below.link);
1001    wl_list_remove(&eda_client->comp_object_stack_above.link);
1002    wl_list_remove(&eda_client->comp_object_set_layer.link);
1003    wl_list_remove(&eda_client->comp_object_lower.link);
1004    wl_list_remove(&eda_client->comp_object_raise.link);
1005    wl_list_remove(&eda_client->client_subsurface_stack_update.link);
1006    wl_list_remove(&eda_client->client_get_below.link);
1007    wl_list_remove(&eda_client->client_get_above.link);
1008
1009    E_FREE(eda_client);
1010 #else
1011    E_Desk_Area_Client_Layer edgc_layer;
1012
1013    edgc_layer = e_client_desk_area_client_layer_get(ec);
1014    if (!_check_desk_area_client_layer_validation(edgc_layer)) return;
1015
1016    eda->ec_lists[edgc_layer] = eina_list_remove(eda->ec_lists[edgc_layer], ec);
1017 #endif
1018 }
1019
1020 #ifdef REFACTOR_DESK_AREA
1021 #else
1022 static E_Client *
1023 _find_above_ec_in_same_edgc_layer(E_Desk_Area *eda, E_Client *ec)
1024 {
1025    Eina_List *l;
1026    E_Client *above = NULL;
1027    E_Client *temp = NULL;
1028    E_Desk_Area_Client_Layer edgc_layer;
1029    Eina_Bool find = EINA_FALSE;
1030
1031    edgc_layer = e_client_desk_area_client_layer_get(ec);
1032    if (!_check_desk_area_client_layer_validation(edgc_layer)) return NULL;
1033
1034    EINA_LIST_REVERSE_FOREACH(eda->ec_lists[edgc_layer], l, temp)
1035      {
1036         if (find)
1037           {
1038              above = temp;
1039              break;
1040           }
1041
1042         if (temp == ec)
1043           {
1044              find = EINA_TRUE;
1045           }
1046      }
1047
1048    // TODO: do we need check below->frame???
1049
1050    return above;
1051 }
1052
1053 static E_Client *
1054 _find_bottom_ec_in_above_edgc_layer(E_Desk_Area *eda, E_Client *ec)
1055 {
1056    Eina_List *l;
1057    E_Client *bottom = NULL;
1058    E_Desk_Area_Client_Layer edgc_layer;
1059    int i;
1060
1061    edgc_layer = e_client_desk_area_client_layer_get(ec);
1062    if (!_check_desk_area_client_layer_validation(edgc_layer)) return NULL;
1063
1064    for (i = edgc_layer+1; i < E_DESK_AREA_CLIENT_LAYER_MAX; i++)
1065      {
1066         EINA_LIST_REVERSE_FOREACH(eda->ec_lists[i], l, bottom)
1067           {
1068              // TODO: do we need check below->frame???
1069              if (bottom)
1070                return bottom;
1071           }
1072      }
1073
1074    return NULL;
1075 }
1076
1077 static E_Client *
1078 _find_bottom_ec_in_above_edg(E_Desk_Area *eda)
1079 {
1080    E_Desk_Area *above_edg = NULL;
1081    E_Client *bottom = NULL;
1082    Eina_List *l;
1083    int i;
1084
1085    above_edg = e_desk_desk_area_above_get(eda->desk, eda);
1086    while (above_edg)
1087      {
1088         for (i=E_DESK_AREA_CLIENT_LAYER_DESKTOP; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
1089           {
1090              EINA_LIST_REVERSE_FOREACH(above_edg->ec_lists[i], l, bottom)
1091                {
1092                   if (bottom)
1093                     goto find_bottom;
1094                }
1095           }
1096
1097         bottom = NULL;
1098         above_edg = e_desk_desk_area_above_get(above_edg->desk, above_edg);
1099      }
1100
1101 find_bottom:
1102    return bottom;
1103 }
1104
1105 static E_Client *
1106 _find_below_ec_in_same_edgc_layer(E_Desk_Area *eda, E_Client *ec)
1107 {
1108    Eina_List *l;
1109    E_Client *below = NULL;
1110    E_Client *temp = NULL;
1111    E_Desk_Area_Client_Layer edgc_layer;
1112    Eina_Bool find = EINA_FALSE;
1113
1114    edgc_layer = e_client_desk_area_client_layer_get(ec);
1115    if (!_check_desk_area_client_layer_validation(edgc_layer)) return NULL;
1116
1117    EINA_LIST_FOREACH(eda->ec_lists[edgc_layer], l, temp)
1118      {
1119         if (find)
1120           {
1121              below = temp;
1122              break;
1123           }
1124
1125         if (temp == ec)
1126           {
1127              find = EINA_TRUE;
1128           }
1129      }
1130
1131    // TODO: do we need check below->frame???
1132
1133    return below;
1134 }
1135
1136 static E_Client *
1137 _find_top_ec_in_below_edgc_layer(E_Desk_Area *eda, E_Client *ec)
1138 {
1139    Eina_List *l;
1140    E_Client *top = NULL;
1141    E_Desk_Area_Client_Layer edgc_layer;
1142    int i;
1143
1144    edgc_layer = e_client_desk_area_client_layer_get(ec);
1145    if (!_check_desk_area_client_layer_validation(edgc_layer)) return NULL;
1146
1147    for (i = edgc_layer-1; i >= E_DESK_AREA_CLIENT_LAYER_DESKTOP; i--)
1148      {
1149         EINA_LIST_FOREACH(eda->ec_lists[i], l, top)
1150           {
1151              // TODO: do we need check top->frame???
1152              if (top)
1153                return top;
1154           }
1155      }
1156
1157    return NULL;
1158 }
1159
1160 static E_Client *
1161 _find_top_ec_in_below_edg(E_Desk_Area *eda)
1162 {
1163    E_Desk_Area *below_edg = NULL;
1164    E_Client *top = NULL;
1165    Eina_List *l;
1166    int i;
1167
1168    below_edg = e_desk_desk_area_below_get(eda->desk, eda);
1169    while (below_edg)
1170      {
1171         for (i=E_DESK_AREA_CLIENT_LAYER_MAX-1; i>=E_DESK_AREA_CLIENT_LAYER_DESKTOP; i--)
1172           {
1173              EINA_LIST_FOREACH(below_edg->ec_lists[i], l, top)
1174                {
1175                   if (top)
1176                     goto find_top;
1177                }
1178           }
1179
1180         top = NULL;
1181         below_edg = e_desk_desk_area_below_get(below_edg->desk, below_edg);
1182      }
1183
1184 find_top:
1185    return top;
1186 }
1187
1188 EINTERN void
1189 e_desk_area_ec_raise(E_Desk_Area *eda, E_Client *ec)
1190 {
1191    E_Client *below = NULL;
1192    E_Client *above = NULL;
1193
1194    if (!eda) return;
1195    if (!ec) return;
1196
1197    ELOGF("EDG", "RAISE... eda:%p", ec, eda);
1198
1199    _e_desk_area_ec_prepend(eda, ec);
1200
1201    // 1. find below ec in same edgc layer in same eda
1202    below = _find_below_ec_in_same_edgc_layer(eda, ec);
1203    if (below) goto find_below;
1204
1205    // 2. find above ec in same edgc layer in same eda
1206    above = _find_above_ec_in_same_edgc_layer(eda, ec);
1207    if (above) goto find_above;
1208
1209    // 3. find bottom ec in above edgc layer in same eda
1210    above = _find_bottom_ec_in_above_edgc_layer(eda, ec);
1211    if (above) goto find_above;
1212
1213    // 4. find bottom ec in above eda
1214    above = _find_bottom_ec_in_above_edg(eda);
1215    if (above) goto find_above;
1216
1217    // 5. if not found, just evas_object_raise
1218    ELOGF("EDG", "RAISE... call evas_object_raise", ec);
1219    evas_object_raise(ec->frame);
1220    return;
1221
1222 find_below:
1223    if (below)
1224      {
1225         ELOGF("EDG", "STACK_ABOVE... below(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(below), below);
1226         if (below->frame)
1227           {
1228              ELOGF("EDG", "STACK_ABOVE... call evas_object_stack_above", ec);
1229              evas_object_stack_above(ec->frame, below->frame);
1230           }
1231      }
1232    return;
1233
1234 find_above:
1235    if (above)
1236      {
1237         ELOGF("EDG", "STACK_BELOW... above(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(above), above);
1238         if (above->frame)
1239           {
1240              ELOGF("EDG", "STACK_BELOW... call evas_object_stack_below", ec);
1241              evas_object_stack_below(ec->frame, above->frame);
1242           }
1243      }
1244    return;
1245 }
1246
1247 EINTERN void
1248 e_desk_area_ec_lower(E_Desk_Area *eda, E_Client *ec)
1249 {
1250    E_Client *above = NULL;
1251    E_Client *below = NULL;
1252
1253    if (!eda) return;
1254    if (!ec) return;
1255
1256    ELOGF("EDG", "LOWER... eda:%p", ec, eda);
1257
1258    _e_desk_area_ec_append(eda, ec);
1259
1260    // 1. find above ec in same edgc layer in same eda
1261    above = _find_above_ec_in_same_edgc_layer(eda, ec);
1262    if (above) goto find_above;
1263
1264    // 2. find below ec in same edgc layer in same eda
1265    below = _find_below_ec_in_same_edgc_layer(eda, ec);
1266    if (below) goto find_below;
1267
1268    // 3. find top ec in below edgc layer in same eda
1269    below = _find_top_ec_in_below_edgc_layer(eda, ec);
1270    if (below) goto find_below;
1271
1272    // 4. find top ec in below eda
1273    below = _find_top_ec_in_below_edg(eda);
1274    if (below) goto find_below;
1275
1276    // 5. if not found, just evas_object_raise
1277    ELOGF("EDG", "LOWER... call evas_object_raise", ec);
1278    evas_object_lower(ec->frame);
1279    return;
1280
1281 find_below:
1282    if (below)
1283      {
1284         ELOGF("EDG", "STACK_ABOVE... below(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(below), below);
1285         if (below->frame)
1286           {
1287              ELOGF("EDG", "STACK_ABOVE... call evas_object_stack_above", ec);
1288              evas_object_stack_above(ec->frame, below->frame);
1289           }
1290      }
1291    return;
1292
1293 find_above:
1294    if (above)
1295      {
1296         ELOGF("EDG", "STACK_BELOW... above(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(above), above);
1297         if (above->frame)
1298           {
1299              ELOGF("EDG", "STACK_BELOW... call evas_object_stack_below", ec);
1300              evas_object_stack_below(ec->frame, above->frame);
1301           }
1302      }
1303    return;
1304 }
1305
1306 EINTERN void
1307 e_desk_area_ec_stack_above(E_Desk_Area *eda, E_Client *ec, E_Client *above)
1308 {
1309    if (!eda) return;
1310    if (!ec) return;
1311    if (!ec->frame) return;
1312    if (!above) return;
1313    if (!above->frame) return;
1314
1315    _e_desk_area_ec_prepend_relative(eda, ec, above);
1316
1317    evas_object_stack_above(ec->frame, above->frame);
1318 }
1319
1320 EINTERN void
1321 e_desk_area_ec_stack_below(E_Desk_Area *eda, E_Client *ec, E_Client *below)
1322 {
1323    if (!eda) return;
1324    if (!ec) return;
1325    if (!ec->frame) return;
1326    if (!below) return;
1327    if (!below->frame) return;
1328
1329    _e_desk_area_ec_append_relative(eda, ec, below);
1330
1331    evas_object_stack_below(ec->frame, below->frame);
1332 }
1333
1334 EINTERN void
1335 e_desk_area_ec_edg_layer_set(E_Desk_Area *eda, E_Client *ec, E_Layer layer)
1336 {
1337    E_Desk_Area_Client_Layer edg_layer;
1338
1339    if (!eda) return;
1340    if (!ec) return;
1341
1342    // save original layer
1343
1344    edg_layer = eda->layer;
1345    evas_object_layer_set(ec->frame, edg_layer);
1346 }
1347
1348 static void
1349 _e_desk_area_ec_restack(E_Desk_Area *eda, E_Client *ec)
1350 {
1351    E_Client *above = NULL, *below = NULL;
1352
1353    // 1. find below ec in same edgc layer in same eda
1354    below = _find_below_ec_in_same_edgc_layer(eda, ec);
1355    if (below) goto find_below;
1356
1357    // 2. find above ec in same edgc layer in same eda
1358    above = _find_above_ec_in_same_edgc_layer(eda, ec);
1359    if (above) goto find_above;
1360
1361    // 3. find bottom ec in above edgc layer in same eda
1362    above = _find_bottom_ec_in_above_edgc_layer(eda, ec);
1363    if (above) goto find_above;
1364
1365    // 4. find bottom ec in above eda
1366    above = _find_bottom_ec_in_above_edg(eda);
1367    if (above) goto find_above;
1368
1369    // 5. if not found, just evas_object_raise
1370    ELOGF("EDG", "RESTACK raise... call evas_object_raise", ec);
1371    evas_object_raise(ec->frame);
1372    return;
1373
1374 find_below:
1375    if (below)
1376      {
1377         ELOGF("EDG", "STACK_ABOVE... below(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(below), below);
1378         if (below->frame)
1379           {
1380              ELOGF("EDG", "STACK_ABOVE... call evas_object_stack_above", ec);
1381              evas_object_stack_above(ec->frame, below->frame);
1382           }
1383      }
1384    return;
1385
1386 find_above:
1387    if (above)
1388      {
1389         ELOGF("EDG", "STACK_BELOW... above(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(above), above);
1390         if (above->frame)
1391           {
1392              ELOGF("EDG", "STACK_BELOW... call evas_object_stack_below", ec);
1393              evas_object_stack_below(ec->frame, above->frame);
1394           }
1395      }
1396    return;
1397 }
1398
1399 EINTERN void
1400 e_desk_area_ec_rearrange(E_Desk_Area *eda, E_Client *ec)
1401 {
1402    E_Layer layer;
1403    E_Desk_Area_Client_Layer edgc_layer, prev_edgc_layer;
1404
1405    ELOGF("EDG", "RE-ARRANGE... eda:%p", ec, eda);
1406
1407    if (!eda) return;
1408    if (!ec) return;
1409
1410    prev_edgc_layer = e_client_desk_area_client_layer_get(ec);
1411    if (!_check_desk_area_client_layer_validation(prev_edgc_layer)) return;
1412    
1413    eda->ec_lists[prev_edgc_layer] = eina_list_remove(eda->ec_lists[prev_edgc_layer], ec);
1414
1415    layer = e_client_desk_area_original_layer_get(ec);
1416    edgc_layer = _e_desk_area_client_layer_convert_from_layer(layer);
1417    eda->ec_lists[edgc_layer] = eina_list_prepend(eda->ec_lists[edgc_layer], ec);
1418
1419    e_client_desk_area_client_layer_set(ec, edgc_layer);
1420
1421    _e_desk_area_ec_restack(eda, ec);
1422 }
1423
1424 EINTERN void
1425 e_desk_area_ec_stack_change(E_Desk_Area *eda, E_Client *ec)
1426 {
1427 }
1428
1429 E_API void
1430 e_desk_area_ec_update(E_Desk_Area *eda, E_Client *ec)
1431 {
1432    E_Layer layer;
1433
1434    if (!eda) return;
1435    if (!ec) return;
1436
1437    layer = e_client_desk_area_original_layer_get(ec);
1438
1439    // update stack
1440    e_client_layer_set_by_desk_area(ec, layer);
1441
1442    // update geometry
1443    _e_desk_area_ec_geometry_apply(eda, ec);
1444 }
1445
1446 E_API void
1447 e_desk_area_all_ec_update(E_Desk_Area *eda)
1448 {
1449    int i;
1450    E_Client *ec;
1451    Eina_List *l;
1452    Eina_List *list;
1453
1454    if (!eda) return;
1455
1456    for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
1457      {
1458         list = eina_list_clone(eda->ec_lists[i]);
1459
1460         EINA_LIST_REVERSE_FOREACH(list, l, ec)
1461           {
1462              e_desk_area_ec_update(eda, ec);
1463           }
1464
1465         eina_list_free(list);
1466         list = NULL;
1467      }
1468 }
1469
1470 E_API Eina_List *
1471 e_desk_area_ec_list_get(E_Desk_Area *eda)
1472 {
1473    if (!eda) return NULL;
1474
1475    return NULL;
1476 }
1477
1478 E_API void
1479 e_desk_area_transform_enable_set(E_Desk_Area *eda, Eina_Bool enable)
1480 {
1481    if (!eda) return;
1482
1483    eda->transform_enabled = enable;
1484 }
1485
1486 E_API Eina_Bool
1487 e_desk_area_transform_enable_get(E_Desk_Area *eda)
1488 {
1489    if (!eda) return EINA_FALSE;
1490
1491    return eda->transform_enabled;
1492 }
1493 #endif
1494
1495 // for debug
1496 EINTERN void
1497 e_desk_area_info_print(E_Desk_Area *eda)
1498 {
1499 #ifdef REFACTOR_DESK_AREA
1500    Eina_List *l;
1501    E_Client *ec;
1502
1503    if (!eda) return;
1504
1505    ELOGF("EDG_INFO", "===========================================", NULL);
1506    ELOGF("EDG_INFO", "E_Desk_Area(%p), ID(%d), Geo(%d,%d,%d,%d), Layer:%d", NULL, eda, eda->id, eda->x, eda->y, eda->w, eda->h, eda->layer);
1507    ELOGF("EDG_INFO", "-------------------------------------------", NULL);
1508    for (int i=E_DESK_AREA_CLIENT_LAYER_MAX-1; i>=0; i--)
1509      {
1510         EINA_LIST_FOREACH(eda->ec_lists[i], l, ec)
1511           {
1512              ELOGF("EDG_INFO", "EDG_Layer[%d] Win:0x%08zx, EC:%p, frame:%p, ec->layer:%d, org_layer:%d, name:%s", NULL, i, e_client_util_win_get(ec), ec, ec->frame, ec->layer, ec->desk_area.layer_backup, ec->icccm.title ? ec->icccm.title:"NO NAME");
1513           }
1514      }
1515    ELOGF("EDG_INFO", "===========================================", NULL);
1516 #endif
1517 }
1518
1519 static void
1520 _e_desk_area_hooks_clean(void)
1521 {
1522    Eina_Inlist *l;
1523    E_Desk_Area_Hook *dgh;
1524    unsigned int x;
1525
1526    for (x = 0; x < E_DESK_AREA_HOOK_LAST; x++)
1527      EINA_INLIST_FOREACH_SAFE(_e_desk_area_hooks[x], l, dgh)
1528        {
1529           if (!dgh->delete_me) continue;
1530           _e_desk_area_hooks[x] = eina_inlist_remove(_e_desk_area_hooks[x], EINA_INLIST_GET(dgh));
1531           free(dgh);
1532        }
1533
1534    _e_desk_area_hooks_delete = 0;
1535 }
1536
1537 static Eina_Bool
1538 _e_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *data)
1539 {
1540    E_Desk_Area_Hook *dgh;
1541
1542    e_object_ref(E_OBJECT(desk_area));
1543    _e_desk_area_hooks_walking++;
1544    EINA_INLIST_FOREACH(_e_desk_area_hooks[hookpoint], dgh)
1545      {
1546         if (dgh->delete_me) continue;
1547         dgh->func(dgh->data, desk_area, data);
1548      }
1549    _e_desk_area_hooks_walking--;
1550    if ((_e_desk_area_hooks_walking == 0) && (_e_desk_area_hooks_delete > 0))
1551      _e_desk_area_hooks_clean();
1552
1553    return !!e_object_unref(E_OBJECT(desk_area));
1554 }
1555
1556 EINTERN Eina_Bool
1557 e_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data)
1558 {
1559    return _e_desk_area_hook_call(hookpoint, eda, data);
1560 }
1561
1562 E_API E_Desk_Area_Hook *
1563 e_desk_area_hook_add(E_Desk_Area_Hook_Point hookpoint,
1564       E_Desk_Area_Hook_Cb func, const void *data)
1565 {
1566    E_Desk_Area_Hook *dgh;
1567
1568    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_DESK_AREA_HOOK_LAST, NULL);
1569    dgh = E_NEW(E_Desk_Area_Hook, 1);
1570    if (!dgh) return NULL;
1571
1572    dgh->hookpoint = hookpoint;
1573    dgh->func = func;
1574    dgh->data = (void*)data;
1575
1576    _e_desk_area_hooks[hookpoint] =
1577       eina_inlist_append(_e_desk_area_hooks[hookpoint], EINA_INLIST_GET(dgh));
1578
1579    return dgh;
1580 }
1581
1582 E_API void
1583 e_desk_area_hook_del(E_Desk_Area_Hook * dgh)
1584 {
1585    dgh->delete_me = 1;
1586
1587    if (_e_desk_area_hooks_walking == 0)
1588      {
1589         _e_desk_area_hooks[dgh->hookpoint] =
1590             eina_inlist_remove(_e_desk_area_hooks[dgh->hookpoint], EINA_INLIST_GET(dgh));
1591         free(dgh);
1592      }
1593    else
1594      _e_desk_area_hooks_delete++;
1595 }
1596
1597 #ifdef REFACTOR_DESK_AREA
1598 #else
1599 E_API Eina_Bool
1600 e_desk_area_ec_reassign(E_Desk_Area *eda, E_Client *ec)
1601 {
1602    E_Desk_Area *old_edg;
1603
1604    if (!ec) return EINA_FALSE;
1605
1606 #if 0 // if this is removed.. then below if (eda != old_edg) is removed also...
1607    if (ec->desk_area.desk_area == eda)
1608      return EINA_TRUE;
1609 #endif
1610
1611    ELOGF("EDG", "Desk Group Set (new:%p, old:%p)", ec, eda, ec->desk_area.desk_area);
1612    old_edg = ec->desk_area.desk_area;
1613    if (old_edg)
1614      e_desk_area_ec_remove(old_edg, ec);
1615
1616    ec->desk_area.desk_area = eda;
1617    e_desk_area_ec_add(eda, ec);
1618
1619 #if 0 // if this is removed.. then above if (ec->desk_area.desk_area == eda) is removed also...
1620    if (eda != old_edg)
1621 #endif
1622      {
1623         e_desk_area_ec_update(eda, ec);
1624         e_desk_area_ec_rearrange(ec->desk_area.desk_area, ec);
1625      }
1626
1627    return EINA_TRUE;
1628 }
1629
1630 EINTERN Eina_Bool
1631 e_desk_area_ec_enable_set(E_Desk_Area *eda, E_Client *ec, Eina_Bool enable)
1632 {
1633    if (!eda) return EINA_FALSE;
1634    if (!ec) return EINA_FALSE;
1635
1636    ec->desk_area.enable = enable;
1637
1638    ELOGF("EDG", "Desk group enable set to %d", ec, enable);
1639    if (enable)
1640      {
1641         if (!ec->desk_area.transform)
1642           {
1643              ec->desk_area.transform = e_util_transform_new();
1644              e_util_transform_role_set(ec->desk_area.transform, "desk_area");
1645           }
1646      }
1647    else
1648      {
1649         if (ec->desk_area.transform)
1650           {
1651              e_util_transform_del(ec->desk_area.transform);
1652              ec->desk_area.transform = NULL;
1653           }
1654      }
1655
1656    e_desk_area_ec_update(ec->desk_area.desk_area, ec);
1657
1658    return EINA_TRUE;
1659 }
1660 #endif
1661
1662 static void
1663 _desk_area_cb_splitscreen_region_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1664 {
1665    //TODO:
1666 }
1667
1668 static void
1669 _desk_area_cb_splitscreen_region_assign_appid(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1670 {
1671   E_Desk_Area_Private *priv;
1672   const char *appid = data;
1673
1674   priv = container_of(listener, E_Desk_Area_Private, splitscreen_region_assign_appid);
1675
1676   e_desk_area_hook_call(priv->eda, E_DESK_AREA_HOOK_SET_APPID, (void *)appid);
1677 }
1678
1679 EINTERN Eina_Bool
1680 e_desk_area_splitscreen_region_enable(E_Desk_Area *eda, struct ds_tizen_splitscreen_region *splitscreen_region)
1681 {
1682    API_ENTRY_VAL(EINA_FALSE);
1683
1684    if (!splitscreen_region) return EINA_FALSE;
1685
1686    priv->splitscreen_region = splitscreen_region;
1687    priv->splitscreen_region_destroy.notify = _desk_area_cb_splitscreen_region_destroy;
1688    ds_tizen_splitscreen_region_add_destroy_listener(
1689          priv->splitscreen_region, &priv->splitscreen_region_destroy);
1690    priv->splitscreen_region_assign_appid.notify = _desk_area_cb_splitscreen_region_assign_appid;
1691    ds_tizen_splitscreen_region_add_assign_appid_listener(
1692          priv->splitscreen_region, &priv->splitscreen_region_assign_appid);
1693
1694    return EINA_TRUE;
1695 }
1696
1697
1698 #ifdef REFACTOR_DESK_AREA
1699 EINTERN E_Client *
1700 e_desk_area_top_ec_get(E_Desk_Area *eda)
1701 {
1702    E_Client *ec;
1703    unsigned int x;
1704
1705    g_rec_mutex_lock(&e_comp->ec_list_mutex);
1706
1707    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
1708      {
1709         if (!e_comp->layers[x].clients) continue;
1710
1711         EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec)
1712           if (!e_object_is_del(E_OBJECT(ec)))
1713             {
1714                g_rec_mutex_unlock(&e_comp->ec_list_mutex);
1715                return ec;
1716             }
1717      }
1718
1719    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
1720
1721    return NULL;
1722 }
1723
1724 EINTERN E_Client *
1725 e_desk_area_bottom_ec_get(E_Desk_Area *eda)
1726 {
1727    E_Client *ec;
1728    unsigned int x;
1729
1730    g_rec_mutex_lock(&e_comp->ec_list_mutex);
1731
1732    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
1733      {
1734         if (!e_comp->layers[x].clients) continue;
1735
1736         EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec)
1737           if (!e_object_is_del(E_OBJECT(ec)))
1738             {
1739                g_rec_mutex_unlock(&e_comp->ec_list_mutex);
1740                return ec;
1741             }
1742      }
1743
1744    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
1745
1746    return NULL;
1747 }
1748 #endif