1 #include "e_comp_object_intern.h"
2 #include "e_bindings_intern.h"
3 #include "e_utils_intern.h"
4 #include "e_comp_canvas_intern.h"
5 #include "e_comp_cfdata_intern.h"
6 #include "e_comp_wl_subsurface_intern.h"
7 #include "e_comp_wl_tbm_intern.h"
8 #include "e_comp_intern.h"
9 #include "e_pixmap_intern.h"
10 #include "e_map_intern.h"
11 #include "e_hwc_window_intern.h"
12 #include "e_hwc_windows_intern.h"
13 #include "e_policy_visibility_intern.h"
14 #include "e_client_video_intern.h"
15 #include "e_client_intern.h"
16 #include "e_zone_intern.h"
17 #include "e_theme_intern.h"
18 #include "e_config_intern.h"
22 = keys that return objects =
23 - E_Client: the client associated with the object (E_Client*)
24 - comp_smart_obj: cw->smart_obj (Evas_Object*)
25 - comp_obj: cw (E_Comp_Object*)
27 = keys that are bool flags =
28 - client_restack: client needs a protocol-level restack
29 - comp_override: object is triggering a nocomp override to force compositing
30 - comp_ref: object has a ref from visibility animations
31 - comp_showing: object is currently running its show animation
32 - comp_hiding: object is currently running its hiding animation
33 - comp_object: object is a compositor-created object
34 - comp_object_skip: object has a name which prohibits theme shadows
35 - comp_object-to_del: list of objects which will be deleted when this object is deleted
36 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
37 - effect_running: object is animating by external module
40 #define UPDATE_MAX 512 // same as evas
41 #define FAILURE_MAX 2 // seems reasonable
42 #define SMART_NAME "e_comp_object"
43 #define INPUT_OBJ_SMART_NAME "input_object"
45 /* for non-util functions */
46 #define API_ENTRY E_Comp_Object *cw; \
47 cw = evas_object_smart_data_get(obj); \
48 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
50 /* for util functions (obj may or may not be E_Comp_Object */
51 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
54 CRI("YOU PASSED NULL! ARGH!"); \
57 cw = evas_object_smart_data_get(obj); \
58 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
60 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
62 /* enable for lots of client size info in console output */
64 # define e_util_size_debug_set(x, y)
67 /* enable along with display-specific damage INF calls to enable render tracing
71 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
73 #define RENDER_DEBUG(...)
76 typedef struct _E_Input_Rect_Data
82 typedef struct _E_Input_Rect_Smart_Data
84 Eina_List *input_rect_data_list;
86 } E_Input_Rect_Smart_Data;
88 struct E_Comp_Object_Mover
91 E_Comp_Object_Mover_Cb func;
97 static Eina_Inlist *_e_comp_object_movers = NULL;
98 static Evas_Smart *_e_comp_smart = NULL;
99 static Evas_Smart *_e_comp_input_obj_smart = NULL;
101 static int _e_comp_object_hooks_delete = 0;
102 static int _e_comp_object_hooks_walking = 0;
104 static Eina_Inlist *_e_comp_object_hooks[] =
106 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
107 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
108 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
109 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
110 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
111 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
112 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
113 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
114 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET] = NULL,
117 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
118 static int _e_comp_object_intercept_hooks_delete = 0;
119 static int _e_comp_object_intercept_hooks_walking = 0;
121 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
123 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
124 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
128 static Eina_Bool _damage_trace = EINA_FALSE;
129 static Eina_List *_damage_trace_objs = NULL;
130 static Eina_List *_damage_trace_post_objs = NULL;
132 /* sekrit functionzzz */
133 EINTERN void e_client_focused_set(E_Client *ec);
135 /* emitted every time a new noteworthy comp object is added */
136 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
138 /* ecore event define */
139 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
140 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
141 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
143 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
144 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
145 static void _e_comp_object_dim_update(E_Comp_Object *cw);
146 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
147 #ifdef REFACTOR_DESK_AREA
149 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
150 static void _e_comp_object_raise(Evas_Object *obj);
151 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
152 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
153 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
154 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
157 static E_Client *dim_client = NULL;
160 _e_comp_object_hooks_clean(void)
163 E_Comp_Object_Hook *ch;
166 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
167 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
169 if (!ch->delete_me) continue;
170 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
176 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
178 E_Comp_Object_Hook *ch;
179 Eina_Bool ret = EINA_TRUE;
181 if (e_object_is_del(E_OBJECT(ec)))
183 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
184 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
185 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
186 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET)
197 e_object_ref(E_OBJECT(ec));
198 _e_comp_object_hooks_walking++;
199 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
201 if (ch->delete_me) continue;
202 if (!(ch->func(ch->data, ec)))
208 _e_comp_object_hooks_walking--;
209 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
210 _e_comp_object_hooks_clean();
212 e_object_unref(E_OBJECT(ec));
217 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
219 _e_comp_object_intercept_hooks_clean(void)
222 E_Comp_Object_Intercept_Hook *ch;
225 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
226 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
228 if (!ch->delete_me) continue;
229 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
235 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
237 E_Comp_Object_Intercept_Hook *ch;
238 Eina_Bool ret = EINA_TRUE;
240 if (e_object_is_del(E_OBJECT(ec))) return ret;
241 e_object_ref(E_OBJECT(ec));
242 _e_comp_object_intercept_hooks_walking++;
243 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
245 if (ch->delete_me) continue;
246 if (!(ch->func(ch->data, ec)))
252 _e_comp_object_intercept_hooks_walking--;
253 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
254 _e_comp_object_intercept_hooks_clean();
256 e_object_unref(E_OBJECT(ec));
263 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
265 E_Event_Comp_Object *ev = event;
268 ec = evas_object_data_get(ev->comp_object, "E_Client");
272 e_object_unref(E_OBJECT(ec));
274 evas_object_unref(ev->comp_object);
279 _e_comp_object_event_add(Evas_Object *obj)
281 E_Event_Comp_Object *ev;
284 if (stopping) return;
285 ev = E_NEW(E_Event_Comp_Object, 1);
286 EINA_SAFETY_ON_NULL_RETURN(ev);
288 evas_object_ref(obj);
289 ev->comp_object = obj;
290 ec = evas_object_data_get(ev->comp_object, "E_Client");
294 e_object_ref(E_OBJECT(ec));
296 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
300 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
302 E_Event_Comp_Object *ev = event;
305 ec = evas_object_data_get(ev->comp_object, "E_Client");
309 e_object_unref(E_OBJECT(ec));
311 evas_object_unref(ev->comp_object);
316 _e_comp_object_event_simple(Evas_Object *obj, int type)
318 E_Event_Comp_Object *ev;
321 ev = E_NEW(E_Event_Comp_Object, 1);
324 evas_object_ref(obj);
325 ev->comp_object = obj;
326 ec = evas_object_data_get(ev->comp_object, "E_Client");
330 e_object_ref(E_OBJECT(ec));
332 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
334 /////////////////////////////////////
337 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
339 E_Comp_Object *cw = data;
341 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
345 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
347 E_Comp_Object *cw = data;
349 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
350 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
353 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
354 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
358 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
360 E_Comp_Object *cw = data;
363 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
364 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
367 /////////////////////////////////////
369 #ifdef REFACTOR_DESK_AREA
371 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
374 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
379 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
380 if (cw->ec->input_only) return;
382 layer = evas_object_layer_get(obj);
384 if (cw->transform_bg_obj)
386 if (layer != evas_object_layer_get(cw->transform_bg_obj))
388 evas_object_layer_set(cw->transform_bg_obj, layer);
391 evas_object_stack_below(cw->transform_bg_obj, obj);
394 if (cw->transform_tranp_obj)
396 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
398 evas_object_layer_set(cw->transform_tranp_obj, layer);
401 evas_object_stack_below(cw->transform_tranp_obj, obj);
406 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
413 if (!map) return NULL;
415 e_map_util_points_populate_from_object_full(map, obj, 0);
416 e_map_util_points_color_set(map, 255, 255, 255, 255);
418 for (i = 0 ; i < 4 ; ++i)
423 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
424 e_map_point_coord_set(map, i, x, y, 1.0);
431 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
437 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
440 e_comp_object_map_set(obj, map);
441 e_comp_object_map_enable_set(obj, EINA_TRUE);
448 evas_object_map_enable_set(obj, EINA_FALSE);
453 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
459 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
462 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
464 e_comp_object_map_set(obj, map);
465 e_comp_object_map_enable_set(obj, EINA_TRUE);
472 evas_object_map_enable_set(obj, EINA_FALSE);
475 /////////////////////////////////////
477 static inline Eina_Bool
478 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
480 if (num > 1) return EINA_TRUE;
481 if ((rects[0].x == 0) && (rects[0].y == 0) &&
482 ((int)rects[0].w == w) && ((int)rects[0].h == h))
487 /////////////////////////////////////
489 /* add a client to the layer-client list */
490 #ifdef REFACTOR_DESK_AREA
493 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
495 g_rec_mutex_lock(&e_comp->ec_list_mutex);
498 e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
500 e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
501 if ((!above) && (!below))
504 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
505 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
506 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508 e_comp->layers[cw->layer].clients_count++;
510 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
514 _e_comp_object_layers_remove(E_Comp_Object *cw)
516 g_rec_mutex_lock(&e_comp->ec_list_mutex);
518 if (cw->ec && e_comp->layers[cw->layer].clients)
520 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
521 e_comp->layers[cw->layer].clients_count--;
524 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
528 /////////////////////////////////////
530 _e_comp_object_alpha_set(E_Comp_Object *cw)
532 Eina_Bool alpha = cw->ec->argb;
534 if ((cw->external_content) &&
535 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
540 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
541 if (cw->user_alpha_set) alpha = cw->user_alpha;
543 evas_object_image_alpha_set(cw->obj, alpha);
547 _e_comp_object_shadow(E_Comp_Object *cw)
549 if (e_client_util_shadow_state_get(cw->ec))
550 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
552 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
553 if (cw->frame_object)
554 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
555 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
558 /* convert from the surface coordinates to the buffer coordinates */
560 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
562 E_Comp_Wl_Buffer_Viewport *vp;
563 E_Comp_Wl_Client_Data *cdata;
567 cdata = e_client_cdata_get(ec);
569 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
576 vp = &cdata->scaler.buffer_viewport;
577 transform = e_comp_wl_output_buffer_transform_get(ec);
579 e_pixmap_size_get(ec->pixmap, &bw, &bh);
581 /* for subsurface, it should be swap 90 and 270 */
582 if (e_comp_wl_subsurface_check(ec))
585 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
586 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
587 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
588 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
594 case WL_OUTPUT_TRANSFORM_NORMAL:
595 default: tx = sx, ty = sy; break;
596 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
597 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
598 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
599 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
600 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
601 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
605 tx *= vp->buffer.scale;
606 ty *= vp->buffer.scale;
613 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
621 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
622 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
629 if (dw) *dw = MAX(x1, x2) - mx;
630 if (dh) *dh = MAX(y1, y2) - my;
634 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
635 int *dx, int *dy, int *dw, int *dh)
637 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
638 E_Util_Transform_Rect_Vertex sv, dv;
642 e_pixmap_size_get(ec->pixmap, &bw, &bh);
644 sv = e_util_transform_rect_to_vertices(&rect);
646 for (i = 0; i < 4; i++)
648 double x = 0.0, y = 0.0;
650 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
652 /* if evas decide coordinate is outside of map, it returns (0, 0)
653 in this case, full damage is added.
655 if ((i != 0) && (x == 0.0) && (y == 0.0))
658 dv.vertices[i].vertex[0] = x;
659 dv.vertices[i].vertex[1] = y;
660 dv.vertices[i].vertex[2] = 1.0;
661 dv.vertices[i].vertex[3] = 1.0;
664 rect = e_util_transform_vertices_to_rect(&dv);
666 if (dx) *dx = rect.x;
667 if (dy) *dy = rect.y;
668 if (dw) *dw = rect.w;
669 if (dh) *dh = rect.h;
683 _e_comp_object_map_damage_transform_get(E_Client *ec)
690 if (!e_client_transform_core_enable_get(ec))
693 m = e_client_map_get(ec);
697 e_pixmap_size_get(ec->pixmap, &bw, &bh);
698 if ((bw == 0) || (bh == 0))
711 e_map_point_coord_set(m2, 0, 0, 0, 0);
712 e_map_point_coord_set(m2, 1, bw, 0, 0);
713 e_map_point_coord_set(m2, 2, bw, bh, 0);
714 e_map_point_coord_set(m2, 3, 0, bh, 0);
716 for (i = 0; i < 4; i++)
720 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
721 e_map_point_image_uv_set(m2, i, map_x, map_y);
728 /////////////////////////////////////
730 /* handle evas mouse-in events on client object */
732 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
734 Evas_Event_Mouse_In *ev = event_info;
735 E_Comp_Object *cw = data;
737 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
740 /* handle evas mouse-out events on client object */
742 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
744 Evas_Event_Mouse_Out *ev = event_info;
745 E_Comp_Object *cw = data;
747 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
750 /* handle evas mouse wheel events on client object */
752 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
754 Evas_Event_Mouse_Wheel *ev = event_info;
755 E_Comp_Object *cw = data;
756 E_Binding_Event_Wheel ev2;
759 if (e_client_action_get()) return;
760 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
761 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
764 /* handle evas mouse down events on client object */
766 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
768 Evas_Event_Mouse_Down *ev = event_info;
769 E_Comp_Object *cw = data;
770 E_Binding_Event_Mouse_Button ev2;
773 if (e_client_action_get()) return;
774 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
775 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
778 /* handle evas mouse up events on client object */
780 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
782 Evas_Event_Mouse_Up *ev = event_info;
783 E_Comp_Object *cw = data;
784 E_Binding_Event_Mouse_Button ev2;
787 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
788 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
789 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
792 /* handle evas mouse movement events on client object */
794 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
796 Evas_Event_Mouse_Move *ev = event_info;
797 E_Comp_Object *cw = data;
800 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
801 e_client_mouse_move(cw->ec, &ev->cur.output);
803 /////////////////////////////////////
805 /* helper function for checking compositor themes based on user-defined matches */
807 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
809 if (((m->title) && (!ec->netwm.name)) ||
810 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
812 #if defined(__cplusplus) || defined(c_plusplus)
813 if (((m->clas) && (!ec->icccm.cpp_class)) ||
814 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
817 if (((m->clas) && (!ec->icccm.class)) ||
818 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
822 if (((m->role) && (!ec->icccm.window_role)) ||
823 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
829 if ((int)ec->netwm.type != m->primary_type)
832 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
835 if (m->borderless != 0)
839 if (e_client_util_borderless(ec))
841 if (!(((m->borderless == -1) && (!borderless)) ||
842 ((m->borderless == 1) && (borderless))))
849 if (((ec->icccm.transient_for != 0) ||
852 if (!(((m->dialog == -1) && (!dialog)) ||
853 ((m->dialog == 1) && (dialog))))
856 if (m->accepts_focus != 0)
858 int accepts_focus = 0;
860 if (ec->icccm.accepts_focus)
862 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
863 ((m->accepts_focus == 1) && (accepts_focus))))
872 if (!(((m->vkbd == -1) && (!vkbd)) ||
873 ((m->vkbd == 1) && (vkbd))))
878 if (!(((m->argb == -1) && (!ec->argb)) ||
879 ((m->argb == 1) && (ec->argb))))
882 if (m->fullscreen != 0)
884 int fullscreen = ec->fullscreen;
886 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
887 ((m->fullscreen == 1) && (fullscreen))))
892 if (!(m->modal == -1))
898 /* function for setting up a client's compositor frame theme (cw->shobj) */
900 _e_comp_object_shadow_setup(E_Comp_Object *cw)
904 Eina_List *list = NULL, *l;
905 E_Input_Rect_Data *input_rect_data;
906 E_Input_Rect_Smart_Data *input_rect_sd;
908 Eina_Stringshare *reshadow_group = NULL;
909 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
910 Eina_Stringshare *name, *title;
911 E_Comp_Config *conf = e_comp_config_get();
913 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
914 /* match correct client type */
915 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
916 name = cw->ec->icccm.name;
917 title = cw->ec->icccm.title;
918 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
919 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
921 /* skipping here is mostly a hack for systray because I hate it */
924 EINA_LIST_FOREACH(list, l, m)
926 if (((m->name) && (!name)) ||
927 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
929 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
932 no_shadow = m->no_shadow;
935 /* fast effects are just themes with "/fast" appended and shorter effect times */
938 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
939 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
941 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
943 /* default to non-fast style if fast not available */
946 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
947 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
949 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
951 if (ok && m->visibility_effect)
952 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
959 if (skip || (cw->ec->e.state.video))
961 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
963 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
966 if (conf->shadow_style)
970 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
971 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
973 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
977 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
978 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
980 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
987 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
989 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
993 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
995 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1000 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1005 if (cw->ec->override)
1007 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1008 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1010 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1011 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1017 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1018 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1021 _e_comp_object_shadow(cw);
1024 if (focus || cw->ec->focused || cw->ec->override)
1025 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1027 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1029 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1031 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1032 /* visibility must always be enabled for re_manage clients to prevent
1033 * pop-in animations every time the user sees a persistent client again;
1034 * applying visibility for iconic clients prevents the client from getting
1037 if (cw->visible || cw->ec->re_manage)
1038 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1040 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1042 /* breaks animation counter */
1043 if (cw->frame_object)
1045 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1046 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1047 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1048 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1054 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1058 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1061 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1063 if (input_rect_data->obj)
1065 pass_event_flag = EINA_TRUE;
1071 if (cw->indicator.obj)
1073 Evas_Object *indicator;
1074 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1075 if (indicator != cw->indicator.obj)
1077 edje_object_part_unswallow(cw->shobj, indicator);
1078 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1079 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1083 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1084 evas_object_pass_events_set(cw->obj, pass_event_flag);
1089 /////////////////////////////////////////////
1092 _e_comp_object_animating_begin(E_Comp_Object *cw)
1095 if (cw->animating == 1)
1097 e_comp->animating++;
1099 e_object_ref(E_OBJECT(cw->ec));
1104 _e_comp_object_animating_end(E_Comp_Object *cw)
1113 if (cw->ec->launching)
1115 if (!cw->ec->extra_animating)
1117 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1118 cw->ec->launching = EINA_FALSE;
1119 if (cw->ec->first_mapped)
1121 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1122 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1125 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1129 e_comp->animating--;
1130 cw->showing = cw->hiding = 0;
1132 if (e_comp->animating == 0)
1133 e_comp_visibility_calculation_set(EINA_TRUE);
1134 /* remove ref from animation start, account for possibility of deletion from unref */
1135 return !!e_object_unref(E_OBJECT(cw->ec));
1141 /* handle the end of a compositor animation */
1143 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1145 E_Comp_Object *cw = data;
1147 /* visible clients which have never been sized are a bug */
1148 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1149 CRI("ACK! ec:%p", cw->ec);
1150 if (!_e_comp_object_animating_end(cw)) return;
1151 if (cw->animating) return;
1152 /* hide only after animation finishes to guarantee a full run of the animation */
1153 if (!cw->defer_hide) return;
1154 if ((!strcmp(emission, "e,action,hide,done")) ||
1155 (!strcmp(emission, "e,action,done")) ||
1156 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1158 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1159 evas_object_hide(cw->smart_obj);
1163 /* run a visibility compositor effect if available, return false if object is dead */
1165 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1171 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1172 if (!cw->effect_running)
1173 _e_comp_object_animating_begin(cw);
1174 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1175 return _e_comp_object_animating_end(cw);
1176 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1177 return _e_comp_object_animating_end(cw);
1179 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1182 zone = e_comp_zone_find_by_ec(cw->ec);
1184 zw = zone->w, zh = zone->h;
1189 zone = e_comp_object_util_zone_get(cw->smart_obj);
1190 if (!zone) zone = e_zone_current_get();
1197 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1198 cw->w, cw->h, zw, zh, x, y}, 8);
1199 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1200 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1203 /////////////////////////////////////////////
1205 /* create necessary objects for clients that e manages */
1207 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1209 if (cw->set_mouse_callbacks) return;
1210 if (!cw->smart_obj) return;
1212 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1213 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1214 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1219 cw->set_mouse_callbacks = EINA_TRUE;
1223 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1225 if (!cw->set_mouse_callbacks) return;
1226 if (!cw->smart_obj) return;
1228 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1229 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1230 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1235 cw->set_mouse_callbacks = EINA_FALSE;
1239 _e_comp_object_color_visible_set(E_Comp_Object *cw, Eina_Bool set)
1241 if (cw->color_visible == set) return EINA_TRUE;
1243 cw->color_visible = set;
1245 ELOGF("COMP", "color_visible set:%d", cw->ec, set);
1247 wl_signal_emit_mutable(&cw->events.color_visible_set, NULL);
1253 _e_comp_object_color_visible_update(E_Comp_Object *cw)
1257 e_comp_object_color_get(cw->smart_obj, NULL, NULL, NULL, &a);
1260 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1266 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
1269 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1277 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
1280 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1287 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
1290 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1295 _e_comp_object_color_visible_set(cw, EINA_TRUE);
1299 _e_comp_intercept_effect_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1301 E_Comp_Object *cw = data;
1303 evas_object_color_set(obj, r, g, b, a);
1305 _e_comp_object_color_visible_update(cw);
1309 _e_comp_intercept_shobj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1311 E_Comp_Object *cw = data;
1313 evas_object_color_set(obj, r, g, b, a);
1315 _e_comp_object_color_visible_update(cw);
1319 _e_comp_intercept_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1321 E_Comp_Object *cw = data;
1323 evas_object_color_set(obj, r, g, b, a);
1325 _e_comp_object_color_visible_update(cw);
1329 _e_comp_object_setup(E_Comp_Object *cw)
1331 cw->clip = evas_object_rectangle_add(e_comp->evas);
1332 evas_object_move(cw->clip, -9999, -9999);
1333 evas_object_resize(cw->clip, 999999, 999999);
1334 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1335 cw->effect_obj = edje_object_add(e_comp->evas);
1336 evas_object_move(cw->effect_obj, cw->x, cw->y);
1337 evas_object_clip_set(cw->effect_obj, cw->clip);
1338 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1339 evas_object_intercept_color_set_callback_add(cw->effect_obj, _e_comp_intercept_effect_obj_color_set, cw);
1340 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1341 cw->shobj = edje_object_add(e_comp->evas);
1342 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1343 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1344 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1345 evas_object_intercept_color_set_callback_add(cw->shobj, _e_comp_intercept_shobj_color_set, cw);
1347 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1348 if (cw->ec->override)
1350 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1351 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1352 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1354 else if (!cw->ec->input_only)
1356 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1357 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1358 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1360 cw->real_hid = !cw->ec->input_only;
1361 if (!cw->ec->input_only)
1363 e_util_size_debug_set(cw->effect_obj, 1);
1364 _e_comp_object_mouse_event_callback_set(cw);
1367 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1368 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1369 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1370 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1371 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1372 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1374 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1377 /////////////////////////////////////////////
1379 /* for fast path evas rendering; only called during render */
1381 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1383 E_Comp_Object *cw = data;
1384 E_Client *ec = cw->ec;
1386 int bx, by, bxx, byy;
1388 if (e_object_is_del(E_OBJECT(ec))) return;
1389 if (cw->external_content) return;
1390 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1391 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1394 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1395 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1397 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1399 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1400 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1404 bx = by = bxx = byy = 0;
1405 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1408 Edje_Message_Int_Set *msg;
1409 Edje_Message_Int msg2;
1410 Eina_Bool id = (bx || by || bxx || byy);
1412 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1418 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1420 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1424 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1425 e_comp_client_post_update_add(cw->ec);
1427 else if (e_comp_object_render(ec->frame))
1429 /* apply shape mask if necessary */
1430 if ((!cw->native) && (ec->shaped))
1431 e_comp_object_shape_apply(ec->frame);
1433 /* shaped clients get precise mouse events to handle transparent pixels */
1434 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1436 /* queue another render if client is still dirty; cannot refresh here. */
1437 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1438 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1440 if (cw->render_trace)
1442 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1448 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1450 E_Comp_Object *cw = data;
1451 E_Client *ec = cw->ec;
1453 if (e_object_is_del(E_OBJECT(ec))) return;
1454 if (cw->external_content) return;
1455 if (!e_comp->hwc) return;
1457 e_comp_client_render_list_add(cw->ec);
1459 if (!ec->hwc_window) return;
1461 e_hwc_windows_rendered_window_add(ec->hwc_window);
1464 /////////////////////////////////////////////
1467 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1469 E_Comp_Object *cw = data;
1472 if (cw->render_update_lock.lock)
1474 cw->render_update_lock.pending_move_x = x;
1475 cw->render_update_lock.pending_move_y = y;
1476 cw->render_update_lock.pending_move_set = EINA_TRUE;
1480 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1481 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1482 (cw->external_content))
1484 /* delay to move until the external content is unset */
1485 cw->ec->changes.pos = 1;
1490 if (cw->ec->move_after_resize)
1492 if ((x != cw->ec->x) || (y != cw->ec->y))
1494 if (!cw->ec->is_cursor)
1495 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1496 e_client_pos_set(cw->ec, x, y);
1497 cw->ec->changes.pos = 1;
1503 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1504 (cw->ec->manage_resize.resize_obj))
1506 e_client_pos_set(cw->ec, x, y);
1507 cw->ec->client.x = x + cw->client_inset.l;
1508 cw->ec->client.y = y + cw->client_inset.t;
1509 e_policy_visibility_client_defer_move(cw->ec);
1513 /* if frame_object does not exist, client_inset indicates CSD.
1514 * this means that ec->client matches cw->x/y, the opposite
1517 fx = (!cw->frame_object) * cw->client_inset.l;
1518 fy = (!cw->frame_object) * cw->client_inset.t;
1519 if ((cw->x == x + fx) && (cw->y == y + fy))
1521 if ((cw->ec->x != x) || (cw->ec->y != y))
1523 /* handle case where client tries to move to position and back very quickly */
1524 e_client_pos_set(cw->ec, x, y);
1525 cw->ec->client.x = x + cw->client_inset.l;
1526 cw->ec->client.y = y + cw->client_inset.t;
1530 if (!cw->ec->maximize_override)
1532 /* prevent moving in some directions while directionally maximized */
1533 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1535 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1538 ix = x + cw->client_inset.l;
1539 iy = y + cw->client_inset.t;
1540 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1541 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1542 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1544 /* prevent moving at all if move isn't allowed in current maximize state */
1545 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1546 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1549 zone = e_comp_zone_find_by_ec(cw->ec);
1552 cw->ec->changes.need_unmaximize = 1;
1553 cw->ec->saved.x = ix - zone->x;
1554 cw->ec->saved.y = iy - zone->y;
1555 cw->ec->saved.w = cw->ec->client.w;
1556 cw->ec->saved.h = cw->ec->client.h;
1560 /* only update during resize if triggered by resize */
1561 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1562 /* delay to move while surface waits paired commit serial*/
1563 if (e_client_pending_geometry_has(cw->ec))
1565 /* do nothing while waiting paired commit serial*/
1569 e_client_pos_set(cw->ec, x, y);
1570 if (cw->ec->new_client)
1572 /* don't actually do anything until first client idler loop */
1573 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1574 cw->ec->changes.pos = 1;
1579 /* only update xy position of client to avoid invalid
1580 * first damage region if it is not a new_client. */
1581 cw->ec->client.x = ix;
1582 cw->ec->client.y = iy;
1585 if (!cw->frame_object)
1587 evas_object_move(obj, x, y);
1592 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1594 E_Comp_Object *cw = data;
1595 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1598 if (cw->render_update_lock.lock)
1600 cw->render_update_lock.pending_resize_w = w;
1601 cw->render_update_lock.pending_resize_h = h;
1602 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1606 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1608 e_client_size_set(cw->ec, w, h);
1609 evas_object_resize(obj, w, h);
1613 /* if frame_object does not exist, client_inset indicates CSD.
1614 * this means that ec->client matches cw->w/h, the opposite
1617 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1618 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1619 if ((cw->w == w + fw) && (cw->h == h + fh))
1621 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1622 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1623 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1625 /* handle case where client tries to resize itself and back very quickly */
1626 e_client_size_set(cw->ec, w, h);
1627 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1628 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1629 evas_object_smart_callback_call(obj, "client_resize", NULL);
1633 /* guarantee that fullscreen is fullscreen */
1634 zone = e_comp_zone_find_by_ec(cw->ec);
1636 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1638 if (!e_client_transform_core_enable_get(cw->ec))
1641 /* calculate client size */
1642 iw = w - cw->client_inset.l - cw->client_inset.r;
1643 ih = h - cw->client_inset.t - cw->client_inset.b;
1644 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1646 /* prevent resizing while maximized depending on direction and config */
1647 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1649 Eina_Bool reject = EINA_FALSE;
1650 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1652 if (cw->ec->client.h != ih)
1654 cw->ec->saved.h = ih;
1655 cw->ec->saved.y = cw->ec->client.y - zone->y;
1656 reject = cw->ec->changes.need_unmaximize = 1;
1659 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1661 if (cw->ec->client.w != iw)
1663 cw->ec->saved.w = iw;
1664 cw->ec->saved.x = cw->ec->client.x - zone->x;
1665 reject = cw->ec->changes.need_unmaximize = 1;
1674 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1676 /* do nothing until client idler loops */
1677 if ((cw->ec->w != w) || (cw->ec->h != h))
1679 e_client_size_set(cw->ec, w, h);
1680 cw->ec->changes.size = 1;
1685 if (e_client_pending_geometry_has(cw->ec))
1687 /* do nothing while waiting paired commit serial*/
1691 e_client_size_set(cw->ec, w, h);
1693 cw->ec->client.w = iw;
1694 cw->ec->client.h = ih;
1695 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1697 /* The size of non-compositing window can be changed, so there is a
1698 * need to check that cw is H/W composited if cw is not redirected.
1699 * And of course we have to change size of evas object of H/W composited cw,
1700 * otherwise cw can't receive input events even if it is shown on the screen.
1702 Eina_Bool redirected = cw->redirected;
1704 redirected = e_comp_is_on_overlay(cw->ec);
1706 if ((!cw->ec->input_only) && (redirected) &&
1707 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1708 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1709 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1710 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1713 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1714 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1716 prev_w = cw->w, prev_h = cw->h;
1717 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1718 /* check shading and clamp to pixmap size for regular clients */
1719 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1720 (((w - fw != pw) || (h - fh != ph))))
1722 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1723 evas_object_smart_callback_call(obj, "client_resize", NULL);
1725 if (cw->frame_object || cw->ec->input_only)
1726 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1729 if ((cw->w == w) && (cw->h == h))
1731 /* going to be a noop resize which won't trigger smart resize */
1732 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1733 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1735 evas_object_resize(obj, w, h);
1739 evas_object_smart_callback_call(obj, "client_resize", NULL);
1742 if ((!cw->frame_object) && (!cw->ec->input_only))
1744 /* "just do it" for overrides */
1745 evas_object_resize(obj, w, h);
1747 if (!cw->ec->override)
1749 /* shape probably changed for non-overrides */
1754 /* this fixes positioning jiggles when using a resize mode
1755 * which also changes the client's position
1758 if (cw->frame_object)
1759 x = cw->x, y = cw->y;
1761 x = cw->ec->x, y = cw->ec->y;
1762 switch (cw->ec->resize_mode)
1764 case E_POINTER_RESIZE_BL:
1765 case E_POINTER_RESIZE_L:
1766 evas_object_move(obj, x + prev_w - cw->w, y);
1768 case E_POINTER_RESIZE_TL:
1769 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1771 case E_POINTER_RESIZE_T:
1772 case E_POINTER_RESIZE_TR:
1773 evas_object_move(obj, x, y + prev_h - cw->h);
1782 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1784 #ifdef REFACTOR_DESK_AREA
1785 E_Comp_Object *cw = data;
1786 E_Comp_Object_Data_Set_Layer layer_set_data;
1788 layer_set_data.cw = cw;
1789 layer_set_data.layer = layer;
1791 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1795 e_comp_render_queue();
1796 e_comp_object_transform_obj_stack_update(obj);
1800 E_Comp_Object *cw = data;
1801 E_Comp_Wl_Client_Data *child_cdata;
1802 unsigned int l = e_comp_canvas_layer_map(layer);
1805 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1807 /* doing a compositor effect, follow directions */
1808 _e_comp_object_layer_set(obj, layer);
1809 if (layer == cw->ec->layer) //trying to put layer back
1813 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1814 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1815 if (cw->layer != l) goto layer_set;
1819 e_comp_render_queue();
1821 ec = e_client_above_get(cw->ec);
1822 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1823 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1824 ec = e_client_above_get(ec);
1825 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1827 ec = e_client_below_get(cw->ec);
1828 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1829 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1830 ec = e_client_below_get(ec);
1831 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1833 evas_object_stack_above(obj, ec->frame);
1838 if (ec && (cw->ec->parent == ec))
1840 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1841 evas_object_stack_above(obj, ec->frame);
1843 evas_object_stack_below(obj, ec->frame);
1846 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1852 if (cw->layer == l) return;
1853 if (e_comp_canvas_client_layer_map(layer) == 9999)
1854 return; //invalid layer for clients not doing comp effects
1855 if (cw->ec->fullscreen)
1857 cw->ec->saved.layer = layer;
1860 oldraise = e_config->transient.raise;
1862 /* clamp to valid client layer */
1863 layer = e_comp_canvas_client_layer_map_nearest(layer);
1864 cw->ec->layer = layer;
1865 if (e_config->transient.layer)
1868 Eina_List *list = eina_list_clone(cw->ec->transients);
1870 /* We need to set raise to one, else the child wont
1871 * follow to the new layer. It should be like this,
1872 * even if the user usually doesn't want to raise
1875 e_config->transient.raise = 1;
1876 EINA_LIST_FREE(list, child)
1878 child_cdata = e_client_cdata_get(child);
1879 if (child_cdata && !child_cdata->mapped)
1881 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1884 e_client_layer_set(child, layer);
1888 e_config->transient.raise = oldraise;
1890 _e_comp_object_layers_remove(cw);
1891 cw->layer = e_comp_canvas_layer_map(layer);
1892 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1893 //if (cw->ec->new_client)
1894 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1895 _e_comp_object_layer_set(obj, layer);
1896 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1897 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1898 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1900 /* can't stack a client above its own layer marker */
1901 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1903 if (!cw->visible) return;
1904 e_comp_render_queue();
1905 _e_comp_object_transform_obj_stack_update(obj);
1909 #ifdef REFACTOR_DESK_AREA
1911 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1914 #ifdef REFACTOR_DESK_AREA
1916 e_comp_object_raise(Evas_Object *obj)
1919 _e_comp_object_raise(Evas_Object *obj)
1922 evas_object_raise(obj);
1924 if (evas_object_smart_smart_get(obj))
1926 E_Client *ec = e_comp_object_client_get(obj);
1928 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1932 #ifdef REFACTOR_DESK_AREA
1934 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1937 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1940 evas_object_lower(obj);
1942 if (evas_object_smart_smart_get(obj))
1944 E_Client *ec = e_comp_object_client_get(obj);
1947 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1948 #ifdef REFACTOR_DESK_AREA
1949 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1951 wl_signal_emit_mutable(&cw->events.lower, NULL);
1957 #ifdef REFACTOR_DESK_AREA
1959 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1962 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1965 evas_object_stack_above(obj, target);
1967 if (evas_object_smart_smart_get(obj))
1969 E_Client *ec = e_comp_object_client_get(obj);
1971 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1975 #ifdef REFACTOR_DESK_AREA
1977 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1980 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1983 evas_object_stack_below(obj, target);
1985 if (evas_object_smart_smart_get(obj))
1987 E_Client *ec = e_comp_object_client_get(obj);
1989 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1993 #ifdef REFACTOR_DESK_AREA
1995 e_comp_object_layer_set(Evas_Object *obj, short layer)
1998 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2001 evas_object_layer_set(obj, layer);
2003 if (evas_object_smart_smart_get(obj))
2005 E_Client *ec = e_comp_object_client_get(obj);
2007 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2011 #ifdef REFACTOR_DESK_AREA
2014 _e_comp_object_is_pending(E_Client *ec)
2018 if (!ec) return EINA_FALSE;
2020 topmost = e_comp_wl_topmost_parent_get(ec);
2022 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2026 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2028 E_Comp_Object *cw2 = NULL;
2031 Evas_Object *o = stack;
2032 #ifdef REFACTOR_DESK_AREA
2033 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
2035 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2038 /* We should consider topmost's layer_pending for subsurface */
2039 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2041 if (_e_comp_object_is_pending(cw->ec))
2042 e_comp_object_layer_update(cw->smart_obj,
2043 raising? stack : NULL,
2044 raising? NULL : stack);
2046 /* obey compositor effects! */
2047 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2048 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2049 stack_cb(cw->smart_obj, stack);
2050 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2051 evas_object_data_del(cw->smart_obj, "client_restack");
2055 cw2 = evas_object_data_get(o, "comp_obj");
2057 /* assume someone knew what they were doing during client init */
2058 if (cw->ec->new_client)
2059 layer = cw->ec->layer;
2060 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2061 layer = cw2->ec->layer;
2063 layer = evas_object_layer_get(stack);
2064 ecstack = e_client_below_get(cw->ec);
2065 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2067 evas_object_layer_set(cw->smart_obj, layer);
2068 /* we got our layer wrangled, return now! */
2069 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2072 /* check if we're stacking below another client */
2075 /* check for non-client layer object */
2076 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2078 /* find an existing client to use for layering
2079 * by walking up the object stack
2081 * this is guaranteed to be pretty quick since we'll either:
2082 * - run out of client layers
2083 * - find a stacking client
2085 o = evas_object_above_get(o);
2086 if ((!o) || (o == cw->smart_obj)) break;
2087 if (evas_object_layer_get(o) != layer)
2089 /* reached the top client layer somehow
2090 * use top client object
2092 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2095 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2096 * return here since the top client layer window
2101 ec = e_client_top_get();
2106 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2109 if (cw2 && cw->layer != cw2->layer)
2112 /* remove existing layers */
2113 _e_comp_object_layers_remove(cw);
2116 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2117 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2118 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2119 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2120 else //if no stacking objects found, either raise or lower
2121 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2124 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2126 /* find new object for stacking if cw2 is on state of layer_pending */
2127 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2129 E_Client *new_stack = NULL, *current_ec = NULL;
2130 current_ec = cw2->ec;
2133 while ((new_stack = e_client_below_get(current_ec)))
2135 current_ec = new_stack;
2136 if (new_stack == cw->ec) continue;
2137 if (new_stack->layer != cw2->ec->layer) break;
2138 if (!_e_comp_object_is_pending(new_stack)) break;
2140 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2141 stack = new_stack->frame;
2144 /* stack it above layer object */
2146 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2147 stack = e_comp->layers[below_layer].obj;
2152 while ((new_stack = e_client_above_get(current_ec)))
2154 current_ec = new_stack;
2155 if (new_stack == cw->ec) continue;
2156 if (new_stack->layer != cw2->ec->layer) break;
2157 if (!_e_comp_object_is_pending(new_stack)) break;
2159 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2160 stack = new_stack->frame;
2162 stack = e_comp->layers[cw2->layer].obj;
2166 /* set restack if stacking has changed */
2167 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2168 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2169 stack_cb(cw->smart_obj, stack);
2170 if (e_comp->layers[cw->layer].obj)
2171 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2173 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2175 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2176 evas_object_data_del(cw->smart_obj, "client_restack");
2177 if (!cw->visible) return;
2178 e_comp_render_queue();
2183 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2185 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2187 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2189 #ifdef REFACTOR_DESK_AREA
2190 E_Comp_Object *cw = data;
2191 E_Comp_Object_Data_Stack_Above stack_above_data;
2193 stack_above_data.cw = cw;
2194 stack_above_data.above_obj = above;
2196 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2198 if (evas_object_below_get(obj) == above)
2200 e_comp_object_layer_update(obj, above, NULL);
2204 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2206 _e_comp_object_transform_obj_stack_update(obj);
2207 _e_comp_object_transform_obj_stack_update(above);
2214 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2216 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2218 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2220 #ifdef REFACTOR_DESK_AREA
2221 E_Comp_Object *cw = data;
2222 E_Comp_Object_Data_Stack_Below stack_below_data;
2224 stack_below_data.cw = cw;
2225 stack_below_data.below_obj = below;
2227 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2230 e_comp_render_queue();
2232 if (evas_object_above_get(obj) == below)
2234 e_comp_object_layer_update(obj, NULL, below);
2238 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2240 if (evas_object_smart_smart_get(obj))
2241 _e_comp_object_transform_obj_stack_update(obj);
2242 if (evas_object_smart_smart_get(below))
2243 _e_comp_object_transform_obj_stack_update(below);
2250 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2252 E_Comp_Object *cw = data;
2254 #ifdef REFACTOR_DESK_AREA
2259 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2261 #ifdef REFACTOR_DESK_AREA
2262 wl_signal_emit_mutable(&cw->events.lower, cw);
2264 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2266 if (cw->ec->layer_pending)
2267 e_comp_object_layer_update(obj, NULL, obj);
2269 #ifdef REFACTOR_DESK_AREA
2270 e_comp_object_lower(cw, obj);
2272 _e_comp_object_lower(cw, obj);
2276 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2277 o = evas_object_below_get(obj);
2278 _e_comp_object_layers_remove(cw);
2279 /* prepend to client list since this client should be the first item now */
2280 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2281 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2282 evas_object_data_set(obj, "client_restack", (void*)1);
2283 #ifdef REFACTOR_DESK_AREA
2284 e_comp_object_lower(cw, obj);
2286 _e_comp_object_lower(cw, obj);
2288 evas_object_data_del(obj, "client_restack");
2289 if (!cw->visible) goto end;
2290 e_comp_render_queue();
2291 #ifdef REFACTOR_DESK_AREA
2292 e_comp_object_transform_obj_stack_update(obj);
2294 _e_comp_object_transform_obj_stack_update(obj);
2303 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2305 E_Comp_Object *cw = data;
2306 #ifdef REFACTOR_DESK_AREA
2312 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2314 #ifdef REFACTOR_DESK_AREA
2315 wl_signal_emit_mutable(&cw->events.raise, cw);
2317 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2319 if (cw->ec->layer_pending)
2321 int obj_layer = evas_object_layer_get(obj);
2322 if (cw->ec->layer != obj_layer)
2323 e_comp_object_layer_update(obj, NULL, NULL);
2325 #ifdef REFACTOR_DESK_AREA
2326 e_comp_object_raise(obj);
2328 _e_comp_object_raise(obj);
2332 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2333 o = evas_object_above_get(obj);
2334 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2336 /* still stack below override below the layer marker */
2337 for (op = o = e_comp->layers[cw->layer].obj;
2338 o && o != e_comp->layers[cw->layer - 1].obj;
2339 op = o, o = evas_object_below_get(o))
2341 if (evas_object_smart_smart_get(o))
2345 ec = e_comp_object_client_get(o);
2346 if (ec && (!ec->override)) break;
2349 #ifdef REFACTOR_DESK_AREA
2350 e_comp_object_stack_below(obj, op);
2352 _e_comp_object_stack_below(obj, op);
2354 e_client_focus_defer_set(cw->ec);
2356 if (!cw->visible) goto end;
2357 e_comp_render_queue();
2358 #ifdef REFACTOR_DESK_AREA
2359 e_comp_object_transform_obj_stack_update(obj);
2361 _e_comp_object_transform_obj_stack_update(obj);
2370 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2372 E_Comp_Object *cw = data;
2374 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2375 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2377 ELOGF("COMP", "Hide. intercepted", cw->ec);
2382 if (cw->ec->launching == EINA_TRUE)
2384 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2385 cw->ec->launching = EINA_FALSE;
2390 /* hidden flag = just do it */
2391 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2392 evas_object_hide(obj);
2394 wl_signal_emit_mutable(&cw->events.hide, NULL);
2399 if (cw->ec->input_only)
2401 /* input_only = who cares */
2402 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2403 evas_object_hide(obj);
2405 wl_signal_emit_mutable(&cw->events.hide, NULL);
2409 /* already hidden or currently animating */
2410 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2412 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2416 /* don't try hiding during shutdown */
2417 cw->defer_hide |= stopping;
2418 if (!cw->defer_hide)
2420 if ((!cw->ec->iconic) && (!cw->ec->override))
2421 /* unset delete requested so the client doesn't break */
2422 cw->ec->delete_requested = 0;
2423 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2425 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2426 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2429 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2432 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2434 _e_comp_object_animating_begin(cw);
2435 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2437 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2438 cw->defer_hide = !!cw->animating;
2440 e_comp_object_effect_set(obj, NULL);
2443 if (cw->animating) return;
2444 /* if we have no animations running, go ahead and hide */
2446 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2447 evas_object_hide(obj);
2449 wl_signal_emit_mutable(&cw->events.hide, NULL);
2453 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2455 E_Client *ec = cw->ec;
2458 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2460 if (ec->show_pending.count > 0)
2462 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2463 ec->show_pending.running = EINA_TRUE;
2467 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2468 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2470 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2475 ELOGF("COMP", "show_helper. cw(v:%d,a:%d,dh:%d,ct:%d,u:%p,s(%d,%d)), ec(i:%d(%d,%d),o:%d,g:%d,n:%d)", ec,
2476 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2477 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2480 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2483 if (ec->iconic && cw->animating)
2485 /* triggered during iconify animation */
2486 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2489 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2492 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2493 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2495 evas_object_move(cw->smart_obj, ec->x, ec->y);
2496 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2497 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2499 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2500 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2503 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2504 evas_object_show(cw->smart_obj);
2507 e_client_focus_defer_set(ec);
2511 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2515 pw = ec->client.w, ph = ec->client.h;
2517 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2519 ec->changes.visible = !ec->hidden;
2522 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2526 cw->updates = eina_tiler_new(pw, ph);
2529 ec->changes.visible = !ec->hidden;
2532 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2537 eina_tiler_tile_size_set(cw->updates, 1, 1);
2540 /* ignore until client idler first run */
2541 ec->changes.visible = !ec->hidden;
2544 ELOGF("COMP", "show_helper. return. new_client", ec);
2551 evas_object_move(cw->smart_obj, ec->x, ec->y);
2552 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2553 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2554 evas_object_show(cw->smart_obj);
2557 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2559 /* start_drag not received */
2560 ec->changes.visible = 1;
2563 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2566 /* re-set geometry */
2567 evas_object_move(cw->smart_obj, ec->x, ec->y);
2568 /* force resize in case it hasn't happened yet, or just to update size */
2569 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2570 if ((cw->w < 1) || (cw->h < 1))
2572 /* if resize didn't go through, try again */
2573 ec->visible = ec->changes.visible = 1;
2575 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2578 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2579 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2580 e_pixmap_clear(ec->pixmap);
2582 if (cw->real_hid && w && h)
2585 /* force comp theming in case it didn't happen already */
2586 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2587 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2588 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2591 /* only do the show if show is allowed */
2594 if (ec->internal) //internal clients render when they feel like it
2595 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2597 if (!e_client_is_iconified_by_client(ec)||
2598 e_policy_visibility_client_is_uniconic(ec))
2600 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2601 evas_object_show(cw->smart_obj);
2603 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2604 it is rendered in idle callback without native surface and
2605 compositor shows an empty frame if other objects aren't shown
2606 because job callback of e_comp called at the next loop.
2607 it causes a visual defect when windows are switched.
2611 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2612 e_comp_object_dirty(cw->smart_obj);
2613 e_comp_object_render(cw->smart_obj);
2618 wl_signal_emit_mutable(&cw->events.show, NULL);
2622 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2624 E_Comp_Object *cw = data;
2625 E_Client *ec = cw->ec;
2627 E_Input_Rect_Data *input_rect_data;
2628 E_Input_Rect_Smart_Data *input_rect_sd;
2631 if (ec->ignored) return;
2635 //INF("SHOW2 %p", ec);
2636 _e_comp_intercept_show_helper(cw);
2639 //INF("SHOW %p", ec);
2642 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2643 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2644 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2645 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2649 if ((!cw->obj) && (cw->external_content))
2651 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2655 _e_comp_object_setup(cw);
2658 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2659 cw->obj = evas_object_image_filled_add(e_comp->evas);
2660 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2661 e_util_size_debug_set(cw->obj, 1);
2662 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2663 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2664 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2665 evas_object_name_set(cw->obj, "cw->obj");
2666 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2667 evas_object_intercept_color_set_callback_add(cw->obj, _e_comp_intercept_obj_color_set, cw);
2669 _e_comp_object_alpha_set(cw);
2672 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2675 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2676 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2679 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2682 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2684 if (input_rect_data->obj)
2686 evas_object_geometry_set(input_rect_data->obj,
2687 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2688 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2689 input_rect_data->rect.w, input_rect_data->rect.h);
2696 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2698 _e_comp_intercept_show_helper(cw);
2702 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2704 E_Comp_Object *cw = data;
2708 /* note: this is here as it seems there are enough apps that do not even
2709 * expect us to emulate a look of focus but not actually set x input
2710 * focus as we do - so simply abort any focus set on such windows */
2711 /* be strict about accepting focus hint */
2712 /* be strict about accepting focus hint */
2713 if ((!ec->icccm.accepts_focus) &&
2714 (!ec->icccm.take_focus))
2718 if (e_client_focused_get() == ec)
2719 e_client_focused_set(NULL);
2721 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2722 evas_object_focus_set(obj, focus);
2726 if (focus && ec->lock_focus_out) return;
2727 if (e_object_is_del(E_OBJECT(ec)) && focus)
2728 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2730 /* filter focus setting based on current state */
2735 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2736 evas_object_focus_set(obj, focus);
2739 if ((ec->iconic) && (!ec->deskshow))
2741 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2743 /* don't focus an iconified window. that's silly! */
2744 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2745 e_client_uniconify(ec);
2746 e_client_focus_latest_set(ec);
2760 /* not yet visible, wait till the next time... */
2761 ec->want_focus = !ec->hidden;
2766 e_client_focused_set(ec);
2770 if (e_client_focused_get() == ec)
2771 e_client_focused_set(NULL);
2775 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2777 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2779 evas_object_focus_set(obj, focus);
2783 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2785 E_Comp_Object *cw = data;
2787 if (cw->transparent.set)
2789 cw->transparent.user_r = r;
2790 cw->transparent.user_g = g;
2791 cw->transparent.user_b = b;
2792 cw->transparent.user_a = a;
2794 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2796 cw->transparent.user_r,
2797 cw->transparent.user_g,
2798 cw->transparent.user_b,
2799 cw->transparent.user_a);
2803 evas_object_color_set(obj, r, g, b, a);
2806 wl_signal_emit_mutable(&cw->events.color_set, NULL);
2808 _e_comp_object_color_visible_update(cw);
2811 ////////////////////////////////////////////////////
2814 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2816 int w, h, ox, oy, ow, oh;
2818 Eina_Bool pass_event_flag = EINA_FALSE;
2819 E_Input_Rect_Data *input_rect_data;
2820 E_Input_Rect_Smart_Data *input_rect_sd;
2822 if (cw->frame_object)
2824 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2825 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2826 /* set a fixed size, force edje calc, check size difference */
2827 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2828 edje_object_message_signal_process(cw->frame_object);
2829 edje_object_calc_force(cw->frame_object);
2830 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2831 cw->client_inset.l = ox;
2832 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2833 cw->client_inset.t = oy;
2834 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2835 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2836 evas_object_resize(cw->frame_object, w, h);
2840 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2843 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2845 if (input_rect_data->obj)
2847 pass_event_flag = EINA_TRUE;
2853 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2854 evas_object_pass_events_set(cw->obj, pass_event_flag);
2858 cw->client_inset.l = 0;
2859 cw->client_inset.r = 0;
2860 cw->client_inset.t = 0;
2861 cw->client_inset.b = 0;
2863 cw->client_inset.calc = !!cw->frame_object;
2867 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2869 E_Comp_Object *cw = data;
2873 /* - get current size
2875 * - readjust for new frame size
2878 w = cw->ec->w, h = cw->ec->h;
2879 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2881 _e_comp_object_frame_recalc(cw);
2883 if (!cw->ec->fullscreen)
2884 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2886 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2887 if (cw->ec->fullscreen)
2889 zone = e_comp_zone_find_by_ec(cw->ec);
2891 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2893 else if (cw->ec->new_client)
2895 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2896 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2897 evas_object_resize(cw->ec->frame, w, h);
2899 else if ((w != cw->ec->w) || (h != cw->ec->h))
2900 evas_object_resize(cw->ec->frame, w, h);
2904 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2906 E_Comp_Object *cw = data;
2908 _e_comp_object_shadow_setup(cw);
2909 if (cw->frame_object)
2911 _e_comp_object_shadow(cw);
2912 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2913 _e_comp_object_frame_recalc(cw);
2914 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2919 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2921 E_Comp_Object *cw = data;
2923 if (_e_comp_object_shadow_setup(cw))
2924 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2925 if (cw->frame_object)
2927 _e_comp_object_shadow(cw);
2928 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2929 _e_comp_object_frame_recalc(cw);
2930 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2935 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2937 E_Comp_Object *cw = data;
2939 if (cw->frame_object)
2941 _e_comp_object_shadow(cw);
2942 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2943 _e_comp_object_frame_recalc(cw);
2944 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2949 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2951 E_Comp_Object *cw = data;
2953 if (_e_comp_object_shadow_setup(cw))
2956 cw->ec->changes.size = 1;
2958 if (cw->frame_object)
2960 _e_comp_object_shadow(cw);
2961 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2962 _e_comp_object_frame_recalc(cw);
2963 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2968 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2970 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2974 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2976 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2980 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2982 E_Comp_Object *cw = data;
2984 if (!cw->ec) return; //NYI
2985 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2989 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2991 E_Comp_Object *cw = data;
2993 if (!cw->ec) return; //NYI
2994 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2998 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3000 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3004 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3006 E_Comp_Object *cw = data;
3008 if (!e_object_is_del(E_OBJECT(cw->ec)))
3009 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3013 _e_comp_input_obj_smart_add(Evas_Object *obj)
3015 E_Input_Rect_Smart_Data *input_rect_sd;
3016 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3018 if (!input_rect_sd) return;
3019 evas_object_smart_data_set(obj, input_rect_sd);
3023 _e_comp_input_obj_smart_del(Evas_Object *obj)
3025 E_Input_Rect_Smart_Data *input_rect_sd;
3026 E_Input_Rect_Data *input_rect_data;
3028 input_rect_sd = evas_object_smart_data_get(obj);
3029 if (!input_rect_sd) return;
3031 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3033 if (input_rect_data->obj)
3035 evas_object_smart_member_del(input_rect_data->obj);
3036 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3038 E_FREE(input_rect_data);
3040 E_FREE(input_rect_sd);
3044 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3046 E_Input_Rect_Smart_Data *input_rect_sd;
3047 E_Input_Rect_Data *input_rect_data;
3051 input_rect_sd = evas_object_smart_data_get(obj);
3052 if (!input_rect_sd) return;
3054 cw = input_rect_sd->cw;
3055 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3057 if (input_rect_data->obj)
3059 evas_object_geometry_set(input_rect_data->obj,
3060 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3061 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3062 input_rect_data->rect.w, input_rect_data->rect.h);
3068 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3070 E_Input_Rect_Smart_Data *input_rect_sd;
3071 E_Input_Rect_Data *input_rect_data;
3075 input_rect_sd = evas_object_smart_data_get(obj);
3076 if (!input_rect_sd) return;
3078 cw = input_rect_sd->cw;
3079 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3081 if (input_rect_data->obj)
3083 evas_object_geometry_set(input_rect_data->obj,
3084 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3085 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3086 input_rect_data->rect.w, input_rect_data->rect.h);
3092 _e_comp_input_obj_smart_show(Evas_Object *obj)
3094 E_Input_Rect_Smart_Data *input_rect_sd;
3095 E_Input_Rect_Data *input_rect_data;
3098 input_rect_sd = evas_object_smart_data_get(obj);
3099 if (!input_rect_sd) return;
3101 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3103 if (input_rect_data->obj)
3105 evas_object_show(input_rect_data->obj);
3111 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3113 E_Input_Rect_Smart_Data *input_rect_sd;
3114 E_Input_Rect_Data *input_rect_data;
3117 input_rect_sd = evas_object_smart_data_get(obj);
3118 if (!input_rect_sd) return;
3120 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3122 if (input_rect_data->obj)
3124 evas_object_hide(input_rect_data->obj);
3130 _e_comp_input_obj_smart_init(void)
3132 if (_e_comp_input_obj_smart) return;
3134 static const Evas_Smart_Class sc =
3136 INPUT_OBJ_SMART_NAME,
3137 EVAS_SMART_CLASS_VERSION,
3138 _e_comp_input_obj_smart_add,
3139 _e_comp_input_obj_smart_del,
3140 _e_comp_input_obj_smart_move,
3141 _e_comp_input_obj_smart_resize,
3142 _e_comp_input_obj_smart_show,
3143 _e_comp_input_obj_smart_hide,
3156 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3162 _e_comp_smart_add(Evas_Object *obj)
3166 cw = E_NEW(E_Comp_Object, 1);
3167 EINA_SAFETY_ON_NULL_RETURN(cw);
3169 wl_signal_init(&cw->events.lower);
3170 #ifdef REFACTOR_DESK_AREA
3171 wl_signal_init(&cw->events.lower_done);
3172 wl_signal_init(&cw->events.raise);
3174 wl_signal_init(&cw->events.show);
3175 wl_signal_init(&cw->events.hide);
3176 #ifdef REFACTOR_DESK_AREA
3177 wl_signal_init(&cw->events.set_layer);
3178 wl_signal_init(&cw->events.stack_above);
3179 wl_signal_init(&cw->events.stack_below);
3181 wl_signal_init(&cw->events.image_filter_set);
3182 wl_signal_init(&cw->events.render_op_set);
3183 wl_signal_init(&cw->events.content_type_set);
3184 wl_signal_init(&cw->events.color_set);
3185 wl_signal_init(&cw->events.color_visible_set);
3187 cw->smart_obj = obj;
3188 cw->x = cw->y = cw->w = cw->h = -1;
3189 evas_object_smart_data_set(obj, cw);
3190 cw->opacity = 255.0;
3191 cw->external_content = 0;
3192 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3193 cw->transform_bg_color.r = 0;
3194 cw->transform_bg_color.g = 0;
3195 cw->transform_bg_color.b = 0;
3196 cw->transform_bg_color.a = 255;
3197 cw->color_visible = EINA_TRUE;
3198 evas_object_data_set(obj, "comp_obj", cw);
3199 evas_object_move(obj, -1, -1);
3200 /* intercept ALL the callbacks! */
3201 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3202 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3203 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3204 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3205 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3206 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3207 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3208 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3209 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3210 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3211 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3213 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3214 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3215 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3216 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3218 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3219 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3221 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3222 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3224 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3226 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3227 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3231 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3234 evas_object_color_set(cw->clip, r, g, b, a);
3235 evas_object_smart_callback_call(obj, "color_set", NULL);
3240 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3243 evas_object_clip_set(cw->clip, clip);
3247 _e_comp_smart_clip_unset(Evas_Object *obj)
3250 evas_object_clip_unset(cw->clip);
3254 _e_comp_smart_hide(Evas_Object *obj)
3256 TRACE_DS_BEGIN(COMP:SMART HIDE);
3261 evas_object_hide(cw->clip);
3262 if (cw->input_obj) evas_object_hide(cw->input_obj);
3263 evas_object_hide(cw->effect_obj);
3264 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3265 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3266 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3273 /* unset native surface if current displaying buffer was destroied */
3274 if (!cw->buffer_destroy_listener.notify)
3276 Evas_Native_Surface *ns;
3277 ns = evas_object_image_native_surface_get(cw->obj);
3278 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3279 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3282 if (!cw->ec->input_only)
3284 edje_object_freeze(cw->effect_obj);
3285 edje_object_freeze(cw->shobj);
3286 edje_object_play_set(cw->shobj, 0);
3287 if (cw->frame_object)
3288 edje_object_play_set(cw->frame_object, 0);
3291 e_comp_render_queue(); //force nocomp recheck
3297 _e_comp_smart_show(Evas_Object *obj)
3305 if ((cw->w < 0) || (cw->h < 0))
3306 CRI("ACK! ec:%p", cw->ec);
3308 TRACE_DS_BEGIN(COMP:SMART SHOW);
3310 e_comp_object_map_update(obj);
3312 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3313 evas_object_show(tmp->frame);
3315 evas_object_show(cw->clip);
3316 if (cw->input_obj) evas_object_show(cw->input_obj);
3317 if (!cw->ec->input_only)
3319 edje_object_thaw(cw->effect_obj);
3320 edje_object_thaw(cw->shobj);
3321 edje_object_play_set(cw->shobj, 1);
3322 if (cw->frame_object)
3323 edje_object_play_set(cw->frame_object, 1);
3325 evas_object_show(cw->effect_obj);
3326 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3327 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3328 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3329 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3330 e_comp_render_queue();
3331 if (cw->ec->input_only)
3336 if (cw->ec->iconic && (!cw->ec->new_client))
3338 if (e_client_is_iconified_by_client(cw->ec))
3340 ELOGF("COMP", "Set launching flag..", cw->ec);
3341 cw->ec->launching = EINA_TRUE;
3344 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3346 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3349 ELOGF("COMP", "Set launching flag..", cw->ec);
3350 cw->ec->launching = EINA_TRUE;
3352 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3353 _e_comp_object_animating_begin(cw);
3354 if (!_e_comp_object_effect_visibility_start(cw, 1))
3360 /* ensure some random effect doesn't lock the client offscreen */
3364 e_comp_object_effect_set(obj, NULL);
3367 _e_comp_object_dim_update(cw);
3373 _e_comp_smart_del(Evas_Object *obj)
3379 if (cw->buffer_destroy_listener.notify)
3381 wl_list_remove(&cw->buffer_destroy_listener.link);
3382 cw->buffer_destroy_listener.notify = NULL;
3385 if (cw->tbm_surface)
3387 tbm_surface_internal_unref(cw->tbm_surface);
3388 cw->tbm_surface = NULL;
3391 if (cw->render_update_lock.buffer_ref.buffer)
3393 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3394 cw->ec, cw->render_update_lock.lock);
3395 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3398 e_comp_object_render_update_del(cw->smart_obj);
3399 E_FREE_FUNC(cw->updates, eina_tiler_free);
3400 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3407 EINA_LIST_FREE(cw->obj_mirror, o)
3409 evas_object_image_data_set(o, NULL);
3410 evas_object_freeze_events_set(o, 1);
3411 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3415 #ifdef REFACTOR_DESK_AREA
3417 _e_comp_object_layers_remove(cw);
3419 l = evas_object_data_get(obj, "comp_object-to_del");
3420 E_FREE_LIST(l, evas_object_del);
3421 _e_comp_object_mouse_event_callback_unset(cw);
3422 evas_object_del(cw->clip);
3423 evas_object_del(cw->obj);
3424 evas_object_del(cw->shobj);
3425 evas_object_del(cw->effect_obj);
3426 evas_object_del(cw->frame_object);
3427 evas_object_del(cw->input_obj);
3428 evas_object_del(cw->mask.obj);
3429 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3430 evas_object_del(cw->transform_bg_obj);
3431 evas_object_del(cw->transform_tranp_obj);
3432 evas_object_del(cw->default_input_obj);
3433 eina_stringshare_del(cw->frame_theme);
3434 eina_stringshare_del(cw->frame_name);
3438 e_comp->animating--;
3440 e_object_unref(E_OBJECT(cw->ec));
3442 cw->ec->frame = NULL;
3447 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3451 cw->x = x, cw->y = y;
3452 evas_object_move(cw->effect_obj, x, y);
3453 evas_object_move(cw->default_input_obj, x, y);
3454 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3456 e_comp_object_map_update(obj);
3460 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3462 Eina_Bool first = EINA_FALSE;
3467 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3469 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3471 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3473 if (cw->w != w || cw->h != h)
3474 e_comp_object_map_update(obj);
3476 first = ((cw->w < 1) || (cw->h < 1));
3477 cw->w = w, cw->h = h;
3481 if (cw->frame_object)
3482 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3485 /* verify pixmap:object size */
3486 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3488 if ((ww != pw) || (hh != ph))
3489 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3491 evas_object_resize(cw->effect_obj, tw, th);
3492 evas_object_resize(cw->default_input_obj, w, h);
3494 evas_object_resize(cw->input_obj, w, h);
3496 evas_object_resize(cw->mask.obj, w, h);
3497 /* resize render update tiler */
3500 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3501 cw->updates_full = 0;
3502 if (cw->updates) eina_tiler_clear(cw->updates);
3506 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3507 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3515 e_comp_render_queue();
3521 _e_comp_smart_init(void)
3523 if (_e_comp_smart) return;
3525 static const Evas_Smart_Class sc =
3528 EVAS_SMART_CLASS_VERSION,
3532 _e_comp_smart_resize,
3535 _e_comp_smart_color_set,
3536 _e_comp_smart_clip_set,
3537 _e_comp_smart_clip_unset,
3547 _e_comp_smart = evas_smart_class_new(&sc);
3552 e_comp_object_init(void)
3554 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3555 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3556 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3557 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3561 e_comp_object_shutdown(void)
3567 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3569 API_ENTRY EINA_FALSE;
3570 return !!cw->force_visible;
3572 /////////////////////////////////////////////////////////
3575 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3578 Eina_Bool comp_object;
3580 comp_object = !!evas_object_data_get(obj, "comp_object");
3585 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3587 e_comp_render_queue();
3589 l = evas_object_data_get(obj, "comp_object-to_del");
3590 E_FREE_LIST(l, evas_object_del);
3594 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3596 if (e_comp_util_object_is_above_nocomp(obj) &&
3597 (!evas_object_data_get(obj, "comp_override")))
3599 evas_object_data_set(obj, "comp_override", (void*)1);
3600 e_comp_override_add();
3605 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3607 Eina_Bool ref = EINA_TRUE;
3608 if (evas_object_visible_get(obj))
3612 d = evas_object_data_del(obj, "comp_hiding");
3614 /* currently trying to hide */
3617 /* already visible */
3621 evas_object_show(obj);
3624 evas_object_ref(obj);
3625 evas_object_data_set(obj, "comp_ref", (void*)1);
3627 edje_object_signal_emit(obj, "e,state,visible", "e");
3628 evas_object_data_set(obj, "comp_showing", (void*)1);
3629 if (e_comp_util_object_is_above_nocomp(obj))
3631 evas_object_data_set(obj, "comp_override", (void*)1);
3632 e_comp_override_add();
3637 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3639 if (!evas_object_visible_get(obj)) return;
3640 /* already hiding */
3641 if (evas_object_data_get(obj, "comp_hiding")) return;
3642 if (!evas_object_data_del(obj, "comp_showing"))
3644 evas_object_ref(obj);
3645 evas_object_data_set(obj, "comp_ref", (void*)1);
3647 edje_object_signal_emit(obj, "e,state,hidden", "e");
3648 evas_object_data_set(obj, "comp_hiding", (void*)1);
3650 if (evas_object_data_del(obj, "comp_override"))
3651 e_comp_override_timed_pop();
3655 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3657 if (!e_util_strcmp(emission, "e,action,hide,done"))
3659 if (!evas_object_data_del(obj, "comp_hiding")) return;
3660 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3661 evas_object_hide(obj);
3662 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3665 evas_object_data_del(obj, "comp_showing");
3666 if (evas_object_data_del(obj, "comp_ref"))
3667 evas_object_unref(obj);
3671 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3677 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3681 E_API E_Comp_Object_Hook *
3682 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3684 E_Comp_Object_Hook *ch;
3686 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3687 ch = E_NEW(E_Comp_Object_Hook, 1);
3688 if (!ch) return NULL;
3689 ch->hookpoint = hookpoint;
3691 ch->data = (void*)data;
3692 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3697 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3700 if (_e_comp_object_hooks_walking == 0)
3702 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3706 _e_comp_object_hooks_delete++;
3709 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3710 E_API E_Comp_Object_Intercept_Hook *
3711 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3713 E_Comp_Object_Intercept_Hook *ch;
3715 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3716 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3717 if (!ch) return NULL;
3718 ch->hookpoint = hookpoint;
3720 ch->data = (void*)data;
3721 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3726 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3729 if (_e_comp_object_intercept_hooks_walking == 0)
3731 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3735 _e_comp_object_intercept_hooks_delete++;
3740 e_comp_object_util_add(Evas_Object *obj)
3744 E_Comp_Config *conf = e_comp_config_get();
3745 Eina_Bool skip = EINA_FALSE;
3751 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3753 name = evas_object_name_get(obj);
3754 vis = evas_object_visible_get(obj);
3755 o = edje_object_add(e_comp->evas);
3756 evas_object_data_set(o, "comp_object", (void*)1);
3758 skip = (!strncmp(name, "noshadow", 8));
3760 evas_object_data_set(o, "comp_object_skip", (void*)1);
3762 if (conf->shadow_style)
3764 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3765 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3768 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3769 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3770 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3772 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3774 evas_object_geometry_get(obj, &x, &y, &w, &h);
3775 evas_object_geometry_set(o, x, y, w, h);
3776 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3778 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3780 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3781 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3782 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3783 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3784 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3787 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3789 edje_object_part_swallow(o, "e.swallow.content", obj);
3791 _e_comp_object_event_add(o);
3794 evas_object_show(o);
3799 /* utility functions for deleting objects when their "owner" is deleted */
3801 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3806 EINA_SAFETY_ON_NULL_RETURN(to_del);
3807 l = evas_object_data_get(obj, "comp_object-to_del");
3808 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3809 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3810 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3814 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3819 EINA_SAFETY_ON_NULL_RETURN(to_del);
3820 l = evas_object_data_get(obj, "comp_object-to_del");
3822 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3825 /////////////////////////////////////////////////////////
3827 EINTERN Evas_Object *
3828 e_comp_object_client_add(E_Client *ec)
3833 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3834 if (ec->frame) return NULL;
3835 _e_comp_smart_init();
3836 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3837 cw = evas_object_smart_data_get(o);
3838 if (!cw) return NULL;
3839 evas_object_data_set(o, "E_Client", ec);
3842 evas_object_data_set(o, "comp_object", (void*)1);
3844 _e_comp_object_event_add(o);
3849 /* utility functions for getting client inset */
3851 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3854 if (!cw->client_inset.calc)
3860 if (ax) *ax = x - cw->client_inset.l;
3861 if (ay) *ay = y - cw->client_inset.t;
3865 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3868 if (!cw->client_inset.calc)
3874 if (ax) *ax = x + cw->client_inset.l;
3875 if (ay) *ay = y + cw->client_inset.t;
3879 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3882 if (!cw->client_inset.calc)
3888 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3889 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3893 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3896 if (!cw->client_inset.calc)
3902 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3903 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3907 e_comp_object_client_get(Evas_Object *obj)
3912 /* FIXME: remove this when eo is used */
3913 o = evas_object_data_get(obj, "comp_smart_obj");
3915 return e_comp_object_client_get(o);
3916 return cw ? cw->ec : NULL;
3920 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3923 if (cw->frame_extends)
3924 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3929 if (w) *w = cw->ec->w;
3930 if (h) *h = cw->ec->h;
3935 e_comp_object_util_zone_get(Evas_Object *obj)
3937 E_Zone *zone = NULL;
3941 zone = e_comp_zone_find_by_ec(cw->ec);
3946 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3947 zone = e_comp_zone_xy_get(x, y);
3953 e_comp_object_util_center(Evas_Object *obj)
3955 int x, y, w, h, ow, oh;
3960 zone = e_comp_object_util_zone_get(obj);
3961 EINA_SAFETY_ON_NULL_RETURN(zone);
3962 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3963 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3964 ow = cw->ec->w, oh = cw->ec->h;
3966 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3967 x = x + (w - ow) / 2;
3968 y = y + (h - oh) / 2;
3969 evas_object_move(obj, x, y);
3973 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3975 int x, y, w, h, ow, oh;
3978 EINA_SAFETY_ON_NULL_RETURN(on);
3979 evas_object_geometry_get(on, &x, &y, &w, &h);
3980 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3981 ow = cw->ec->w, oh = cw->ec->h;
3983 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3984 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3988 e_comp_object_util_fullscreen(Evas_Object *obj)
3993 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3996 evas_object_move(obj, 0, 0);
3997 evas_object_resize(obj, e_comp->w, e_comp->h);
4002 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4010 ow = cw->w, oh = cw->h;
4012 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4013 zone = e_comp_object_util_zone_get(obj);
4014 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4015 if (x) *x = zx + (zw - ow) / 2;
4016 if (y) *y = zy + (zh - oh) / 2;
4020 e_comp_object_input_objs_del(Evas_Object *obj)
4023 E_Input_Rect_Data *input_rect_data;
4024 E_Input_Rect_Smart_Data *input_rect_sd;
4029 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4030 if (!input_rect_sd) return;
4032 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4034 if (input_rect_data->obj)
4036 evas_object_smart_member_del(input_rect_data->obj);
4037 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4039 E_FREE(input_rect_data);
4044 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4047 E_Input_Rect_Data *input_rect_data = NULL;
4048 E_Input_Rect_Smart_Data *input_rect_sd;
4049 int client_w, client_h;
4051 if (cw->ec->client.w)
4052 client_w = cw->ec->client.w;
4054 client_w = cw->ec->w;
4056 if (cw->ec->client.h)
4057 client_h = cw->ec->client.h;
4059 client_h = cw->ec->h;
4061 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4065 _e_comp_input_obj_smart_init();
4066 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4067 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4068 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4071 input_rect_sd->cw = cw;
4074 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4077 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4078 if (input_rect_data)
4080 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4081 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4085 if ((input_rect_data) &&
4086 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4088 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4089 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4090 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4091 evas_object_clip_set(input_rect_data->obj, cw->clip);
4092 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4093 evas_object_geometry_set(input_rect_data->obj,
4094 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4095 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4096 evas_object_pass_events_set(cw->default_input_obj, 1);
4097 evas_object_pass_events_set(cw->obj, 1);
4100 evas_object_show(input_rect_data->obj);
4101 evas_object_show(cw->input_obj);
4106 evas_object_smart_member_del(cw->input_obj);
4107 E_FREE_FUNC(cw->input_obj, evas_object_del);
4108 evas_object_pass_events_set(cw->default_input_obj, 0);
4109 evas_object_pass_events_set(cw->obj, 0);
4114 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4117 E_Input_Rect_Smart_Data *input_rect_sd;
4118 E_Input_Rect_Data *input_rect_data;
4121 if (!cw->input_obj) return;
4123 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4126 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4128 *list = eina_list_append(*list, &input_rect_data->rect);
4134 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4137 if (l) *l = cw->client_inset.l;
4138 if (r) *r = cw->client_inset.r;
4139 if (t) *t = cw->client_inset.t;
4140 if (b) *b = cw->client_inset.b;
4143 /* set geometry for CSD */
4145 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4151 if (cw->frame_object)
4152 CRI("ACK! ec:%p", cw->ec);
4153 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4154 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4155 calc = cw->client_inset.calc;
4156 cw->client_inset.calc = l || r || t || b;
4157 eina_stringshare_replace(&cw->frame_theme, "borderless");
4158 if (cw->client_inset.calc)
4160 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4161 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4162 e_client_size_set(cw->ec, tw, th);
4164 else if (cw->ec->maximized || cw->ec->fullscreen)
4166 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4167 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4169 if (!cw->ec->new_client)
4171 if (calc && cw->client_inset.calc)
4173 tx = cw->ec->x - (l - cw->client_inset.l);
4174 ty = cw->ec->y - (t - cw->client_inset.t);
4175 e_client_pos_set(cw->ec, tx, ty);
4177 cw->ec->changes.pos = cw->ec->changes.size = 1;
4180 cw->client_inset.l = l;
4181 cw->client_inset.r = r;
4182 cw->client_inset.t = t;
4183 cw->client_inset.b = b;
4187 e_comp_object_frame_allowed(Evas_Object *obj)
4189 API_ENTRY EINA_FALSE;
4190 return (cw->frame_object || (!cw->client_inset.calc));
4194 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4196 API_ENTRY EINA_FALSE;
4197 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4198 eina_stringshare_replace(&cw->frame_name, name);
4199 if (cw->frame_object)
4200 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4205 e_comp_object_frame_exists(Evas_Object *obj)
4207 API_ENTRY EINA_FALSE;
4208 return !!cw->frame_object;
4212 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4214 Evas_Object *o, *pbg;
4217 Eina_Stringshare *theme;
4219 API_ENTRY EINA_FALSE;
4221 if (!e_util_strcmp(cw->frame_theme, name))
4222 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4223 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4224 return _e_comp_object_shadow_setup(cw);
4225 pbg = cw->frame_object;
4226 theme = eina_stringshare_add(name);
4228 if (cw->frame_object)
4232 w = cw->ec->w, h = cw->ec->h;
4233 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4234 if ((cw->ec->w != w) || (cw->ec->h != h))
4236 cw->ec->changes.size = 1;
4239 E_FREE_FUNC(cw->frame_object, evas_object_del);
4240 if (!name) goto reshadow;
4242 o = edje_object_add(e_comp->evas);
4243 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4244 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4245 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4247 cw->frame_object = NULL;
4249 eina_stringshare_del(cw->frame_theme);
4250 cw->frame_theme = theme;
4255 if (theme != e_config->theme_default_border_style)
4257 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4258 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4262 ok = e_theme_edje_object_set(o, "base/theme/border",
4263 "e/widgets/border/default/border");
4264 if (ok && (theme == e_config->theme_default_border_style))
4266 /* Reset default border style to default */
4267 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4268 e_config_save_queue();
4275 cw->frame_object = o;
4276 eina_stringshare_del(cw->frame_theme);
4277 cw->frame_theme = theme;
4278 evas_object_name_set(o, "cw->frame_object");
4281 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4285 cw->ec->changes.icon = 1;
4291 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4296 _e_comp_object_shadow_setup(cw);
4299 int old_x, old_y, new_x = 0, new_y = 0;
4301 old_x = cw->x, old_y = cw->y;
4303 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4305 new_x = cw->ec->x, new_y = cw->ec->y;
4306 else if (cw->ec->placed || (!cw->ec->new_client))
4308 /* if no previous frame:
4309 * - reapply client_inset
4314 if (cw->ec->changes.size)
4322 zone = e_comp_zone_find_by_ec(cw->ec);
4325 x = cw->ec->client.x, y = cw->ec->client.y;
4326 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4327 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4329 new_x = x, new_y = y;
4332 if (old_x != new_x || old_y != new_y)
4334 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4335 cw->y = cw->x = -99999;
4336 evas_object_move(obj, new_x, new_y);
4340 if (cw->ec->maximized)
4342 cw->ec->changes.need_maximize = 1;
4345 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4346 if (cw->frame_object)
4348 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4351 cw->frame_extends = 0;
4352 evas_object_del(pbg);
4357 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4359 E_Comp_Object_Mover *prov;
4362 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4363 edje_object_signal_emit(cw->shobj, sig, src);
4364 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4365 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4366 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4368 /* start with highest priority callback first */
4369 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4371 if (!e_util_glob_match(sig, prov->sig)) continue;
4372 if (prov->func(prov->data, obj, sig)) break;
4377 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4379 /* FIXME: at some point I guess this should use eo to inherit
4380 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4381 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4384 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4388 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4391 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4395 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4398 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4402 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4405 Eina_Rectangle rect;
4408 if (cw->ec->input_only || (!cw->updates)) return;
4409 if (cw->nocomp) return;
4410 rect.x = x, rect.y = y;
4411 rect.w = w, rect.h = h;
4412 evas_object_smart_callback_call(obj, "damage", &rect);
4414 if (e_comp_is_on_overlay(cw->ec))
4416 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4417 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4418 * E module attempts to block screen update due to the particular policy.
4420 if (e_pixmap_resource_get(cw->ec->pixmap))
4421 cw->hwc_need_update = EINA_TRUE;
4424 /* ignore overdraw */
4425 if (cw->updates_full)
4427 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4428 e_comp_object_render_update_add(obj);
4430 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4431 evas_object_show(cw->smart_obj);
4435 /* clip rect to client surface */
4436 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4437 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4438 /* if rect is the total size of the client after clip, clear the updates
4439 * since this is guaranteed to be the whole region anyway
4441 eina_tiler_area_size_get(cw->updates, &tw, &th);
4442 if ((w > tw) || (h > th))
4444 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4445 eina_tiler_clear(cw->updates);
4446 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4448 tw = cw->ec->client.w, th = cw->ec->client.h;
4450 if ((!x) && (!y) && (w == tw) && (h == th))
4452 eina_tiler_clear(cw->updates);
4453 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4454 cw->updates_full = 1;
4455 cw->update_count = 0;
4458 if (cw->update_count > UPDATE_MAX)
4460 /* this is going to get really dumb, so just update the whole thing */
4461 eina_tiler_clear(cw->updates);
4462 cw->update_count = cw->updates_full = 1;
4463 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4464 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4468 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4469 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4471 cw->updates_exist = 1;
4472 e_comp_object_render_update_add(obj);
4474 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4475 evas_object_show(cw->smart_obj);
4479 e_comp_object_damage_exists(Evas_Object *obj)
4481 API_ENTRY EINA_FALSE;
4482 return cw->updates_exist;
4486 e_comp_object_render_update_add(Evas_Object *obj)
4490 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4491 if (cw->render_update_lock.lock) return;
4492 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4496 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4498 e_comp_render_queue();
4502 e_comp_object_render_update_del(Evas_Object *obj)
4506 if (cw->ec->input_only || (!cw->updates)) return;
4507 if (!cw->update) return;
4509 /* this gets called during comp animating to clear the update flag */
4510 if (e_comp->grabbed) return;
4511 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4512 if (!e_comp->updates)
4514 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4515 if (e_comp->render_animator)
4516 ecore_animator_freeze(e_comp->render_animator);
4521 e_comp_object_shape_apply(Evas_Object *obj)
4525 unsigned int i, *pix, *p;
4529 if (!cw->ec) return; //NYI
4530 if (cw->external_content) return;
4533 if ((cw->ec->shape_rects_num >= 1) &&
4534 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4539 ERR("BUGGER: shape with native surface? cw=%p", cw);
4542 evas_object_image_size_get(cw->obj, &w, &h);
4543 if ((w < 1) || (h < 1)) return;
4546 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4547 _e_comp_object_alpha_set(cw);
4548 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4549 evas_object_image_alpha_set(o, 1);
4551 p = pix = evas_object_image_data_get(cw->obj, 1);
4554 evas_object_image_data_set(cw->obj, pix);
4559 unsigned char *spix, *sp;
4561 spix = calloc(w * h, sizeof(unsigned char));
4563 for (i = 0; i < cw->ec->shape_rects_num; i++)
4567 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4568 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4569 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4570 sp = spix + (w * ry) + rx;
4571 for (py = 0; py < rh; py++)
4573 for (px = 0; px < rw; px++)
4581 for (py = 0; py < h; py++)
4583 for (px = 0; px < w; px++)
4585 unsigned int mask, imask;
4587 mask = ((unsigned int)(*sp)) << 24;
4589 imask |= imask >> 8;
4590 imask |= imask >> 8;
4591 *p = mask | (*p & imask);
4592 //if (*sp) *p = 0xff000000 | *p;
4593 //else *p = 0x00000000;
4602 for (py = 0; py < h; py++)
4604 for (px = 0; px < w; px++)
4608 evas_object_image_data_set(cw->obj, pix);
4609 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4610 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4612 evas_object_image_data_set(o, pix);
4613 evas_object_image_data_update_add(o, 0, 0, w, h);
4615 // don't need to fix alpha chanel as blending
4616 // should be totally off here regardless of
4617 // alpha channel content
4621 _e_comp_object_clear(E_Comp_Object *cw)
4626 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4628 if (cw->render_update_lock.lock) return;
4631 e_pixmap_clear(cw->ec->pixmap);
4633 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4634 evas_object_image_size_set(cw->obj, 1, 1);
4635 evas_object_image_data_set(cw->obj, NULL);
4636 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4638 evas_object_image_size_set(o, 1, 1);
4639 evas_object_image_data_set(o, NULL);
4642 e_comp_object_render_update_del(cw->smart_obj);
4646 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4650 API_ENTRY EINA_FALSE;
4652 if (cw->transparent.set == set)
4657 evas_object_color_get(obj, &r, &g, &b, &a);
4659 cw->transparent.user_r = r;
4660 cw->transparent.user_g = g;
4661 cw->transparent.user_b = b;
4662 cw->transparent.user_a = a;
4664 cw->transparent.setting = EINA_TRUE;
4665 evas_object_color_set(obj, 0, 0, 0, 0);
4666 cw->transparent.setting = EINA_FALSE;
4668 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4670 cw->transparent.user_r,
4671 cw->transparent.user_g,
4672 cw->transparent.user_b,
4673 cw->transparent.user_a);
4675 cw->transparent.set = EINA_TRUE;
4679 cw->transparent.set = EINA_FALSE;
4681 evas_object_color_set(obj,
4682 cw->transparent.user_r,
4683 cw->transparent.user_g,
4684 cw->transparent.user_b,
4685 cw->transparent.user_a);
4687 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4689 cw->transparent.user_r,
4690 cw->transparent.user_g,
4691 cw->transparent.user_b,
4692 cw->transparent.user_a);
4698 /* helper function to simplify toggling of redirection for display servers which support it */
4700 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4705 if (cw->redirected == set) return;
4706 cw->redirected = set;
4707 if (cw->external_content) return;
4709 e_comp_object_map_update(obj);
4713 if (cw->updates_exist)
4714 e_comp_object_render_update_add(obj);
4716 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4718 _e_comp_object_transparent_set(obj, EINA_FALSE);
4719 evas_object_smart_callback_call(obj, "redirected", NULL);
4723 _e_comp_object_clear(cw);
4724 _e_comp_object_transparent_set(obj, EINA_TRUE);
4725 evas_object_smart_callback_call(obj, "unredirected", NULL);
4730 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4733 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4735 if (cw->buffer_destroy_listener.notify)
4737 cw->buffer_destroy_listener.notify = NULL;
4738 wl_list_remove(&cw->buffer_destroy_listener.link);
4741 if (e_object_is_del(E_OBJECT(cw->ec)))
4743 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4748 /* if it's current displaying buffer, do not remove its content */
4749 if (!evas_object_visible_get(cw->ec->frame))
4750 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4755 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4760 if (cw->buffer_destroy_listener.notify)
4762 wl_list_remove(&cw->buffer_destroy_listener.link);
4763 cw->buffer_destroy_listener.notify = NULL;
4766 if (cw->tbm_surface)
4768 tbm_surface_internal_unref(cw->tbm_surface);
4769 cw->tbm_surface = NULL;
4774 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4776 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4777 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4779 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4781 tbm_surface_internal_ref(ns->data.tbm.buffer);
4782 cw->tbm_surface = ns->data.tbm.buffer;
4786 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4787 evas_object_image_native_surface_set(cw->obj, ns);
4791 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4793 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4794 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4795 evas_object_image_native_surface_set(o, ns);
4802 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4804 Evas_Native_Surface ns;
4807 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4808 if (cw->ec->input_only) return;
4809 if (cw->external_content) return;
4810 if (cw->render_update_lock.lock) return;
4813 memset(&ns, 0, sizeof(Evas_Native_Surface));
4817 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4818 set = (!cw->ec->shaped);
4820 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4824 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4828 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4831 if (cw->ec->input_only) return;
4834 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4835 _e_comp_object_alpha_set(cw);
4837 e_comp_object_native_surface_set(obj, cw->native);
4838 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4842 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4848 if (cw->blanked == set) return;
4850 _e_comp_object_alpha_set(cw);
4853 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4854 evas_object_image_data_set(cw->obj, NULL);
4858 e_comp_object_native_surface_set(obj, 1);
4859 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4863 _e_comp_object_damage_trace_rect_set(Evas_Object *obj, Eina_Rectangle *origin, int dmg_x, int dmg_y, int dmg_w, int dmg_h)
4868 if (!_damage_trace) return;
4872 if (!evas_object_visible_get(cw->obj)) return;
4874 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4876 o = evas_object_rectangle_add(e_comp->evas);
4877 evas_object_layer_set(o, E_LAYER_MAX);
4878 evas_object_name_set(o, "damage_trace");
4879 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4880 evas_object_resize(o, dmg_w, dmg_h);
4881 evas_object_color_set(o, 0, 128, 0, 128);
4882 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4883 evas_object_pass_events_set(o, EINA_TRUE);
4884 evas_object_show(o);
4886 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4888 dmg_w, dmg_h, dmg_x, dmg_y,
4889 origin->w, origin->h, origin->x, origin->y);
4891 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4894 /* mark an object as dirty and setup damages */
4896 e_comp_object_dirty(Evas_Object *obj)
4899 Eina_Rectangle *rect;
4903 Eina_Bool dirty, visible;
4907 if (cw->external_content) return;
4908 if (!cw->redirected) return;
4909 if (cw->render_update_lock.lock)
4911 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4914 /* only actually dirty if pixmap is available */
4915 if (!e_pixmap_resource_get(cw->ec->pixmap))
4917 // e_pixmap_size_get returns last attached buffer size
4918 // eventhough it is destroyed
4919 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4922 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4923 visible = cw->visible;
4924 if (!dirty) w = h = 1;
4925 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4927 evas_object_image_data_set(cw->obj, NULL);
4928 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4929 evas_object_image_size_set(cw->obj, tw, th);
4930 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4931 if (cw->pending_updates)
4932 eina_tiler_area_size_set(cw->pending_updates, w, h);
4933 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4935 evas_object_image_pixels_dirty_set(o, dirty);
4937 evas_object_image_data_set(o, NULL);
4938 evas_object_image_size_set(o, tw, th);
4939 visible |= evas_object_visible_get(o);
4943 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4947 e_comp_object_native_surface_set(obj, 1);
4949 m = _e_comp_object_map_damage_transform_get(cw->ec);
4950 it = eina_tiler_iterator_new(cw->updates);
4951 EINA_ITERATOR_FOREACH(it, rect)
4953 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4954 * of evas engine and doesn't convert damage according to evas_map.
4955 * so damage of evas_object_image use surface coordinate.
4959 int damage_x, damage_y, damage_w, damage_h;
4961 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4962 &damage_x, &damage_y, &damage_w, &damage_h);
4963 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4964 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4968 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4969 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4972 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4973 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4974 if (cw->pending_updates)
4975 eina_tiler_rect_add(cw->pending_updates, rect);
4977 eina_iterator_free(it);
4978 if (m) e_map_free(m);
4979 if (cw->pending_updates)
4980 eina_tiler_clear(cw->updates);
4983 cw->pending_updates = cw->updates;
4984 cw->updates = eina_tiler_new(w, h);
4985 eina_tiler_tile_size_set(cw->updates, 1, 1);
4987 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4988 evas_object_smart_callback_call(obj, "dirty", NULL);
4989 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4990 /* force render if main object is hidden but mirrors are visible */
4991 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4992 e_comp_object_render(obj);
4996 e_comp_object_render(Evas_Object *obj)
5003 API_ENTRY EINA_FALSE;
5005 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5006 if (cw->ec->input_only) return EINA_TRUE;
5007 if (cw->external_content) return EINA_TRUE;
5008 if (cw->native) return EINA_FALSE;
5009 /* if comp object is not redirected state, comp object should not be set by newly committed data
5010 because image size of comp object is 1x1 and it should not be shown on canvas */
5011 if (!cw->redirected) return EINA_TRUE;
5012 if (cw->render_update_lock.lock)
5014 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5017 e_comp_object_render_update_del(obj);
5018 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5020 if (!cw->pending_updates)
5022 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5023 evas_object_image_data_set(cw->obj, NULL);
5024 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5025 evas_object_image_data_set(o, NULL);
5029 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5031 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5033 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5036 e_pixmap_image_refresh(cw->ec->pixmap);
5037 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5040 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5041 e_pixmap_image_data_ref(cw->ec->pixmap);
5043 /* set pixel data */
5044 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5045 _e_comp_object_alpha_set(cw);
5046 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5048 evas_object_image_data_set(o, pix);
5049 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5050 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5053 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5055 e_comp_client_post_update_add(cw->ec);
5060 /* create a duplicate of an evas object */
5062 e_comp_object_util_mirror_add(Evas_Object *obj)
5066 unsigned int *pix = NULL;
5067 Eina_Bool argb = EINA_FALSE;
5072 cw = evas_object_data_get(obj, "comp_mirror");
5075 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5076 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5077 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5078 evas_object_image_alpha_set(o, 1);
5079 evas_object_image_source_set(o, obj);
5082 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5083 if (cw->external_content)
5085 ERR("%p of client %p is external content.", obj, cw->ec);
5088 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5089 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5090 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5091 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5092 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5093 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5094 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5095 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5096 evas_object_data_set(o, "comp_mirror", cw);
5098 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5099 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5101 evas_object_image_size_set(o, tw, th);
5104 pix = evas_object_image_data_get(cw->obj, 0);
5110 evas_object_image_native_surface_set(o, cw->ns);
5113 Evas_Native_Surface ns;
5114 memset(&ns, 0, sizeof(Evas_Native_Surface));
5115 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5116 evas_object_image_native_surface_set(o, &ns);
5121 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5122 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5124 (e_pixmap_image_exists(cw->ec->pixmap)))
5125 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5127 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5134 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5135 evas_object_image_pixels_dirty_set(o, dirty);
5136 evas_object_image_data_set(o, pix);
5137 evas_object_image_data_set(cw->obj, pix);
5139 evas_object_image_data_update_add(o, 0, 0, tw, th);
5144 //////////////////////////////////////////////////////
5147 e_comp_object_effect_allowed_get(Evas_Object *obj)
5149 API_ENTRY EINA_FALSE;
5151 if (!cw->shobj) return EINA_FALSE;
5152 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5153 return !e_comp_config_get()->match.disable_borders;
5156 /* setup an api effect for a client */
5158 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5161 Eina_Stringshare *grp;
5162 E_Comp_Config *config;
5163 Eina_Bool loaded = EINA_FALSE;
5165 API_ENTRY EINA_FALSE;
5166 if (!cw->shobj) return EINA_FALSE; //input window
5168 if (!effect) effect = "none";
5169 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5171 config = e_comp_config_get();
5172 if ((config) && (config->effect_file))
5174 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5176 cw->effect_set = EINA_TRUE;
5183 edje_object_file_get(cw->effect_obj, NULL, &grp);
5184 cw->effect_set = !eina_streq(effect, "none");
5185 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5186 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5188 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5189 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5190 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5192 if (cw->effect_running)
5194 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5197 cw->effect_set = EINA_FALSE;
5198 return cw->effect_set;
5202 if (cw->effect_running)
5204 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5207 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5208 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5209 if (cw->effect_clip)
5211 evas_object_clip_unset(cw->clip);
5212 cw->effect_clip = 0;
5214 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5216 _e_comp_object_dim_update(cw);
5218 return cw->effect_set;
5221 /* set params for embryo scripts in effect */
5223 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5225 Edje_Message_Int_Set *msg;
5229 EINA_SAFETY_ON_NULL_RETURN(params);
5230 EINA_SAFETY_ON_FALSE_RETURN(count);
5231 if (!cw->effect_set) return;
5233 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5234 msg->count = (int)count;
5235 for (x = 0; x < count; x++)
5236 msg->val[x] = params[x];
5237 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5238 edje_object_message_signal_process(cw->effect_obj);
5242 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5244 Edje_Signal_Cb end_cb;
5246 E_Comp_Object *cw = data;
5248 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5249 cw->effect_running = 0;
5250 if (!_e_comp_object_animating_end(cw)) return;
5252 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5254 evas_object_data_del(cw->smart_obj, "effect_running");
5255 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5256 e_comp_visibility_calculation_set(EINA_TRUE);
5259 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5260 if (!end_cb) return;
5261 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5262 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5263 end_cb(end_data, cw->smart_obj, emission, source);
5266 /* clip effect to client's zone */
5268 e_comp_object_effect_clip(Evas_Object *obj)
5272 zone = e_comp_zone_find_by_ec(cw->ec);
5274 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5275 if (!cw->effect_clip_able) return;
5276 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5277 cw->effect_clip = 1;
5280 /* unclip effect from client's zone */
5282 e_comp_object_effect_unclip(Evas_Object *obj)
5285 if (!cw->effect_clip) return;
5286 evas_object_clip_unset(cw->smart_obj);
5287 cw->effect_clip = 0;
5290 /* start effect, running end_cb after */
5292 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5294 API_ENTRY EINA_FALSE;
5295 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5296 if (!cw->effect_set) return EINA_FALSE;
5298 if (cw->effect_running)
5300 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5303 e_comp_object_effect_clip(obj);
5304 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5306 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5307 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5308 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5309 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5311 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5312 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5314 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5315 _e_comp_object_animating_begin(cw);
5316 cw->effect_running = 1;
5320 /* stop a currently-running effect immediately */
5322 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5325 Edje_Signal_Cb end_cb_before = NULL;
5326 void *end_data_before = NULL;
5327 API_ENTRY EINA_FALSE;
5329 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5330 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5332 if (end_cb_before != end_cb) return EINA_TRUE;
5333 e_comp_object_effect_unclip(obj);
5334 if (cw->effect_clip)
5336 evas_object_clip_unset(cw->effect_obj);
5337 cw->effect_clip = 0;
5339 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5340 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5342 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5344 evas_object_data_del(cw->smart_obj, "effect_running");
5345 e_comp_visibility_calculation_set(EINA_TRUE);
5348 cw->effect_running = 0;
5349 ret = _e_comp_object_animating_end(cw);
5351 if ((ret) && (end_cb_before))
5353 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5354 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5361 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5363 return a->pri - b->pri;
5366 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5367 E_API E_Comp_Object_Mover *
5368 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5370 E_Comp_Object_Mover *prov;
5372 prov = E_NEW(E_Comp_Object_Mover, 1);
5373 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5374 prov->func = provider;
5375 prov->data = (void*)data;
5378 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5379 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5384 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5386 EINA_SAFETY_ON_NULL_RETURN(prov);
5387 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5392 e_comp_object_effect_object_get(Evas_Object *obj)
5396 return cw->effect_obj;
5400 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5402 API_ENTRY EINA_FALSE;
5403 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5404 if (!cw->effect_set) return EINA_FALSE;
5411 ////////////////////////////////////
5414 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5416 if (e_comp->autoclose.obj)
5418 e_comp_ungrab_input(0, 1);
5419 if (e_comp->autoclose.del_cb)
5420 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5421 else if (!already_del)
5423 evas_object_hide(e_comp->autoclose.obj);
5424 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5426 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5428 e_comp->autoclose.obj = NULL;
5429 e_comp->autoclose.data = NULL;
5430 e_comp->autoclose.del_cb = NULL;
5431 e_comp->autoclose.key_cb = NULL;
5432 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5436 _e_comp_object_autoclose_mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
5438 _e_comp_object_autoclose_cleanup(0);
5442 _e_comp_object_autoclose_setup(Evas_Object *obj)
5444 if (!e_comp->autoclose.rect)
5446 /* create rect just below autoclose object to catch mouse events */
5447 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5448 evas_object_move(e_comp->autoclose.rect, 0, 0);
5449 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5450 evas_object_show(e_comp->autoclose.rect);
5451 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5452 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5453 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5454 e_comp_grab_input(0, 1);
5456 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5457 evas_object_focus_set(obj, 1);
5461 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5463 _e_comp_object_autoclose_setup(obj);
5464 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5468 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5470 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5471 _e_comp_object_autoclose_cleanup(1);
5472 if (e_client_focused_get()) return;
5474 E_Zone *zone = e_zone_current_get();
5477 e_zone_focus_reset(zone);
5481 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5485 if (e_comp->autoclose.obj)
5487 if (e_comp->autoclose.obj == obj) return;
5488 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5489 e_comp->autoclose.obj = obj;
5490 e_comp->autoclose.del_cb = del_cb;
5491 e_comp->autoclose.key_cb = cb;
5492 e_comp->autoclose.data = (void*)data;
5493 if (evas_object_visible_get(obj))
5494 _e_comp_object_autoclose_setup(obj);
5496 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5497 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5500 e_comp->autoclose.obj = obj;
5501 e_comp->autoclose.del_cb = del_cb;
5502 e_comp->autoclose.key_cb = cb;
5503 e_comp->autoclose.data = (void*)data;
5504 if (evas_object_visible_get(obj))
5505 _e_comp_object_autoclose_setup(obj);
5507 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5508 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5512 e_comp_object_is_animating(Evas_Object *obj)
5516 return cw->animating;
5520 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5524 if ((cw->external_content) &&
5525 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5527 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5528 "But current external content is %d object for %p.",
5529 cw->content_type, cw->ec);
5533 cw->user_alpha_set = EINA_TRUE;
5534 cw->user_alpha = alpha;
5536 if (!cw->obj) return;
5538 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5540 evas_object_image_alpha_set(cw->obj, alpha);
5542 if ((!cw->native) && (!cw->external_content))
5543 evas_object_image_data_set(cw->obj, NULL);
5547 e_comp_object_alpha_get(Evas_Object *obj)
5549 API_ENTRY EINA_FALSE;
5551 return evas_object_image_alpha_get(cw->obj);
5555 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5557 Eina_Bool mask_set = EINA_FALSE;
5561 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5562 if (cw->ec->input_only) return;
5569 o = evas_object_rectangle_add(e_comp->evas);
5570 evas_object_color_set(o, 0, 0, 0, 0);
5571 evas_object_clip_set(o, cw->clip);
5572 evas_object_smart_member_add(o, obj);
5573 evas_object_move(o, 0, 0);
5574 evas_object_resize(o, cw->w, cw->h);
5575 /* save render op value to restore when clear a mask.
5577 * NOTE: DO NOT change the render op on ec->frame while mask object
5578 * is set. it will overwrite the changed op value. */
5579 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5580 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5581 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5582 if (cw->visible) evas_object_show(o);
5585 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5586 ELOGF("COMP", " |mask_obj", cw->ec);
5587 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5594 evas_object_smart_member_del(cw->mask.obj);
5595 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5597 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5598 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5604 e_comp_object_mask_has(Evas_Object *obj)
5606 API_ENTRY EINA_FALSE;
5608 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5612 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5617 if ((cw->external_content) &&
5618 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5620 WRN("Can set up size to ONLY evas \"image\" object. "
5621 "But current external content is %d object for %p.",
5622 cw->content_type, cw->ec);
5626 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5628 evas_object_image_size_set(cw->obj, tw, th);
5632 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5634 Eina_Bool transform_set = EINA_FALSE;
5636 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5637 if (cw->ec->input_only) return;
5639 transform_set = !!set;
5643 if (!cw->transform_bg_obj)
5645 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5646 evas_object_move(o, 0, 0);
5647 evas_object_resize(o, 1, 1);
5648 if (cw->transform_bg_color.a >= 255)
5649 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5651 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5652 evas_object_color_set(o,
5653 cw->transform_bg_color.r,
5654 cw->transform_bg_color.g,
5655 cw->transform_bg_color.b,
5656 cw->transform_bg_color.a);
5657 if (cw->visible) evas_object_show(o);
5659 cw->transform_bg_obj = o;
5660 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5662 #ifdef REFACTOR_DESK_AREA
5663 e_comp_object_transform_obj_stack_update(obj);
5665 _e_comp_object_transform_obj_stack_update(obj);
5670 if (cw->transform_bg_obj)
5672 evas_object_smart_member_del(cw->transform_bg_obj);
5673 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5679 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5683 cw->transform_bg_color.r = r;
5684 cw->transform_bg_color.g = g;
5685 cw->transform_bg_color.b = b;
5686 cw->transform_bg_color.a = a;
5688 if (cw->transform_bg_obj)
5690 evas_object_color_set(cw->transform_bg_obj,
5691 cw->transform_bg_color.r,
5692 cw->transform_bg_color.g,
5693 cw->transform_bg_color.b,
5694 cw->transform_bg_color.a);
5699 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5702 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5703 if (cw->ec->input_only) return;
5704 if (!cw->transform_bg_obj) return;
5706 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5710 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5713 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5714 if (cw->ec->input_only) return;
5715 if (!cw->transform_bg_obj) return;
5717 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5721 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5723 Eina_Bool transform_set = EINA_FALSE;
5725 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5726 if (cw->ec->input_only) return;
5728 transform_set = !!set;
5732 if (!cw->transform_tranp_obj)
5734 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5735 evas_object_move(o, 0, 0);
5736 evas_object_resize(o, 1, 1);
5737 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5738 evas_object_color_set(o, 0, 0, 0, 0);
5739 if (cw->visible) evas_object_show(o);
5741 cw->transform_tranp_obj = o;
5742 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5743 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5744 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5746 #ifdef REFACTOR_DESK_AREA
5747 e_comp_object_transform_obj_stack_update(obj);
5749 _e_comp_object_transform_obj_stack_update(obj);
5754 if (cw->transform_tranp_obj)
5756 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5757 evas_object_smart_member_del(cw->transform_tranp_obj);
5758 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5764 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5767 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5768 if (cw->ec->input_only) return;
5769 if (!cw->transform_tranp_obj) return;
5771 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5775 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5778 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5779 if (cw->ec->input_only) return;
5780 if (!cw->transform_tranp_obj) return;
5782 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5785 #ifdef REFACTOR_DESK_AREA
5788 e_comp_object_layer_update(Evas_Object *obj,
5789 Evas_Object *above, Evas_Object *below)
5791 E_Comp_Object *cw2 = NULL;
5792 Evas_Object *o = NULL;
5797 if (cw->ec->layer_block) return;
5798 if ((above) && (below))
5800 ERR("Invalid layer update request! cw=%p", cw);
5808 layer = evas_object_layer_get(o);
5809 cw2 = evas_object_data_get(o, "comp_obj");
5812 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5814 o = evas_object_above_get(o);
5815 if ((!o) || (o == cw->smart_obj)) break;
5816 if (evas_object_layer_get(o) != layer)
5818 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5823 ec = e_client_top_get();
5824 if (ec) o = ec->frame;
5827 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5831 _e_comp_object_layers_remove(cw);
5834 if (cw2->layer > cw->layer)
5835 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5836 else if (cw2->layer == cw->layer)
5839 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5841 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5843 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5846 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5849 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5854 e_comp_object_layer_get(Evas_Object *obj)
5861 e_comp_object_content_set(Evas_Object *obj,
5862 Evas_Object *content,
5863 E_Comp_Object_Content_Type type)
5865 API_ENTRY EINA_FALSE;
5867 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5868 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5869 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5873 ERR("Can't set e.swallow.content to requested content. "
5874 "Previous comp object should not be changed at all.");
5878 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5880 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5881 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5883 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5884 type, content, cw->ec, cw->ec->pixmap);
5888 cw->external_content = EINA_TRUE;
5891 cw->content_type = type;
5892 e_util_size_debug_set(cw->obj, 1);
5893 evas_object_name_set(cw->obj, "cw->obj");
5894 _e_comp_object_alpha_set(cw);
5897 _e_comp_object_shadow_setup(cw);
5899 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5905 e_comp_object_content_unset(Evas_Object *obj)
5907 API_ENTRY EINA_FALSE;
5909 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5910 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5912 if (!cw->obj && !cw->ec->visible)
5914 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5918 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5920 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5926 if (cw->frame_object)
5927 edje_object_part_unswallow(cw->frame_object, cw->obj);
5929 edje_object_part_unswallow(cw->shobj, cw->obj);
5931 evas_object_del(cw->obj);
5932 evas_object_hide(cw->obj);
5936 cw->external_content = EINA_FALSE;
5937 if (cw->ec->is_cursor)
5940 DBG("%p is cursor surface..", cw->ec);
5941 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5943 evas_object_resize(cw->ec->frame, pw, ph);
5944 evas_object_hide(cw->ec->frame);
5949 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5950 cw->obj = evas_object_image_filled_add(e_comp->evas);
5951 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5952 e_util_size_debug_set(cw->obj, 1);
5953 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5954 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5955 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5956 evas_object_name_set(cw->obj, "cw->obj");
5957 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5958 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_obj_color_set, cw);
5959 _e_comp_object_alpha_set(cw);
5962 _e_comp_object_shadow_setup(cw);
5967 _e_comp_intercept_show_helper(cw);
5971 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5972 e_comp_object_dirty(cw->smart_obj);
5973 e_comp_object_render(cw->smart_obj);
5974 e_comp_object_render_update_add(obj);
5976 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5981 EINTERN Evas_Object *
5982 e_comp_object_content_get(Evas_Object *obj)
5986 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5988 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5990 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5997 E_API E_Comp_Object_Content_Type
5998 e_comp_object_content_type_get(Evas_Object *obj)
6000 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
6002 return cw->content_type;
6006 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
6009 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6010 E_Comp_Config *conf = e_comp_config_get();
6011 if (cw->ec->input_only) return;
6012 if (!conf->dim_rect_enable) return;
6014 cw->dim.mask_set = mask_set;
6020 if (!cw->dim.enable) return;
6021 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6025 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6027 Eina_Bool mask_set = EINA_FALSE;
6031 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6032 E_Comp_Config *conf = e_comp_config_get();
6033 if (cw->ec->input_only) return;
6034 if (!conf->dim_rect_enable) return;
6040 if (cw->dim.mask_obj)
6042 evas_object_smart_member_del(cw->dim.mask_obj);
6043 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6046 ELOGF("COMP", "DIM |Mask applied on Dim rect mask_rect[%d %d %d %d]", cw->ec, cw->dim.mask_x, cw->dim.mask_y, cw->dim.mask_w, cw->dim.mask_h);
6047 o = evas_object_rectangle_add(e_comp->evas);
6048 evas_object_color_set(o, 0, 0, 0, 0);
6049 evas_object_smart_member_add(o, obj);
6050 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6051 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6053 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6054 if (cw->visible) evas_object_show(o);
6056 cw->dim.mask_obj = o;
6057 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6059 evas_object_layer_set(cw->dim.mask_obj, 9998);
6063 if (cw->dim.mask_obj)
6065 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6066 evas_object_smart_member_del(cw->dim.mask_obj);
6067 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6073 e_comp_object_dim_client_set(E_Client *ec)
6075 E_Comp_Config *conf = e_comp_config_get();
6077 if (!conf->dim_rect_enable) return ;
6078 if (dim_client == ec) return;
6080 Eina_Bool prev_dim = EINA_FALSE;
6081 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6083 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6084 prev_dim = EINA_TRUE;
6086 if (prev_dim && dim_client->visible && ec)
6088 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6089 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6093 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6094 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6100 e_comp_object_dim_client_get(void)
6102 E_Comp_Config *conf = e_comp_config_get();
6104 if (!conf->dim_rect_enable ) return NULL;
6110 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6113 char emit[32] = "\0";
6114 E_Comp_Config *conf = e_comp_config_get();
6117 if (!conf->dim_rect_enable) return;
6118 if (!cw->effect_obj) return;
6119 if (enable == cw->dim.enable) return;
6121 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6122 if (noeffect || !conf->dim_rect_effect)
6124 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6128 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6131 cw->dim.enable = enable;
6133 if (cw->dim.mask_set && !enable)
6135 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6136 edje_object_signal_emit(cw->effect_obj, emit, "e");
6138 else if (cw->dim.mask_set && enable)
6140 edje_object_signal_emit(cw->effect_obj, emit, "e");
6141 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6145 edje_object_signal_emit(cw->effect_obj, emit, "e");
6150 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6152 API_ENTRY EINA_FALSE;
6153 E_Comp_Config *conf = e_comp_config_get();
6155 if (!ec) return EINA_FALSE;
6156 if (!conf->dim_rect_enable) return EINA_FALSE;
6158 if (cw->dim.enable) return EINA_TRUE;
6164 _e_comp_object_dim_update(E_Comp_Object *cw)
6166 E_Comp_Config *conf = e_comp_config_get();
6169 if (!conf->dim_rect_enable) return;
6170 if (!cw->effect_obj) return;
6173 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6174 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6176 if (cw->dim.mask_set)
6178 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6184 e_comp_object_clear(Evas_Object *obj)
6188 _e_comp_object_clear(cw);
6192 e_comp_object_hwc_update_exists(Evas_Object *obj)
6194 API_ENTRY EINA_FALSE;
6195 return cw->hwc_need_update;
6200 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6203 cw->hwc_need_update = set;
6207 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6209 API_ENTRY EINA_FALSE;
6210 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6214 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6217 if (cw->indicator.obj != indicator)
6218 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6219 cw->indicator.obj = indicator;
6220 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6224 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6227 if (cw->indicator.obj != indicator) return;
6228 cw->indicator.obj = NULL;
6229 edje_object_part_unswallow(cw->shobj, indicator);
6233 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6236 Edje_Message_Int_Set *msg;
6238 if (!cw->indicator.obj) return;
6240 cw->indicator.w = w;
6241 cw->indicator.h = h;
6243 if (!cw->shobj) return;
6245 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6249 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6250 edje_object_message_signal_process(cw->shobj);
6253 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6255 e_comp_object_map_update(Evas_Object *obj)
6258 E_Client *ec = cw->ec;
6259 E_Comp_Wl_Client_Data *cdata;
6261 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6264 int l, remain = sizeof buffer;
6267 if (e_object_is_del(E_OBJECT(ec))) return;
6268 cdata = e_client_cdata_get(ec);
6271 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6272 * when new buffer is attached.
6274 if (!cdata->buffer_ref.buffer) return;
6276 if ((!cw->redirected) ||
6277 (e_client_video_hw_composition_check(ec)) ||
6278 (!e_comp_wl_output_buffer_transform_get(ec) &&
6279 cdata->scaler.buffer_viewport.buffer.scale == 1))
6281 if (evas_object_map_enable_get(cw->effect_obj))
6283 ELOGF("TRANSFORM", "map: disable", cw->ec);
6284 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6285 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6286 evas_object_resize(cw->effect_obj, tw, th);
6293 EINA_SAFETY_ON_NULL_RETURN(map);
6295 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6301 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6303 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6304 e_map_point_image_uv_set(map, 0, x, y);
6305 l = snprintf(p, remain, "%d,%d", x, y);
6306 p += l, remain -= l;
6308 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6309 e_map_point_image_uv_set(map, 1, x, y);
6310 l = snprintf(p, remain, " %d,%d", x, y);
6311 p += l, remain -= l;
6313 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6314 e_map_point_image_uv_set(map, 2, x, y);
6315 l = snprintf(p, remain, " %d,%d", x, y);
6316 p += l, remain -= l;
6318 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6319 e_map_point_image_uv_set(map, 3, x, y);
6320 l = snprintf(p, remain, " %d,%d", x, y);
6321 p += l, remain -= l;
6323 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6325 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6327 e_comp_object_map_set(cw->effect_obj, map);
6328 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6332 /* if there's screen rotation with comp mode, then ec->effect_obj and
6333 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6335 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6336 evas_object_resize(cw->effect_obj, tw, th);
6340 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6342 API_ENTRY EINA_FALSE;
6344 cw->render_trace = set;
6350 e_comp_object_native_usable_get(Evas_Object *obj)
6352 API_ENTRY EINA_FALSE;
6353 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6355 if (cw->ec->input_only) return EINA_FALSE;
6356 if (cw->external_content) return EINA_FALSE;
6357 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6359 /* just return true value, if it is normal case */
6360 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6363 Evas_Native_Surface *ns;
6364 ns = evas_object_image_native_surface_get(cw->obj);
6366 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6369 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6377 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6379 API_ENTRY EINA_FALSE;
6380 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6381 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6382 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6384 if (cw->image_filter == filter) return EINA_TRUE;
6388 case E_COMP_IMAGE_FILTER_BLUR:
6389 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6391 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6392 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6394 case E_COMP_IMAGE_FILTER_INVERSE:
6395 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6397 case E_COMP_IMAGE_FILTER_NONE:
6399 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6403 cw->image_filter = filter;
6405 wl_signal_emit_mutable(&cw->events.image_filter_set, NULL);
6410 EINTERN E_Comp_Image_Filter
6411 e_comp_object_image_filter_get(Evas_Object *obj)
6413 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6414 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6415 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6416 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6418 return cw->image_filter;
6422 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6426 if (!_damage_trace) return;
6428 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6429 evas_object_del(obj);
6431 _damage_trace_post_objs = NULL;
6435 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6437 if (!_damage_trace) return;
6439 _damage_trace_post_objs = _damage_trace_objs;
6440 _damage_trace_objs = NULL;
6444 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6446 if (_damage_trace == onoff) return;
6450 evas_event_callback_add(e_comp->evas,
6451 EVAS_CALLBACK_RENDER_PRE,
6452 _e_comp_object_damage_trace_render_pre_cb,
6455 evas_event_callback_add(e_comp->evas,
6456 EVAS_CALLBACK_RENDER_POST,
6457 _e_comp_object_damage_trace_render_post_cb,
6464 EINA_LIST_FREE(_damage_trace_objs, obj)
6465 evas_object_del(obj);
6467 _damage_trace_objs = NULL;
6469 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6470 evas_object_del(obj);
6472 _damage_trace_post_objs = NULL;
6474 evas_event_callback_del(e_comp->evas,
6475 EVAS_CALLBACK_RENDER_PRE,
6476 _e_comp_object_damage_trace_render_pre_cb);
6478 evas_event_callback_del(e_comp->evas,
6479 EVAS_CALLBACK_RENDER_POST,
6480 _e_comp_object_damage_trace_render_post_cb);
6483 _damage_trace = onoff;
6487 e_comp_object_redirected_get(Evas_Object *obj)
6489 API_ENTRY EINA_FALSE;
6490 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6492 return cw->redirected;
6496 e_comp_object_color_visible_get(Evas_Object *obj)
6498 API_ENTRY EINA_FALSE;
6500 return cw->color_visible;
6504 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6506 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6508 return e_map_set_to_comp_object(em, obj);
6512 e_comp_object_map_get(const Evas_Object *obj)
6514 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6516 return e_map_get_from_comp_object(obj);
6520 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6522 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6524 evas_object_map_enable_set(obj, enable);
6530 e_comp_object_render_update_lock(Evas_Object *obj)
6532 E_Comp_Wl_Buffer *buffer;
6533 struct wayland_tbm_client_queue *cqueue;
6535 API_ENTRY EINA_FALSE;
6537 if (cw->render_update_lock.lock == 0)
6539 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6541 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6542 if ((buffer) && (buffer->resource))
6544 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6546 wayland_tbm_server_client_queue_flush(cqueue);
6549 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6550 e_comp_object_render_update_del(obj);
6552 ELOGF("COMP", "Render update lock enabled", cw->ec);
6555 cw->render_update_lock.lock++;
6561 e_comp_object_render_update_unlock(Evas_Object *obj)
6565 if (cw->render_update_lock.lock == 0)
6568 cw->render_update_lock.lock--;
6570 if (cw->render_update_lock.lock == 0)
6573 if (cw->render_update_lock.pending_move_set)
6575 evas_object_move(obj,
6576 cw->render_update_lock.pending_move_x,
6577 cw->render_update_lock.pending_move_y);
6578 cw->render_update_lock.pending_move_x = 0;
6579 cw->render_update_lock.pending_move_y = 0;
6580 cw->render_update_lock.pending_move_set = EINA_FALSE;
6583 if (cw->render_update_lock.pending_resize_set)
6585 evas_object_resize(obj,
6586 cw->render_update_lock.pending_resize_w,
6587 cw->render_update_lock.pending_resize_h);
6588 cw->render_update_lock.pending_resize_w = 0;
6589 cw->render_update_lock.pending_resize_h = 0;
6590 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6593 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6595 if ((cw->ec->exp_iconify.buffer_flush) &&
6596 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6597 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6598 e_comp_object_clear(obj);
6600 e_comp_object_render_update_add(obj);
6602 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET, cw->ec);
6604 ELOGF("COMP", "Render update lock disabled", cw->ec);
6609 e_comp_object_render_update_lock_get(Evas_Object *obj)
6611 API_ENTRY EINA_FALSE;
6613 if (cw->render_update_lock.lock > 0)
6620 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6624 if ((cw->transparent.set) || (cw->transparent.setting))
6626 if (r) *r = cw->transparent.user_r;
6627 if (g) *g = cw->transparent.user_g;
6628 if (b) *b = cw->transparent.user_b;
6629 if (a) *a = cw->transparent.user_a;
6633 evas_object_color_get(obj, r, g, b, a);
6638 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6642 evas_object_render_op_set(cw->obj, op);
6644 wl_signal_emit_mutable(&cw->events.render_op_set, NULL);
6647 EINTERN Evas_Render_Op
6648 e_comp_object_render_op_get(Evas_Object *obj)
6650 API_ENTRY EVAS_RENDER_BLEND;
6652 return evas_object_render_op_get(cw->obj);
6656 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6659 wl_signal_add(&cw->events.lower, listener);
6662 #ifdef REFACTOR_DESK_AREA
6664 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6667 wl_signal_add(&cw->events.lower_done, listener);
6671 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6674 wl_signal_add(&cw->events.raise, listener);
6679 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6682 wl_signal_add(&cw->events.show, listener);
6686 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6689 wl_signal_add(&cw->events.hide, listener);
6692 #ifdef REFACTOR_DESK_AREA
6694 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6697 wl_signal_add(&cw->events.set_layer, listener);
6701 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6704 wl_signal_add(&cw->events.stack_above, listener);
6708 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6711 wl_signal_add(&cw->events.stack_below, listener);
6716 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6719 wl_signal_add(&cw->events.image_filter_set, listener);
6723 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6726 wl_signal_add(&cw->events.render_op_set, listener);
6730 e_comp_object_content_type_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6733 wl_signal_add(&cw->events.content_type_set, listener);
6737 e_comp_object_color_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6740 wl_signal_add(&cw->events.color_set, listener);
6744 e_comp_object_color_visible_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6747 wl_signal_add(&cw->events.color_visible_set, listener);