e_keyrouter: take keyrouter functions to enlightenment's core
[platform/upstream/enlightenment.git] / src / bin / e_comp_canvas.c
1 #include "e.h"
2
3 static Eina_List *handlers;
4 static Eina_Bool _ev_freeze = EINA_FALSE;
5
6 static void
7 _e_comp_canvas_cb_del()
8 {
9    E_FREE_LIST(handlers, ecore_event_handler_del);
10 }
11
12 static void
13 _e_comp_canvas_event_compositor_resize_free(void *data EINA_UNUSED, void *event EINA_UNUSED)
14 {
15    e_object_unref(E_OBJECT(e_comp));
16 }
17
18 ///////////////////////////////////
19
20 static void
21 _e_comp_canvas_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
22 {
23    E_Client *ec;
24    EINA_LIST_FREE(e_comp->post_updates, ec)
25      {
26         ec->on_post_updates = EINA_FALSE;
27         if (!e_object_is_del(E_OBJECT(ec)))
28           e_pixmap_image_clear(ec->pixmap, 1);
29         e_object_unref(E_OBJECT(ec));
30      }
31 }
32
33 ///////////////////////////////////
34
35 static void
36 _e_comp_canvas_cb_mouse_in(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
37 {
38    E_Client *ec;
39
40    if (e_client_action_get()) return;
41    ec = e_client_focused_get();
42    if (ec) e_focus_event_mouse_out(ec);
43 }
44
45 static void
46 _e_comp_canvas_cb_mouse_down(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
47 {
48    /* Do nothing */
49    ;
50 }
51
52 static void
53 _e_comp_canvas_cb_mouse_up(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
54 {
55    /* Do nothing */
56    ;
57 }
58
59 static void
60 _e_comp_canvas_cb_mouse_wheel(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
61 {
62    /* Do nothing */
63    ;
64 }
65
66 ////////////////////////////////////
67
68 static Eina_Bool
69 _e_comp_cb_zone_change()
70 {
71    e_comp_canvas_update();
72    return ECORE_CALLBACK_PASS_ON;
73 }
74
75 ////////////////////////////////////
76
77 static int
78 _e_comp_canvas_cb_zone_sort(const void *data1, const void *data2)
79 {
80    const E_Zone *z1 = data1, *z2 = data2;
81
82    return z1->num - z2->num;
83 }
84
85 static void
86 _e_comp_canvas_resize(Ecore_Evas *ee EINA_UNUSED)
87 {
88    e_comp_screen_e_screens_setup(e_comp->e_comp_screen, e_comp->w, e_comp->h);
89    e_comp_canvas_update();
90 }
91
92 static void
93 _e_comp_canvas_prerender(Ecore_Evas *ee EINA_UNUSED)
94 {
95    E_Comp_Cb cb;
96    Eina_List *l;
97
98    EINA_LIST_FOREACH(e_comp->pre_render_cbs, l, cb)
99      cb();
100 }
101
102 static Eina_Bool
103 _e_comp_cb_compositor_enabled()
104 {
105    // canvas is not updated if there were no window or no obj changes on canvas by evas calc.
106    // it happens sometimes after hwc end, than force canvas render
107    DBG("Compositor Enabled");
108
109    if (e_comp->evas)
110      evas_damage_rectangle_add(e_comp->evas, 0, 0, e_comp->w, e_comp->h);
111
112    return ECORE_CALLBACK_PASS_ON;
113 }
114
115 E_API Eina_Bool
116 e_comp_canvas_init(int w, int h)
117 {
118    Evas_Object *o;
119    Eina_List *screens;
120    unsigned int r, g, b, a;
121    Evas_Render_Op opmode;
122
123    TRACE_DS_BEGIN(COMP_CANVAS:INIT);
124
125    e_comp->evas = ecore_evas_get(e_comp->ee);
126    e_comp->w = w;
127    e_comp->h = h;
128
129    r = g = b = 0;
130    a = 255;
131    opmode = EVAS_RENDER_BLEND;
132
133    if (e_config)
134      {
135         r = e_config->comp_canvas_bg.r;
136         g = e_config->comp_canvas_bg.g;
137         b = e_config->comp_canvas_bg.b;
138         a = e_config->comp_canvas_bg.a;
139         opmode = e_config->comp_canvas_bg.opmode;
140      }
141
142    o = evas_object_rectangle_add(e_comp->evas);
143    e_comp->bg_blank_object = o;
144    evas_object_layer_set(o, E_LAYER_BOTTOM);
145    evas_object_move(o, 0, 0);
146    evas_object_resize(o, e_comp->w, e_comp->h);
147    evas_object_color_set(o, r, g, b, a);
148
149    if (opmode != evas_object_render_op_get(o))
150      evas_object_render_op_set(o, opmode);
151
152    evas_object_name_set(o, "comp->bg_blank_object");
153    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_down, NULL);
154    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_up, NULL);
155    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_in, NULL);
156    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_wheel, NULL);
157    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_canvas_cb_del, NULL);
158    evas_object_show(o);
159
160    ecore_evas_name_class_set(e_comp->ee, "E", "Comp_EE");
161    //ecore_evas_manual_render_set(e_comp->ee, conf->lock_fps);
162    ecore_evas_show(e_comp->ee);
163
164    evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_render_post, NULL);
165
166    e_comp->ee_win = ecore_evas_window_get(e_comp->ee);
167
168    screens = (Eina_List *)e_comp_screen_e_screens_get(e_comp->e_comp_screen);
169    if (screens)
170      {
171         E_Screen *scr;
172         Eina_List *l;
173
174         EINA_LIST_FOREACH(screens, l, scr)
175           {
176              E_Zone *zone = e_zone_new(scr->screen, scr->escreen,
177                                        scr->x, scr->y, scr->w, scr->h);
178              if (scr->id) zone->output_id = strdup(scr->id);
179           }
180      }
181    else
182      e_zone_new(0, 0, 0, 0, e_comp->w, e_comp->h);
183
184    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_comp_cb_zone_change, NULL);
185    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_comp_cb_zone_change, NULL);
186    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_comp_cb_zone_change, NULL);
187    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMPOSITOR_ENABLE,    _e_comp_cb_compositor_enabled, NULL);
188
189    ecore_evas_callback_pre_render_set(e_comp->ee, _e_comp_canvas_prerender);
190    ecore_evas_callback_resize_set(e_comp->ee, _e_comp_canvas_resize);
191
192    TRACE_DS_END();
193    return EINA_TRUE;
194 }
195
196 EINTERN void
197 e_comp_canvas_clear(void)
198 {
199    evas_event_freeze(e_comp->evas);
200    edje_freeze();
201
202    E_FREE_FUNC(e_comp->fps_fg, evas_object_del);
203    E_FREE_FUNC(e_comp->fps_bg, evas_object_del);
204    E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
205    E_FREE_FUNC(e_comp->pointer, e_object_del);
206 }
207
208 //////////////////////////////////////////////
209
210 E_API void
211 e_comp_all_freeze(void)
212 {
213    if (_ev_freeze) return;
214    evas_event_freeze(e_comp->evas);
215    _ev_freeze = EINA_TRUE;
216 }
217
218 E_API void
219 e_comp_all_thaw(void)
220 {
221    if (!_ev_freeze) return;
222    evas_event_thaw(e_comp->evas);
223    _ev_freeze = EINA_FALSE;
224 }
225
226 E_API E_Zone *
227 e_comp_zone_xy_get(Evas_Coord x, Evas_Coord y)
228 {
229    const Eina_List *l;
230    E_Zone *zone;
231
232    EINA_LIST_FOREACH(e_comp->zones, l, zone)
233      if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h)) return zone;
234    return NULL;
235 }
236
237 E_API E_Zone *
238 e_comp_zone_number_get(int num)
239 {
240    Eina_List *l = NULL;
241    E_Zone *zone = NULL;
242
243    EINA_LIST_FOREACH(e_comp->zones, l, zone)
244      {
245         if ((int)zone->num == num) return zone;
246      }
247    return NULL;
248 }
249
250 E_API E_Zone *
251 e_comp_zone_id_get(int id)
252 {
253    Eina_List *l = NULL;
254    E_Zone *zone = NULL;
255
256    EINA_LIST_FOREACH(e_comp->zones, l, zone)
257      {
258         if (zone->id == id) return zone;
259      }
260    return NULL;
261 }
262
263 E_API E_Desk *
264 e_comp_desk_window_profile_get(const char *profile)
265 {
266    Eina_List *l = NULL;
267    E_Zone *zone = NULL;
268    int x, y;
269
270    EINA_SAFETY_ON_NULL_RETURN_VAL(profile, NULL);
271
272    EINA_LIST_FOREACH(e_comp->zones, l, zone)
273      {
274         for (x = 0; x < zone->desk_x_count; x++)
275           {
276              for (y = 0; y < zone->desk_y_count; y++)
277                {
278                   E_Desk *desk = e_desk_at_xy_get(zone, x, y);
279                   if (desk)
280                     {
281                        if (e_object_is_del(E_OBJECT(desk))) continue;
282                        if (!e_util_strcmp(desk->window_profile, profile))
283                          return desk;
284                     }
285                }
286           }
287      }
288
289    return NULL;
290 }
291
292 E_API void
293 e_comp_canvas_zone_update(E_Zone *zone)
294 {
295    Evas_Object *o;
296    const char *const over_styles[] =
297    {
298       "e/comp/screen/overlay/default",
299       "e/comp/screen/overlay/noeffects"
300    };
301    const char *const under_styles[] =
302    {
303       "e/comp/screen/base/default",
304       "e/comp/screen/base/noeffects"
305    };
306    E_Comp_Config *conf = e_comp_config_get();
307
308    if (zone->over && zone->base)
309      {
310         e_theme_edje_object_set(zone->base, "base/theme/comp",
311                                 under_styles[conf->disable_screen_effects]);
312         edje_object_part_swallow(zone->base, "e.swallow.background",
313                                  zone->transition_object ?: zone->bg_object);
314         e_theme_edje_object_set(zone->over, "base/theme/comp",
315                                 over_styles[conf->disable_screen_effects]);
316         return;
317      }
318    E_FREE_FUNC(zone->base, evas_object_del);
319    E_FREE_FUNC(zone->over, evas_object_del);
320    zone->base = o = edje_object_add(e_comp->evas);
321    evas_object_repeat_events_set(o, 1);
322    evas_object_name_set(zone->base, "zone->base");
323    e_theme_edje_object_set(o, "base/theme/comp", under_styles[conf->disable_screen_effects]);
324    edje_object_part_swallow(zone->base, "e.swallow.background", zone->transition_object ?: zone->bg_object);
325    evas_object_move(o, zone->x, zone->y);
326    evas_object_resize(o, zone->w, zone->h);
327    evas_object_layer_set(o, E_LAYER_BG);
328    evas_object_show(o);
329
330    zone->over = o = edje_object_add(e_comp->evas);
331    //edje_object_signal_callback_add(o, "e,state,screensaver,active", "e", _e_comp_canvas_screensaver_active, NULL);
332    evas_object_layer_set(o, E_LAYER_MAX);
333    evas_object_raise(o);
334    evas_object_name_set(zone->over, "zone->over");
335    evas_object_pass_events_set(o, 1);
336    e_theme_edje_object_set(o, "base/theme/comp", over_styles[conf->disable_screen_effects]);
337    evas_object_move(o, zone->x, zone->y);
338    evas_object_resize(o, zone->w, zone->h);
339    evas_object_raise(o);
340    evas_object_show(o);
341 }
342
343 E_API void
344 e_comp_canvas_update(void)
345 {
346    Eina_List *l, *screens, *zones = NULL, *ll;
347    E_Zone *zone;
348    E_Screen *scr;
349    int i;
350    Eina_Bool changed = EINA_FALSE;
351
352    screens = (Eina_List *)e_comp_screen_e_screens_get(e_comp->e_comp_screen);
353
354    if (screens)
355      {
356         zones = e_comp->zones;
357         e_comp->zones = NULL;
358         printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
359         EINA_LIST_FOREACH(screens, l, scr)
360           {
361              zone = NULL;
362
363              printf("@ match screens %p[%i] = %i %i %ix%i -- %i\n", 
364                     scr, scr->escreen, scr->x, scr->y, scr->w, scr->h, scr->escreen);
365              EINA_LIST_FOREACH(zones, ll, zone)
366                {
367                   if (zone->id == scr->escreen) break;
368                   zone = NULL;
369                }
370              printf("@ matches existing zone %p\n", zone);
371              if (zone)
372                {
373                   printf("   move resize %i %i %ix%i -> %i %i %ix%i\n",
374                          zone->x, zone->y, zone->w, zone->h,
375                          scr->x, scr->y, scr->w, scr->h);
376                   changed |= e_zone_move_resize(zone, scr->x, scr->y, scr->w, scr->h);
377                   if (changed)
378                     printf("@@@ FOUND ZONE %i %i [%p]\n", zone->num, zone->id, zone);
379                   zones = eina_list_remove(zones, zone);
380                   e_comp->zones = eina_list_append(e_comp->zones, zone);
381                   zone->num = scr->screen;
382                   free(zone->output_id);
383                   zone->output_id = NULL;
384                   if (scr->id) zone->output_id = strdup(scr->id);
385                }
386              else
387                {
388                   zone = e_zone_new(scr->screen, scr->escreen,
389                                     scr->x, scr->y, scr->w, scr->h);
390                   if (scr->id) zone->output_id = strdup(scr->id);
391
392                   printf("@@@ NEW ZONE = %p\n", zone);
393                   changed = EINA_TRUE;
394                }
395              if (changed)
396                printf("@@@ SCREENS: %i %i | %i %i %ix%i\n",
397                       scr->screen, scr->escreen, scr->x, scr->y, scr->w, scr->h);
398           }
399         e_comp->zones = eina_list_sort(e_comp->zones, 0, _e_comp_canvas_cb_zone_sort);
400         if (zones)
401           {
402              E_Zone *spare_zone;
403
404              printf("@zones have been deleted....\n");
405              changed = EINA_TRUE;
406              spare_zone = eina_list_data_get(e_comp->zones);
407
408              EINA_LIST_FREE(zones, zone)
409                {
410                   E_Client *ec;
411
412                   printf("reassign all clients from deleted zone %p\n", zone);
413                   E_CLIENT_FOREACH(ec)
414                     {
415                        if (ec->zone == zone)
416                          {
417                             if (spare_zone)
418                               e_client_zone_set(ec, spare_zone);
419                             else
420                               printf("EEEK! should not be here - but no\n"
421                                      "spare zones exist to move this\n"
422                                      "window to!!! help!\n");
423                          }
424                     }
425                   e_object_del(E_OBJECT(zone));
426                }
427           }
428      }
429    else
430      {
431         E_Zone *z;
432
433         z = e_comp_zone_number_get(0);
434         if (z)
435           {
436              changed |= e_zone_move_resize(z, 0, 0, e_comp->w, e_comp->h);
437           }
438      }
439
440    if (!changed) return;
441    if (!starting)
442      {
443         e_object_ref(E_OBJECT(e_comp));
444         ecore_event_add(E_EVENT_COMPOSITOR_RESIZE, NULL, _e_comp_canvas_event_compositor_resize_free, NULL);
445      }
446
447    EINA_LIST_FOREACH(e_comp->zones, l, zone)
448      {
449         E_FREE_FUNC(zone->base, evas_object_del);
450         E_FREE_FUNC(zone->over, evas_object_del);
451         e_comp_canvas_zone_update(zone);
452      }
453
454    for (i = 0; i < 11; i++)
455      {
456         Eina_List *tmp = NULL;
457         E_Client *ec;
458
459         if (!e_comp->layers[i].clients) continue;
460         /* Make temporary list as e_client_res_change_geometry_restore
461          * rearranges the order. */
462         EINA_INLIST_FOREACH(e_comp->layers[i].clients, ec)
463           {
464              if (!e_client_util_ignored_get(ec))
465                tmp = eina_list_append(tmp, ec);
466           }
467
468         EINA_LIST_FREE(tmp, ec)
469           {
470              e_client_res_change_geometry_save(ec);
471              e_client_res_change_geometry_restore(ec);
472           }
473      }
474 }
475
476 E_API void
477 e_comp_canvas_fake_layers_init(void)
478 {
479    unsigned int layer;
480
481    /* init layers */
482    for (layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); layer++)
483      {
484         Evas_Object *o2;
485
486         o2 = e_comp->layers[layer].obj = evas_object_rectangle_add(e_comp->evas);
487         evas_object_layer_set(o2, e_comp_canvas_layer_map_to(layer));
488         evas_object_name_set(o2, "layer_obj");
489      }
490 }
491
492 E_API void
493 e_comp_canvas_fps_toggle(void)
494 {
495    E_Comp_Config *conf = e_comp_config_get();
496
497    conf->fps_show = !conf->fps_show;
498    e_comp_internal_save();
499    e_comp_render_queue();
500 }
501
502 E_API E_Layer
503 e_comp_canvas_layer_map_to(unsigned int layer)
504 {
505    switch (layer)
506      {
507       case 0: return E_LAYER_BOTTOM;
508       case 1: return E_LAYER_BG;
509       case 2: return E_LAYER_DESKTOP;
510       case 3: return E_LAYER_DESKTOP_TOP;
511       case 4: return E_LAYER_CLIENT_DESKTOP;
512       case 5: return E_LAYER_CLIENT_BELOW;
513       case 6: return E_LAYER_CLIENT_NORMAL;
514       case 7: return E_LAYER_CLIENT_ABOVE;
515       case 8: return E_LAYER_CLIENT_EDGE;
516       case 9: return E_LAYER_CLIENT_FULLSCREEN;
517       case 10: return E_LAYER_CLIENT_EDGE_FULLSCREEN;
518       case 11: return E_LAYER_CLIENT_POPUP;
519       case 12: return E_LAYER_CLIENT_TOP;
520       case 13: return E_LAYER_CLIENT_DRAG;
521       case 14: return E_LAYER_CLIENT_PRIO;
522       case 15: return E_LAYER_CLIENT_NOTIFICATION_LOW;
523       case 16: return E_LAYER_CLIENT_NOTIFICATION_NORMAL;
524       case 17: return E_LAYER_CLIENT_NOTIFICATION_HIGH;
525       case 18: return E_LAYER_CLIENT_NOTIFICATION_TOP;
526       case 19: return E_LAYER_CLIENT_ALERT_LOW;
527       case 20: return E_LAYER_CLIENT_ALERT;
528       case 21: return E_LAYER_CLIENT_ALERT_HIGH;
529       case 22: return E_LAYER_CLIENT_CURSOR;
530       case 23: return E_LAYER_POPUP;
531       case 24: return E_LAYER_EFFECT;
532       case 25: return E_LAYER_DESK_OBJECT_BELOW;
533       case 26: return E_LAYER_DESK_OBJECT;
534       case 27: return E_LAYER_DESK_OBJECT_ABOVE;
535       case 28: return E_LAYER_MENU;
536       case 29: return E_LAYER_DESKLOCK;
537       case 30: return E_LAYER_MAX;
538       default: break;
539      }
540    return -INT_MAX;
541 }
542
543 E_API unsigned int
544 e_comp_canvas_layer_map(E_Layer layer)
545 {
546    switch (layer)
547      {
548       case E_LAYER_BOTTOM: return 0;
549       case E_LAYER_BG: return 1;
550       case E_LAYER_DESKTOP: return 2;
551       case E_LAYER_DESKTOP_TOP: return 3;
552       case E_LAYER_CLIENT_DESKTOP: return 4;
553       case E_LAYER_CLIENT_BELOW: return 5;
554       case E_LAYER_CLIENT_NORMAL: return 6;
555       case E_LAYER_CLIENT_ABOVE: return 7;
556       case E_LAYER_CLIENT_EDGE: return 8;
557       case E_LAYER_CLIENT_FULLSCREEN: return 9;
558       case E_LAYER_CLIENT_EDGE_FULLSCREEN: return 10;
559       case E_LAYER_CLIENT_POPUP: return 11;
560       case E_LAYER_CLIENT_TOP: return 12;
561       case E_LAYER_CLIENT_DRAG: return 13;
562       case E_LAYER_CLIENT_PRIO: return 14;
563       case E_LAYER_CLIENT_NOTIFICATION_LOW: return 15;
564       case E_LAYER_CLIENT_NOTIFICATION_NORMAL: return 16;
565       case E_LAYER_CLIENT_NOTIFICATION_HIGH: return 17;
566       case E_LAYER_CLIENT_NOTIFICATION_TOP: return 18;
567       case E_LAYER_CLIENT_ALERT_LOW: return 19;
568       case E_LAYER_CLIENT_ALERT: return 20;
569       case E_LAYER_CLIENT_ALERT_HIGH: return 21;
570       case E_LAYER_CLIENT_CURSOR: return 22;
571       case E_LAYER_POPUP: return 23;
572       case E_LAYER_EFFECT: return 24;
573       case E_LAYER_DESK_OBJECT_BELOW: return 25;
574       case E_LAYER_DESK_OBJECT: return 26;
575       case E_LAYER_DESK_OBJECT_ABOVE: return 27;
576       case E_LAYER_MENU: return 28;
577       case E_LAYER_DESKLOCK: return 29;
578       case E_LAYER_MAX: return 30;
579       default: break;
580      }
581
582    /* prevents to access the e_comp->layers list out of bounds. */
583    ELOGF("WARNING", "Used not defined layer:%d", NULL, NULL, layer);
584    return E_LAYER_COUNT - 1;
585 }
586
587 E_API unsigned int
588 e_comp_canvas_client_layer_map(E_Layer layer)
589 {
590    switch (layer)
591      {
592       case E_LAYER_CLIENT_DESKTOP: return 0;
593       case E_LAYER_CLIENT_BELOW: return 1;
594       case E_LAYER_CLIENT_NORMAL: return 2;
595       case E_LAYER_CLIENT_ABOVE: return 3;
596       case E_LAYER_CLIENT_EDGE: return 4;
597       case E_LAYER_CLIENT_FULLSCREEN: return 5;
598       case E_LAYER_CLIENT_EDGE_FULLSCREEN: return 6;
599       case E_LAYER_CLIENT_POPUP: return 7;
600       case E_LAYER_CLIENT_TOP: return 8;
601       case E_LAYER_CLIENT_DRAG: return 9;
602       case E_LAYER_CLIENT_PRIO: return 10;
603       case E_LAYER_CLIENT_NOTIFICATION_LOW: return 11;
604       case E_LAYER_CLIENT_NOTIFICATION_NORMAL: return 12;
605       case E_LAYER_CLIENT_NOTIFICATION_HIGH: return 13;
606       case E_LAYER_CLIENT_NOTIFICATION_TOP: return 14;
607       case E_LAYER_CLIENT_ALERT_LOW: return 15;
608       case E_LAYER_CLIENT_ALERT: return 16;
609       case E_LAYER_CLIENT_ALERT_HIGH: return 17;
610       case E_LAYER_CLIENT_CURSOR: return 18;
611       default: break;
612      }
613    return 9999;
614 }
615
616 E_API E_Layer
617 e_comp_canvas_client_layer_map_nearest(int layer)
618 {
619 #define LAYER_MAP(X) \
620    if (layer <= X) return X
621
622    LAYER_MAP(E_LAYER_CLIENT_DESKTOP);
623    LAYER_MAP(E_LAYER_CLIENT_BELOW);
624    LAYER_MAP(E_LAYER_CLIENT_NORMAL);
625    LAYER_MAP(E_LAYER_CLIENT_ABOVE);
626    LAYER_MAP(E_LAYER_CLIENT_EDGE);
627    LAYER_MAP(E_LAYER_CLIENT_FULLSCREEN);
628    LAYER_MAP(E_LAYER_CLIENT_EDGE_FULLSCREEN);
629    LAYER_MAP(E_LAYER_CLIENT_POPUP);
630    LAYER_MAP(E_LAYER_CLIENT_TOP);
631    LAYER_MAP(E_LAYER_CLIENT_DRAG);
632    LAYER_MAP(E_LAYER_CLIENT_PRIO);
633    LAYER_MAP(E_LAYER_CLIENT_NOTIFICATION_LOW);
634    LAYER_MAP(E_LAYER_CLIENT_NOTIFICATION_NORMAL);
635    LAYER_MAP(E_LAYER_CLIENT_NOTIFICATION_HIGH);
636    LAYER_MAP(E_LAYER_CLIENT_NOTIFICATION_TOP);
637    LAYER_MAP(E_LAYER_CLIENT_ALERT_LOW);
638    LAYER_MAP(E_LAYER_CLIENT_ALERT);
639    LAYER_MAP(E_LAYER_CLIENT_ALERT_HIGH);
640    return E_LAYER_CLIENT_CURSOR;
641 }
642
643 E_API void
644 e_comp_post_update_add(E_Client *ec)
645 {
646    E_Client *ec2;
647
648    if (!e_comp) return;
649
650    ec2 = eina_list_data_find(e_comp->post_updates, ec);
651    if (ec2) return;
652
653    e_comp->post_updates = eina_list_append(e_comp->post_updates, ec);
654    e_object_ref(E_OBJECT(ec));
655 }
656
657 E_API void
658 e_comp_post_update_purge(E_Client *ec)
659 {
660    Eina_List *l, *ll;
661    E_Client *ec2;
662
663    if (!e_comp) return;
664
665    EINA_LIST_FOREACH_SAFE(e_comp->post_updates, l, ll, ec2)
666      {
667         if (ec2 == ec)
668           {
669              e_comp->post_updates = eina_list_remove_list(e_comp->post_updates, l);
670              e_object_unref(E_OBJECT(ec));
671           }
672      }
673 }
674
675 E_API void
676 e_comp_canvas_keys_grab(void)
677 {
678    ;
679 }
680
681 E_API void
682 e_comp_canvas_keys_ungrab(void)
683 {
684    ;
685 }
686
687 E_API void
688 e_comp_canvas_feed_mouse_up(unsigned int activate_time)
689 {
690    int button_mask, i;
691
692    button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
693    for (i = 0; i < 32; i++)
694      {
695        if ((button_mask & (1 << i)))
696          evas_event_feed_mouse_up(e_comp->evas, i + 1, EVAS_BUTTON_NONE, activate_time, NULL);
697      }
698 }
699
700 E_API void
701 e_comp_canvas_norender_push(void)
702 {
703    e_comp->norender++;
704
705    // e_plane_render is not working when e_comp->hwc is not initialized
706    if ((!e_comp->hwc) &&
707        (e_comp->norender == 1))
708      ecore_evas_manual_render_set(e_comp->ee, EINA_TRUE);
709 }
710
711 E_API void
712 e_comp_canvas_norender_pop(void)
713 {
714    if (e_comp->norender <= 0)
715      return;
716
717    e_comp->norender--;
718
719    // e_plane_render is not working when e_comp->hwc is not initialized
720    if ((!e_comp->hwc) &&
721        (e_comp->norender == 0))
722      ecore_evas_manual_render_set(e_comp->ee, EINA_FALSE);
723 }
724
725 E_API int
726 e_comp_canvas_norender_get(void)
727 {
728    return e_comp->norender;
729 }