3 static Eina_List *handlers;
4 static Eina_Bool _ev_freeze = EINA_FALSE;
7 _e_comp_canvas_cb_del()
9 E_FREE_LIST(handlers, ecore_event_handler_del);
13 _e_comp_canvas_event_compositor_resize_free(void *data EINA_UNUSED, void *event EINA_UNUSED)
15 e_object_unref(E_OBJECT(e_comp));
18 ///////////////////////////////////
21 _e_comp_canvas_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
24 EINA_LIST_FREE(e_comp->post_updates, ec)
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));
33 ///////////////////////////////////
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)
40 if (e_client_action_get()) return;
41 ec = e_client_focused_get();
42 if (ec) e_focus_event_mouse_out(ec);
46 _e_comp_canvas_cb_mouse_down(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
53 _e_comp_canvas_cb_mouse_up(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
60 _e_comp_canvas_cb_mouse_wheel(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
66 ////////////////////////////////////
69 _e_comp_cb_zone_change()
71 e_comp_canvas_update();
72 return ECORE_CALLBACK_PASS_ON;
75 ////////////////////////////////////
78 _e_comp_canvas_cb_zone_sort(const void *data1, const void *data2)
80 const E_Zone *z1 = data1, *z2 = data2;
82 return z1->num - z2->num;
86 _e_comp_canvas_resize(Ecore_Evas *ee EINA_UNUSED)
88 e_comp_screen_e_screens_setup(e_comp->e_comp_screen, e_comp->w, e_comp->h);
89 e_comp_canvas_update();
93 _e_comp_canvas_prerender(Ecore_Evas *ee EINA_UNUSED)
98 EINA_LIST_FOREACH(e_comp->pre_render_cbs, l, cb)
103 _e_comp_cb_compositor_enabled()
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");
110 evas_damage_rectangle_add(e_comp->evas, 0, 0, e_comp->w, e_comp->h);
112 return ECORE_CALLBACK_PASS_ON;
116 e_comp_canvas_init(int w, int h)
120 unsigned int r, g, b, a;
121 Evas_Render_Op opmode;
123 TRACE_DS_BEGIN(COMP_CANVAS:INIT);
125 e_comp->evas = ecore_evas_get(e_comp->ee);
131 opmode = EVAS_RENDER_BLEND;
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;
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);
149 if (opmode != evas_object_render_op_get(o))
150 evas_object_render_op_set(o, opmode);
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);
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);
164 evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_render_post, NULL);
166 e_comp->ee_win = ecore_evas_window_get(e_comp->ee);
168 screens = (Eina_List *)e_comp_screen_e_screens_get(e_comp->e_comp_screen);
174 EINA_LIST_FOREACH(screens, l, scr)
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);
182 e_zone_new(0, 0, 0, 0, e_comp->w, e_comp->h);
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);
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);
197 e_comp_canvas_clear(void)
199 evas_event_freeze(e_comp->evas);
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);
208 //////////////////////////////////////////////
211 e_comp_all_freeze(void)
213 if (_ev_freeze) return;
214 evas_event_freeze(e_comp->evas);
215 _ev_freeze = EINA_TRUE;
219 e_comp_all_thaw(void)
221 if (!_ev_freeze) return;
222 evas_event_thaw(e_comp->evas);
223 _ev_freeze = EINA_FALSE;
227 e_comp_zone_xy_get(Evas_Coord x, Evas_Coord y)
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;
238 e_comp_zone_number_get(int num)
243 EINA_LIST_FOREACH(e_comp->zones, l, zone)
245 if ((int)zone->num == num) return zone;
251 e_comp_zone_id_get(int id)
256 EINA_LIST_FOREACH(e_comp->zones, l, zone)
258 if (zone->id == id) return zone;
264 e_comp_desk_window_profile_get(const char *profile)
270 EINA_SAFETY_ON_NULL_RETURN_VAL(profile, NULL);
272 EINA_LIST_FOREACH(e_comp->zones, l, zone)
274 for (x = 0; x < zone->desk_x_count; x++)
276 for (y = 0; y < zone->desk_y_count; y++)
278 E_Desk *desk = e_desk_at_xy_get(zone, x, y);
281 if (e_object_is_del(E_OBJECT(desk))) continue;
282 if (!e_util_strcmp(desk->window_profile, profile))
293 e_comp_canvas_zone_update(E_Zone *zone)
296 const char *const over_styles[] =
298 "e/comp/screen/overlay/default",
299 "e/comp/screen/overlay/noeffects"
301 const char *const under_styles[] =
303 "e/comp/screen/base/default",
304 "e/comp/screen/base/noeffects"
306 E_Comp_Config *conf = e_comp_config_get();
308 if (zone->over && zone->base)
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]);
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);
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);
344 e_comp_canvas_update(void)
346 Eina_List *l, *screens, *zones = NULL, *ll;
350 Eina_Bool changed = EINA_FALSE;
352 screens = (Eina_List *)e_comp_screen_e_screens_get(e_comp->e_comp_screen);
356 zones = e_comp->zones;
357 e_comp->zones = NULL;
358 printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
359 EINA_LIST_FOREACH(screens, l, scr)
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)
367 if (zone->id == scr->escreen) break;
370 printf("@ matches existing zone %p\n", zone);
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);
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);
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);
392 printf("@@@ NEW ZONE = %p\n", zone);
396 printf("@@@ SCREENS: %i %i | %i %i %ix%i\n",
397 scr->screen, scr->escreen, scr->x, scr->y, scr->w, scr->h);
399 e_comp->zones = eina_list_sort(e_comp->zones, 0, _e_comp_canvas_cb_zone_sort);
404 printf("@zones have been deleted....\n");
406 spare_zone = eina_list_data_get(e_comp->zones);
408 EINA_LIST_FREE(zones, zone)
412 printf("reassign all clients from deleted zone %p\n", zone);
415 if (ec->zone == zone)
418 e_client_zone_set(ec, spare_zone);
420 printf("EEEK! should not be here - but no\n"
421 "spare zones exist to move this\n"
422 "window to!!! help!\n");
425 e_object_del(E_OBJECT(zone));
433 z = e_comp_zone_number_get(0);
436 changed |= e_zone_move_resize(z, 0, 0, e_comp->w, e_comp->h);
440 if (!changed) return;
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);
447 EINA_LIST_FOREACH(e_comp->zones, l, zone)
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);
454 for (i = 0; i < 11; i++)
456 Eina_List *tmp = NULL;
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)
464 if (!e_client_util_ignored_get(ec))
465 tmp = eina_list_append(tmp, ec);
468 EINA_LIST_FREE(tmp, ec)
470 e_client_res_change_geometry_save(ec);
471 e_client_res_change_geometry_restore(ec);
477 e_comp_canvas_fake_layers_init(void)
482 for (layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); layer++)
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");
493 e_comp_canvas_fps_toggle(void)
495 E_Comp_Config *conf = e_comp_config_get();
497 conf->fps_show = !conf->fps_show;
498 e_comp_internal_save();
499 e_comp_render_queue();
503 e_comp_canvas_layer_map_to(unsigned int layer)
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;
544 e_comp_canvas_layer_map(E_Layer layer)
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;
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;
588 e_comp_canvas_client_layer_map(E_Layer layer)
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;
617 e_comp_canvas_client_layer_map_nearest(int layer)
619 #define LAYER_MAP(X) \
620 if (layer <= X) return X
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;
644 e_comp_post_update_add(E_Client *ec)
650 ec2 = eina_list_data_find(e_comp->post_updates, ec);
653 e_comp->post_updates = eina_list_append(e_comp->post_updates, ec);
654 e_object_ref(E_OBJECT(ec));
658 e_comp_post_update_purge(E_Client *ec)
665 EINA_LIST_FOREACH_SAFE(e_comp->post_updates, l, ll, ec2)
669 e_comp->post_updates = eina_list_remove_list(e_comp->post_updates, l);
670 e_object_unref(E_OBJECT(ec));
676 e_comp_canvas_keys_grab(void)
682 e_comp_canvas_keys_ungrab(void)
688 e_comp_canvas_feed_mouse_up(unsigned int activate_time)
692 button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
693 for (i = 0; i < 32; i++)
695 if ((button_mask & (1 << i)))
696 evas_event_feed_mouse_up(e_comp->evas, i + 1, EVAS_BUTTON_NONE, activate_time, NULL);
701 e_comp_canvas_norender_push(void)
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);
712 e_comp_canvas_norender_pop(void)
714 if (e_comp->norender <= 0)
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);
726 e_comp_canvas_norender_get(void)
728 return e_comp->norender;