2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
8 = keys that return objects =
9 - E_Client: the client associated with the object (E_Client*)
10 - comp_smart_obj: cw->smart_obj (Evas_Object*)
11 - comp_obj: cw (E_Comp_Object*)
13 = keys that are bool flags =
14 - client_restack: client needs a protocol-level restack
15 - comp_override: object is triggering a nocomp override to force compositing
16 - comp_ref: object has a ref from visibility animations
17 - comp_showing: object is currently running its show animation
18 - comp_hiding: object is currently running its hiding animation
19 - comp_object: object is a compositor-created object
20 - comp_object_skip: object has a name which prohibits theme shadows
21 - comp_object-to_del: list of objects which will be deleted when this object is deleted
22 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
23 - effect_running: object is animating by external module
26 #define UPDATE_MAX 512 // same as evas
27 #define FAILURE_MAX 2 // seems reasonable
28 #define SMART_NAME "e_comp_object"
29 #define INPUT_OBJ_SMART_NAME "input_object"
31 /* for non-util functions */
32 #define API_ENTRY E_Comp_Object *cw; \
33 cw = evas_object_smart_data_get(obj); \
34 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
36 /* for util functions (obj may or may not be E_Comp_Object */
37 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
40 CRI("YOU PASSED NULL! ARGH!"); \
43 cw = evas_object_smart_data_get(obj); \
44 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
46 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
48 /* enable for lots of client size info in console output */
50 # define e_util_size_debug_set(x, y)
53 /* enable along with display-specific damage INF calls to enable render tracing
57 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
59 #define RENDER_DEBUG(...)
62 #ifdef REFACTOR_DESK_AREA
64 typedef struct _E_Comp_Object
68 int x, y, w, h; // geometry
72 E_Comp_Object_Frame client_inset;
74 Eina_Stringshare *frame_theme;
75 Eina_Stringshare *frame_name;
76 Eina_Stringshare *visibility_effect; //effect when toggling visibility
78 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
80 Evas_Object *smart_obj; // smart object
81 Evas_Object *clip; // clipper over effect object
82 Evas_Object *input_obj; // input smart object
83 Evas_Object *obj; // composite object
84 Evas_Object *frame_object; // for client frames
85 Evas_Object *shobj; // shadow object
86 Evas_Object *effect_obj; // effects object
87 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
92 Evas_Object *transform_tranp_obj;// transform transp rect obj
93 Evas_Object *default_input_obj; // default input object
94 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
95 Eina_List *obj_mirror; // extra mirror objects
96 Eina_Tiler *updates; //render update regions
97 Eina_Tiler *pending_updates; //render update regions which are about to render
99 Evas_Native_Surface *ns; //for custom gl rendering
101 struct wl_listener buffer_destroy_listener;
103 unsigned int update_count; // how many updates have happened to this obj
105 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
107 unsigned int animating; // it's busy animating
108 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
109 unsigned int force_visible; //number of visible obj_mirror objects
110 Eina_Bool delete_pending : 1; // delete pending
111 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
112 Eina_Bool showing : 1; // object is currently in "show" animation
113 Eina_Bool hiding : 1; // object is currently in "hide" animation
114 Eina_Bool visible : 1; // is visible
116 Eina_Bool shaped : 1; // is shaped
117 Eina_Bool update : 1; // has updates to fetch
118 Eina_Bool redirected : 1; // has updates to fetch
119 Eina_Bool native : 1; // native
121 Eina_Bool nocomp : 1; // nocomp applied
122 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
123 Eina_Bool real_hid : 1; // last hide was a real window unmap
125 Eina_Bool effect_set : 1; //effect_obj has a valid group
126 Eina_Bool effect_running : 1; //effect_obj is playing an animation
127 Eina_Bool effect_clip : 1; //effect_obj is clipped
128 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
130 Eina_Bool updates_exist : 1;
131 Eina_Bool updates_full : 1; // entire object will be updated
133 Eina_Bool force_move : 1;
134 Eina_Bool frame_extends : 1; //frame may extend beyond object size
135 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
136 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
137 Eina_Bool user_alpha_set : 1;
138 Eina_Bool user_alpha : 1;
142 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
143 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
150 } indicator; //indicator object for internal client
154 Evas_Object *mask_obj;
157 int mask_x, mask_y, mask_w, mask_h;
160 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
162 tbm_surface_h tbm_surface;
163 E_Comp_Image_Filter image_filter;
164 Eina_Bool set_mouse_callbacks;
169 E_Comp_Wl_Buffer_Ref buffer_ref;
170 Eina_Bool pending_move_set;
171 int pending_move_x, pending_move_y;
172 Eina_Bool pending_resize_set;
173 int pending_resize_w, pending_resize_h;
174 } render_update_lock;
187 struct wl_signal lower;
188 //#ifdef REFACTOR_DESK_AREA
189 struct wl_signal raise;
191 struct wl_signal show;
192 struct wl_signal hide;
193 //#ifdef REFACTOR_DESK_AREA
194 struct wl_signal set_layer;
195 struct wl_signal stack_above;
196 struct wl_signal stack_below;
202 typedef struct _E_Input_Rect_Data
208 typedef struct _E_Input_Rect_Smart_Data
210 Eina_List *input_rect_data_list;
212 } E_Input_Rect_Smart_Data;
214 struct E_Comp_Object_Mover
217 E_Comp_Object_Mover_Cb func;
223 static Eina_Inlist *_e_comp_object_movers = NULL;
224 static Evas_Smart *_e_comp_smart = NULL;
225 static Evas_Smart *_e_comp_input_obj_smart = NULL;
227 static int _e_comp_object_hooks_delete = 0;
228 static int _e_comp_object_hooks_walking = 0;
230 static Eina_Inlist *_e_comp_object_hooks[] =
232 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
233 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
234 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
235 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
236 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
237 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
238 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
239 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
242 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
243 static int _e_comp_object_intercept_hooks_delete = 0;
244 static int _e_comp_object_intercept_hooks_walking = 0;
246 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
248 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
249 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
253 static Eina_Bool _damage_trace = EINA_FALSE;
254 static Eina_List *_damage_trace_objs = NULL;
255 static Eina_List *_damage_trace_post_objs = NULL;
257 /* sekrit functionzzz */
258 EINTERN void e_client_focused_set(E_Client *ec);
260 /* emitted every time a new noteworthy comp object is added */
261 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
263 /* ecore event define */
264 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
265 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
266 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
268 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
269 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
270 static void _e_comp_object_dim_update(E_Comp_Object *cw);
271 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
272 #ifdef REFACTOR_DESK_AREA
274 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
277 static E_Client *dim_client = NULL;
280 _e_comp_object_hooks_clean(void)
283 E_Comp_Object_Hook *ch;
286 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
287 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
289 if (!ch->delete_me) continue;
290 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
296 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
298 E_Comp_Object_Hook *ch;
299 Eina_Bool ret = EINA_TRUE;
301 if (e_object_is_del(E_OBJECT(ec)))
303 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
304 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
305 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
306 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
307 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
308 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
309 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
310 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
316 e_object_ref(E_OBJECT(ec));
317 _e_comp_object_hooks_walking++;
318 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
320 if (ch->delete_me) continue;
321 if (!(ch->func(ch->data, ec)))
327 _e_comp_object_hooks_walking--;
328 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
329 _e_comp_object_hooks_clean();
331 e_object_unref(E_OBJECT(ec));
336 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
338 _e_comp_object_intercept_hooks_clean(void)
341 E_Comp_Object_Intercept_Hook *ch;
344 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
345 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
347 if (!ch->delete_me) continue;
348 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
354 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
356 E_Comp_Object_Intercept_Hook *ch;
357 Eina_Bool ret = EINA_TRUE;
359 if (e_object_is_del(E_OBJECT(ec))) return ret;
360 e_object_ref(E_OBJECT(ec));
361 _e_comp_object_intercept_hooks_walking++;
362 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
364 if (ch->delete_me) continue;
365 if (!(ch->func(ch->data, ec)))
371 _e_comp_object_intercept_hooks_walking--;
372 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
373 _e_comp_object_intercept_hooks_clean();
375 e_object_unref(E_OBJECT(ec));
382 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
384 E_Event_Comp_Object *ev = event;
387 ec = evas_object_data_get(ev->comp_object, "E_Client");
391 e_object_unref(E_OBJECT(ec));
393 evas_object_unref(ev->comp_object);
398 _e_comp_object_event_add(Evas_Object *obj)
400 E_Event_Comp_Object *ev;
403 if (stopping) return;
404 ev = E_NEW(E_Event_Comp_Object, 1);
405 EINA_SAFETY_ON_NULL_RETURN(ev);
407 evas_object_ref(obj);
408 ev->comp_object = obj;
409 ec = evas_object_data_get(ev->comp_object, "E_Client");
413 e_object_ref(E_OBJECT(ec));
415 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
419 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
421 E_Event_Comp_Object *ev = event;
424 ec = evas_object_data_get(ev->comp_object, "E_Client");
428 e_object_unref(E_OBJECT(ec));
430 evas_object_unref(ev->comp_object);
435 _e_comp_object_event_simple(Evas_Object *obj, int type)
437 E_Event_Comp_Object *ev;
440 ev = E_NEW(E_Event_Comp_Object, 1);
443 evas_object_ref(obj);
444 ev->comp_object = obj;
445 ec = evas_object_data_get(ev->comp_object, "E_Client");
449 e_object_ref(E_OBJECT(ec));
451 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
453 /////////////////////////////////////
456 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
458 E_Comp_Object *cw = data;
460 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
464 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
466 E_Comp_Object *cw = data;
468 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
469 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
472 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
473 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
477 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
479 E_Comp_Object *cw = data;
482 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
483 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
486 /////////////////////////////////////
488 #ifdef REFACTOR_DESK_AREA
490 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
493 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
498 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
499 if (cw->ec->input_only) return;
501 layer = evas_object_layer_get(obj);
503 if (cw->transform_bg_obj)
505 if (layer != evas_object_layer_get(cw->transform_bg_obj))
507 evas_object_layer_set(cw->transform_bg_obj, layer);
510 evas_object_stack_below(cw->transform_bg_obj, obj);
513 if (cw->transform_tranp_obj)
515 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
517 evas_object_layer_set(cw->transform_tranp_obj, layer);
520 evas_object_stack_below(cw->transform_tranp_obj, obj);
525 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
532 if (!map) return NULL;
534 e_map_util_points_populate_from_object_full(map, obj, 0);
535 e_map_util_points_color_set(map, 255, 255, 255, 255);
537 for (i = 0 ; i < 4 ; ++i)
542 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
543 e_map_point_coord_set(map, i, x, y, 1.0);
550 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_comp_object_map_set(obj, map);
560 e_comp_object_map_enable_set(obj, EINA_TRUE);
567 evas_object_map_enable_set(obj, EINA_FALSE);
572 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
578 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
581 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
583 e_comp_object_map_set(obj, map);
584 e_comp_object_map_enable_set(obj, EINA_TRUE);
591 evas_object_map_enable_set(obj, EINA_FALSE);
594 /////////////////////////////////////
596 static inline Eina_Bool
597 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
599 if (num > 1) return EINA_TRUE;
600 if ((rects[0].x == 0) && (rects[0].y == 0) &&
601 ((int)rects[0].w == w) && ((int)rects[0].h == h))
606 /////////////////////////////////////
608 /* add a client to the layer-client list */
609 #ifdef REFACTOR_DESK_AREA
611 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
614 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
617 g_rec_mutex_lock(&e_comp->ec_list_mutex);
620 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));
622 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));
623 if ((!above) && (!below))
626 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
627 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
628 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
630 e_comp->layers[cw->layer].clients_count++;
632 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
635 #ifdef REFACTOR_DESK_AREA
637 _e_comp_object_layers_remove(E_Comp_Object *cw)
640 _e_comp_object_layers_remove(E_Comp_Object *cw)
643 g_rec_mutex_lock(&e_comp->ec_list_mutex);
645 if (cw->ec && e_comp->layers[cw->layer].clients)
647 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
648 e_comp->layers[cw->layer].clients_count--;
651 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
654 /////////////////////////////////////
656 _e_comp_object_alpha_set(E_Comp_Object *cw)
658 Eina_Bool alpha = cw->ec->argb;
660 if ((cw->external_content) &&
661 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
666 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
667 if (cw->user_alpha_set) alpha = cw->user_alpha;
669 evas_object_image_alpha_set(cw->obj, alpha);
673 _e_comp_object_shadow(E_Comp_Object *cw)
675 if (e_client_util_shadow_state_get(cw->ec))
676 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
678 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
679 if (cw->frame_object)
680 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
681 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
684 /* convert from the surface coordinates to the buffer coordinates */
686 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
688 E_Comp_Wl_Buffer_Viewport *vp;
689 E_Comp_Wl_Client_Data *cdata;
693 cdata = e_client_cdata_get(ec);
695 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
702 vp = &cdata->scaler.buffer_viewport;
703 transform = e_comp_wl_output_buffer_transform_get(ec);
705 e_pixmap_size_get(ec->pixmap, &bw, &bh);
707 /* for subsurface, it should be swap 90 and 270 */
708 if (e_comp_wl_subsurface_check(ec))
711 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
712 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
713 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
714 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
720 case WL_OUTPUT_TRANSFORM_NORMAL:
721 default: tx = sx, ty = sy; break;
722 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
723 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
724 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
725 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
726 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
727 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
728 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
731 tx *= vp->buffer.scale;
732 ty *= vp->buffer.scale;
739 _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)
747 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
748 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
755 if (dw) *dw = MAX(x1, x2) - mx;
756 if (dh) *dh = MAX(y1, y2) - my;
760 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
761 int *dx, int *dy, int *dw, int *dh)
763 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
764 E_Util_Transform_Rect_Vertex sv, dv;
768 e_pixmap_size_get(ec->pixmap, &bw, &bh);
770 sv = e_util_transform_rect_to_vertices(&rect);
772 for (i = 0; i < 4; i++)
774 double x = 0.0, y = 0.0;
776 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
778 /* if evas decide coordinate is outside of map, it returns (0, 0)
779 in this case, full damage is added.
781 if ((i != 0) && (x == 0.0) && (y == 0.0))
784 dv.vertices[i].vertex[0] = x;
785 dv.vertices[i].vertex[1] = y;
786 dv.vertices[i].vertex[2] = 1.0;
787 dv.vertices[i].vertex[3] = 1.0;
790 rect = e_util_transform_vertices_to_rect(&dv);
792 if (dx) *dx = rect.x;
793 if (dy) *dy = rect.y;
794 if (dw) *dw = rect.w;
795 if (dh) *dh = rect.h;
809 _e_comp_object_map_damage_transform_get(E_Client *ec)
816 if (!e_client_transform_core_enable_get(ec))
819 m = e_client_map_get(ec);
823 e_pixmap_size_get(ec->pixmap, &bw, &bh);
824 if ((bw == 0) || (bh == 0))
837 e_map_point_coord_set(m2, 0, 0, 0, 0);
838 e_map_point_coord_set(m2, 1, bw, 0, 0);
839 e_map_point_coord_set(m2, 2, bw, bh, 0);
840 e_map_point_coord_set(m2, 3, 0, bh, 0);
842 for (i = 0; i < 4; i++)
846 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
847 e_map_point_image_uv_set(m2, i, map_x, map_y);
854 /////////////////////////////////////
856 /* handle evas mouse-in events on client object */
858 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
860 Evas_Event_Mouse_In *ev = event_info;
861 E_Comp_Object *cw = data;
863 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
866 /* handle evas mouse-out events on client object */
868 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
870 Evas_Event_Mouse_Out *ev = event_info;
871 E_Comp_Object *cw = data;
873 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
876 /* handle evas mouse wheel events on client object */
878 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
880 Evas_Event_Mouse_Wheel *ev = event_info;
881 E_Comp_Object *cw = data;
882 E_Binding_Event_Wheel ev2;
885 if (e_client_action_get()) return;
886 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
887 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
890 /* handle evas mouse down events on client object */
892 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
894 Evas_Event_Mouse_Down *ev = event_info;
895 E_Comp_Object *cw = data;
896 E_Binding_Event_Mouse_Button ev2;
899 if (e_client_action_get()) return;
900 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
901 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
904 /* handle evas mouse up events on client object */
906 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
908 Evas_Event_Mouse_Up *ev = event_info;
909 E_Comp_Object *cw = data;
910 E_Binding_Event_Mouse_Button ev2;
913 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
914 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
915 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
918 /* handle evas mouse movement events on client object */
920 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
922 Evas_Event_Mouse_Move *ev = event_info;
923 E_Comp_Object *cw = data;
926 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
927 e_client_mouse_move(cw->ec, &ev->cur.output);
929 /////////////////////////////////////
931 /* helper function for checking compositor themes based on user-defined matches */
933 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
935 if (((m->title) && (!ec->netwm.name)) ||
936 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
938 #if defined(__cplusplus) || defined(c_plusplus)
939 if (((m->clas) && (!ec->icccm.cpp_class)) ||
940 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
943 if (((m->clas) && (!ec->icccm.class)) ||
944 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
948 if (((m->role) && (!ec->icccm.window_role)) ||
949 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
955 if ((int)ec->netwm.type != m->primary_type)
958 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
961 if (m->borderless != 0)
965 if (e_client_util_borderless(ec))
967 if (!(((m->borderless == -1) && (!borderless)) ||
968 ((m->borderless == 1) && (borderless))))
975 if (((ec->icccm.transient_for != 0) ||
978 if (!(((m->dialog == -1) && (!dialog)) ||
979 ((m->dialog == 1) && (dialog))))
982 if (m->accepts_focus != 0)
984 int accepts_focus = 0;
986 if (ec->icccm.accepts_focus)
988 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
989 ((m->accepts_focus == 1) && (accepts_focus))))
998 if (!(((m->vkbd == -1) && (!vkbd)) ||
999 ((m->vkbd == 1) && (vkbd))))
1004 if (!(((m->argb == -1) && (!ec->argb)) ||
1005 ((m->argb == 1) && (ec->argb))))
1008 if (m->fullscreen != 0)
1010 int fullscreen = ec->fullscreen;
1012 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1013 ((m->fullscreen == 1) && (fullscreen))))
1018 if (!(m->modal == -1))
1024 /* function for setting up a client's compositor frame theme (cw->shobj) */
1026 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1030 Eina_List *list = NULL, *l;
1031 E_Input_Rect_Data *input_rect_data;
1032 E_Input_Rect_Smart_Data *input_rect_sd;
1034 Eina_Stringshare *reshadow_group = NULL;
1035 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1036 Eina_Stringshare *name, *title;
1037 E_Comp_Config *conf = e_comp_config_get();
1039 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1040 /* match correct client type */
1041 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1042 name = cw->ec->icccm.name;
1043 title = cw->ec->icccm.title;
1044 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1045 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1047 /* skipping here is mostly a hack for systray because I hate it */
1050 EINA_LIST_FOREACH(list, l, m)
1052 if (((m->name) && (!name)) ||
1053 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1055 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1058 no_shadow = m->no_shadow;
1059 if (m->shadow_style)
1061 /* fast effects are just themes with "/fast" appended and shorter effect times */
1064 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1065 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1067 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1069 /* default to non-fast style if fast not available */
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1077 if (ok && m->visibility_effect)
1078 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1085 if (skip || (cw->ec->e.state.video))
1087 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1089 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1092 if (conf->shadow_style)
1096 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1097 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1099 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1103 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1104 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1106 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1119 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1121 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1126 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1131 if (cw->ec->override)
1133 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1134 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1136 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1137 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1143 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1144 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1147 _e_comp_object_shadow(cw);
1150 if (focus || cw->ec->focused || cw->ec->override)
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1158 /* visibility must always be enabled for re_manage clients to prevent
1159 * pop-in animations every time the user sees a persistent client again;
1160 * applying visibility for iconic clients prevents the client from getting
1163 if (cw->visible || cw->ec->re_manage)
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1168 /* breaks animation counter */
1169 if (cw->frame_object)
1171 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1172 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1184 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1187 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1189 if (input_rect_data->obj)
1191 pass_event_flag = EINA_TRUE;
1197 if (cw->indicator.obj)
1199 Evas_Object *indicator;
1200 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1201 if (indicator != cw->indicator.obj)
1203 edje_object_part_unswallow(cw->shobj, indicator);
1204 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1205 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1209 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1210 evas_object_pass_events_set(cw->obj, pass_event_flag);
1215 /////////////////////////////////////////////
1218 _e_comp_object_animating_begin(E_Comp_Object *cw)
1221 if (cw->animating == 1)
1223 e_comp->animating++;
1225 e_object_ref(E_OBJECT(cw->ec));
1230 _e_comp_object_animating_end(E_Comp_Object *cw)
1239 if (cw->ec->launching)
1241 if (!cw->ec->extra_animating)
1243 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1244 cw->ec->launching = EINA_FALSE;
1245 if (cw->ec->first_mapped)
1247 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1248 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1251 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1255 e_comp->animating--;
1256 cw->showing = cw->hiding = 0;
1258 if (e_comp->animating == 0)
1259 e_comp_visibility_calculation_set(EINA_TRUE);
1260 /* remove ref from animation start, account for possibility of deletion from unref */
1261 return !!e_object_unref(E_OBJECT(cw->ec));
1267 /* handle the end of a compositor animation */
1269 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1271 E_Comp_Object *cw = data;
1273 /* visible clients which have never been sized are a bug */
1274 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1275 CRI("ACK! ec:%p", cw->ec);
1276 if (!_e_comp_object_animating_end(cw)) return;
1277 if (cw->animating) return;
1278 /* hide only after animation finishes to guarantee a full run of the animation */
1279 if (!cw->defer_hide) return;
1280 if ((!strcmp(emission, "e,action,hide,done")) ||
1281 (!strcmp(emission, "e,action,done")) ||
1282 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1284 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1285 evas_object_hide(cw->smart_obj);
1289 /* run a visibility compositor effect if available, return false if object is dead */
1291 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1297 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1298 if (!cw->effect_running)
1299 _e_comp_object_animating_begin(cw);
1300 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1301 return _e_comp_object_animating_end(cw);
1302 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1303 return _e_comp_object_animating_end(cw);
1305 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1308 zone = e_comp_zone_find_by_ec(cw->ec);
1310 zw = zone->w, zh = zone->h;
1315 zone = e_comp_object_util_zone_get(cw->smart_obj);
1316 if (!zone) zone = e_zone_current_get();
1323 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1324 cw->w, cw->h, zw, zh, x, y}, 8);
1325 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1326 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1329 /////////////////////////////////////////////
1331 /* create necessary objects for clients that e manages */
1333 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1335 if (cw->set_mouse_callbacks) return;
1336 if (!cw->smart_obj) return;
1338 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1339 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1340 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1341 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1342 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1343 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1345 cw->set_mouse_callbacks = EINA_TRUE;
1349 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1351 if (!cw->set_mouse_callbacks) return;
1352 if (!cw->smart_obj) return;
1354 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1355 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1356 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1357 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1358 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1359 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1361 cw->set_mouse_callbacks = EINA_FALSE;
1365 _e_comp_object_setup(E_Comp_Object *cw)
1367 cw->clip = evas_object_rectangle_add(e_comp->evas);
1368 evas_object_move(cw->clip, -9999, -9999);
1369 evas_object_resize(cw->clip, 999999, 999999);
1370 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1371 cw->effect_obj = edje_object_add(e_comp->evas);
1372 evas_object_move(cw->effect_obj, cw->x, cw->y);
1373 evas_object_clip_set(cw->effect_obj, cw->clip);
1374 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1375 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1376 cw->shobj = edje_object_add(e_comp->evas);
1377 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1378 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1379 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1381 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1382 if (cw->ec->override)
1384 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1385 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1386 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1388 else if (!cw->ec->input_only)
1390 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1391 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1392 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1394 cw->real_hid = !cw->ec->input_only;
1395 if (!cw->ec->input_only)
1397 e_util_size_debug_set(cw->effect_obj, 1);
1398 _e_comp_object_mouse_event_callback_set(cw);
1401 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1402 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1403 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1404 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1405 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1406 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1408 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1411 /////////////////////////////////////////////
1413 /* for fast path evas rendering; only called during render */
1415 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1417 E_Comp_Object *cw = data;
1418 E_Client *ec = cw->ec;
1420 int bx, by, bxx, byy;
1422 if (e_object_is_del(E_OBJECT(ec))) return;
1423 if (cw->external_content) return;
1424 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1425 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1428 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1429 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1431 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1433 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1434 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1438 bx = by = bxx = byy = 0;
1439 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1442 Edje_Message_Int_Set *msg;
1443 Edje_Message_Int msg2;
1444 Eina_Bool id = (bx || by || bxx || byy);
1446 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1452 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1454 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1458 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1459 e_comp_client_post_update_add(cw->ec);
1461 else if (e_comp_object_render(ec->frame))
1463 /* apply shape mask if necessary */
1464 if ((!cw->native) && (ec->shaped))
1465 e_comp_object_shape_apply(ec->frame);
1467 /* shaped clients get precise mouse events to handle transparent pixels */
1468 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1470 /* queue another render if client is still dirty; cannot refresh here. */
1471 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1472 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1474 if (cw->render_trace)
1476 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1482 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1484 E_Comp_Object *cw = data;
1485 E_Client *ec = cw->ec;
1487 if (e_object_is_del(E_OBJECT(ec))) return;
1488 if (cw->external_content) return;
1489 if (!e_comp->hwc) return;
1491 e_comp_client_render_list_add(cw->ec);
1493 if (!ec->hwc_window) return;
1495 e_hwc_windows_rendered_window_add(ec->hwc_window);
1498 /////////////////////////////////////////////
1501 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1503 E_Comp_Object *cw = data;
1506 if (cw->render_update_lock.lock)
1508 cw->render_update_lock.pending_move_x = x;
1509 cw->render_update_lock.pending_move_y = y;
1510 cw->render_update_lock.pending_move_set = EINA_TRUE;
1514 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1515 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1516 (cw->external_content))
1518 /* delay to move until the external content is unset */
1519 cw->ec->changes.pos = 1;
1524 if (cw->ec->move_after_resize)
1526 if ((x != cw->ec->x) || (y != cw->ec->y))
1528 if (!cw->ec->is_cursor)
1529 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1530 e_client_pos_set(cw->ec, x, y);
1531 cw->ec->changes.pos = 1;
1537 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1538 (cw->ec->manage_resize.resize_obj))
1540 e_client_pos_set(cw->ec, x, y);
1541 cw->ec->client.x = x + cw->client_inset.l;
1542 cw->ec->client.y = y + cw->client_inset.t;
1543 e_policy_visibility_client_defer_move(cw->ec);
1547 /* if frame_object does not exist, client_inset indicates CSD.
1548 * this means that ec->client matches cw->x/y, the opposite
1551 fx = (!cw->frame_object) * cw->client_inset.l;
1552 fy = (!cw->frame_object) * cw->client_inset.t;
1553 if ((cw->x == x + fx) && (cw->y == y + fy))
1555 if ((cw->ec->x != x) || (cw->ec->y != y))
1557 /* handle case where client tries to move to position and back very quickly */
1558 e_client_pos_set(cw->ec, x, y);
1559 cw->ec->client.x = x + cw->client_inset.l;
1560 cw->ec->client.y = y + cw->client_inset.t;
1564 if (!cw->ec->maximize_override)
1566 /* prevent moving in some directions while directionally maximized */
1567 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1569 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1572 ix = x + cw->client_inset.l;
1573 iy = y + cw->client_inset.t;
1574 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1575 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1576 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1578 /* prevent moving at all if move isn't allowed in current maximize state */
1579 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1580 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1583 zone = e_comp_zone_find_by_ec(cw->ec);
1586 cw->ec->changes.need_unmaximize = 1;
1587 cw->ec->saved.x = ix - zone->x;
1588 cw->ec->saved.y = iy - zone->y;
1589 cw->ec->saved.w = cw->ec->client.w;
1590 cw->ec->saved.h = cw->ec->client.h;
1594 /* only update during resize if triggered by resize */
1595 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1596 /* delay to move while surface waits paired commit serial*/
1597 if (e_client_pending_geometry_has(cw->ec))
1599 /* do nothing while waiting paired commit serial*/
1603 e_client_pos_set(cw->ec, x, y);
1604 if (cw->ec->new_client)
1606 /* don't actually do anything until first client idler loop */
1607 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1608 cw->ec->changes.pos = 1;
1613 /* only update xy position of client to avoid invalid
1614 * first damage region if it is not a new_client. */
1615 cw->ec->client.x = ix;
1616 cw->ec->client.y = iy;
1619 if (!cw->frame_object)
1621 evas_object_move(obj, x, y);
1626 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1628 E_Comp_Object *cw = data;
1629 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1632 if (cw->render_update_lock.lock)
1634 cw->render_update_lock.pending_resize_w = w;
1635 cw->render_update_lock.pending_resize_h = h;
1636 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1640 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1642 e_client_size_set(cw->ec, w, h);
1643 evas_object_resize(obj, w, h);
1647 /* if frame_object does not exist, client_inset indicates CSD.
1648 * this means that ec->client matches cw->w/h, the opposite
1651 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1652 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1653 if ((cw->w == w + fw) && (cw->h == h + fh))
1655 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1656 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1657 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1659 /* handle case where client tries to resize itself and back very quickly */
1660 e_client_size_set(cw->ec, w, h);
1661 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1662 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1663 evas_object_smart_callback_call(obj, "client_resize", NULL);
1667 /* guarantee that fullscreen is fullscreen */
1668 zone = e_comp_zone_find_by_ec(cw->ec);
1670 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1672 if (!e_client_transform_core_enable_get(cw->ec))
1675 /* calculate client size */
1676 iw = w - cw->client_inset.l - cw->client_inset.r;
1677 ih = h - cw->client_inset.t - cw->client_inset.b;
1678 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1680 /* prevent resizing while maximized depending on direction and config */
1681 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1683 Eina_Bool reject = EINA_FALSE;
1684 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1686 if (cw->ec->client.h != ih)
1688 cw->ec->saved.h = ih;
1689 cw->ec->saved.y = cw->ec->client.y - zone->y;
1690 reject = cw->ec->changes.need_unmaximize = 1;
1693 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1695 if (cw->ec->client.w != iw)
1697 cw->ec->saved.w = iw;
1698 cw->ec->saved.x = cw->ec->client.x - zone->x;
1699 reject = cw->ec->changes.need_unmaximize = 1;
1708 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1710 /* do nothing until client idler loops */
1711 if ((cw->ec->w != w) || (cw->ec->h != h))
1713 e_client_size_set(cw->ec, w, h);
1714 cw->ec->changes.size = 1;
1719 if (e_client_pending_geometry_has(cw->ec))
1721 /* do nothing while waiting paired commit serial*/
1725 e_client_size_set(cw->ec, w, h);
1727 cw->ec->client.w = iw;
1728 cw->ec->client.h = ih;
1729 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1731 /* The size of non-compositing window can be changed, so there is a
1732 * need to check that cw is H/W composited if cw is not redirected.
1733 * And of course we have to change size of evas object of H/W composited cw,
1734 * otherwise cw can't receive input events even if it is shown on the screen.
1736 Eina_Bool redirected = cw->redirected;
1738 redirected = e_comp_is_on_overlay(cw->ec);
1740 if ((!cw->ec->input_only) && (redirected) &&
1741 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1742 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1743 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1744 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1747 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1748 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1750 prev_w = cw->w, prev_h = cw->h;
1751 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1752 /* check shading and clamp to pixmap size for regular clients */
1753 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1754 (((w - fw != pw) || (h - fh != ph))))
1756 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1757 evas_object_smart_callback_call(obj, "client_resize", NULL);
1759 if (cw->frame_object || cw->ec->input_only)
1760 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1763 if ((cw->w == w) && (cw->h == h))
1765 /* going to be a noop resize which won't trigger smart resize */
1766 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1767 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1769 evas_object_resize(obj, w, h);
1773 evas_object_smart_callback_call(obj, "client_resize", NULL);
1776 if ((!cw->frame_object) && (!cw->ec->input_only))
1778 /* "just do it" for overrides */
1779 evas_object_resize(obj, w, h);
1781 if (!cw->ec->override)
1783 /* shape probably changed for non-overrides */
1788 /* this fixes positioning jiggles when using a resize mode
1789 * which also changes the client's position
1792 if (cw->frame_object)
1793 x = cw->x, y = cw->y;
1795 x = cw->ec->x, y = cw->ec->y;
1796 switch (cw->ec->resize_mode)
1798 case E_POINTER_RESIZE_BL:
1799 case E_POINTER_RESIZE_L:
1800 evas_object_move(obj, x + prev_w - cw->w, y);
1802 case E_POINTER_RESIZE_TL:
1803 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1805 case E_POINTER_RESIZE_T:
1806 case E_POINTER_RESIZE_TR:
1807 evas_object_move(obj, x, y + prev_h - cw->h);
1816 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1818 #ifdef REFACTOR_DESK_AREA
1819 E_Comp_Object *cw = data;
1820 E_Comp_Object_Data_Set_Layer layer_set_data;
1822 layer_set_data.cw = cw;
1823 layer_set_data.layer = layer;
1825 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1829 e_comp_render_queue();
1830 _e_comp_object_transform_obj_stack_update(obj);
1834 E_Comp_Object *cw = data;
1835 E_Comp_Wl_Client_Data *child_cdata;
1836 unsigned int l = e_comp_canvas_layer_map(layer);
1839 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1841 /* doing a compositor effect, follow directions */
1842 _e_comp_object_layer_set(obj, layer);
1843 if (layer == cw->ec->layer) //trying to put layer back
1847 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1848 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1849 if (cw->layer != l) goto layer_set;
1853 e_comp_render_queue();
1855 ec = e_client_above_get(cw->ec);
1856 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1857 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1858 ec = e_client_above_get(ec);
1859 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1861 ec = e_client_below_get(cw->ec);
1862 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1863 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1864 ec = e_client_below_get(ec);
1865 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1867 evas_object_stack_above(obj, ec->frame);
1872 if (ec && (cw->ec->parent == ec))
1874 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1875 evas_object_stack_above(obj, ec->frame);
1877 evas_object_stack_below(obj, ec->frame);
1880 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1886 if (cw->layer == l) return;
1887 if (e_comp_canvas_client_layer_map(layer) == 9999)
1888 return; //invalid layer for clients not doing comp effects
1889 if (cw->ec->fullscreen)
1891 cw->ec->saved.layer = layer;
1894 oldraise = e_config->transient.raise;
1896 /* clamp to valid client layer */
1897 layer = e_comp_canvas_client_layer_map_nearest(layer);
1898 cw->ec->layer = layer;
1899 if (e_config->transient.layer)
1902 Eina_List *list = eina_list_clone(cw->ec->transients);
1904 /* We need to set raise to one, else the child wont
1905 * follow to the new layer. It should be like this,
1906 * even if the user usually doesn't want to raise
1909 e_config->transient.raise = 1;
1910 EINA_LIST_FREE(list, child)
1912 child_cdata = e_client_cdata_get(child);
1913 if (child_cdata && !child_cdata->mapped)
1915 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1918 e_client_layer_set(child, layer);
1922 e_config->transient.raise = oldraise;
1924 _e_comp_object_layers_remove(cw);
1925 cw->layer = e_comp_canvas_layer_map(layer);
1926 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1927 //if (cw->ec->new_client)
1928 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1929 _e_comp_object_layer_set(obj, layer);
1930 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1931 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1932 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1934 /* can't stack a client above its own layer marker */
1935 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1937 if (!cw->visible) return;
1938 e_comp_render_queue();
1939 _e_comp_object_transform_obj_stack_update(obj);
1943 #ifdef REFACTOR_DESK_AREA
1945 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1949 _e_comp_object_raise(Evas_Object *obj)
1951 evas_object_raise(obj);
1953 if (evas_object_smart_smart_get(obj))
1955 E_Client *ec = e_comp_object_client_get(obj);
1957 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1962 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1964 evas_object_lower(obj);
1966 if (evas_object_smart_smart_get(obj))
1968 E_Client *ec = e_comp_object_client_get(obj);
1971 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1972 wl_signal_emit_mutable(&cw->events.lower, NULL);
1977 #ifdef REFACTOR_DESK_AREA
1979 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1982 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1985 evas_object_stack_above(obj, target);
1987 if (evas_object_smart_smart_get(obj))
1989 E_Client *ec = e_comp_object_client_get(obj);
1991 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1996 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1998 evas_object_stack_below(obj, target);
2000 if (evas_object_smart_smart_get(obj))
2002 E_Client *ec = e_comp_object_client_get(obj);
2004 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2008 #ifdef REFACTOR_DESK_AREA
2010 e_comp_object_layer_set(Evas_Object *obj, short layer)
2013 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2016 evas_object_layer_set(obj, layer);
2018 if (evas_object_smart_smart_get(obj))
2020 E_Client *ec = e_comp_object_client_get(obj);
2022 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2027 _e_comp_object_is_pending(E_Client *ec)
2031 if (!ec) return EINA_FALSE;
2033 topmost = e_comp_wl_topmost_parent_get(ec);
2035 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2038 #ifdef REFACTOR_DESK_AREA
2040 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2043 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2046 E_Comp_Object *cw2 = NULL;
2049 Evas_Object *o = stack;
2050 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2052 /* We should consider topmost's layer_pending for subsurface */
2053 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2055 if (_e_comp_object_is_pending(cw->ec))
2056 e_comp_object_layer_update(cw->smart_obj,
2057 raising? stack : NULL,
2058 raising? NULL : stack);
2060 /* obey compositor effects! */
2061 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2062 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2063 stack_cb(cw->smart_obj, stack);
2064 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2065 evas_object_data_del(cw->smart_obj, "client_restack");
2069 cw2 = evas_object_data_get(o, "comp_obj");
2071 /* assume someone knew what they were doing during client init */
2072 if (cw->ec->new_client)
2073 layer = cw->ec->layer;
2074 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2075 layer = cw2->ec->layer;
2077 layer = evas_object_layer_get(stack);
2078 ecstack = e_client_below_get(cw->ec);
2079 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2081 evas_object_layer_set(cw->smart_obj, layer);
2082 /* we got our layer wrangled, return now! */
2083 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2086 /* check if we're stacking below another client */
2089 /* check for non-client layer object */
2090 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2092 /* find an existing client to use for layering
2093 * by walking up the object stack
2095 * this is guaranteed to be pretty quick since we'll either:
2096 * - run out of client layers
2097 * - find a stacking client
2099 o = evas_object_above_get(o);
2100 if ((!o) || (o == cw->smart_obj)) break;
2101 if (evas_object_layer_get(o) != layer)
2103 /* reached the top client layer somehow
2104 * use top client object
2106 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2109 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2110 * return here since the top client layer window
2115 ec = e_client_top_get();
2120 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2123 if (cw2 && cw->layer != cw2->layer)
2126 /* remove existing layers */
2127 _e_comp_object_layers_remove(cw);
2130 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2131 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2132 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2133 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2134 else //if no stacking objects found, either raise or lower
2135 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2138 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2140 /* find new object for stacking if cw2 is on state of layer_pending */
2141 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2143 E_Client *new_stack = NULL, *current_ec = NULL;
2144 current_ec = cw2->ec;
2147 while ((new_stack = e_client_below_get(current_ec)))
2149 current_ec = new_stack;
2150 if (new_stack == cw->ec) continue;
2151 if (new_stack->layer != cw2->ec->layer) break;
2152 if (!_e_comp_object_is_pending(new_stack)) break;
2154 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2155 stack = new_stack->frame;
2158 /* stack it above layer object */
2160 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2161 stack = e_comp->layers[below_layer].obj;
2166 while ((new_stack = e_client_above_get(current_ec)))
2168 current_ec = new_stack;
2169 if (new_stack == cw->ec) continue;
2170 if (new_stack->layer != cw2->ec->layer) break;
2171 if (!_e_comp_object_is_pending(new_stack)) break;
2173 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2174 stack = new_stack->frame;
2176 stack = e_comp->layers[cw2->layer].obj;
2180 /* set restack if stacking has changed */
2181 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2182 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2183 stack_cb(cw->smart_obj, stack);
2184 if (e_comp->layers[cw->layer].obj)
2185 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2187 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2189 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2190 evas_object_data_del(cw->smart_obj, "client_restack");
2191 if (!cw->visible) return;
2192 e_comp_render_queue();
2196 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2198 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2200 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2202 #ifdef REFACTOR_DESK_AREA
2203 E_Comp_Object *cw = data;
2204 E_Comp_Object_Data_Stack_Above stack_above_data;
2206 stack_above_data.cw = cw;
2207 stack_above_data.above_obj = above;
2209 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2211 if (evas_object_below_get(obj) == above)
2213 e_comp_object_layer_update(obj, above, NULL);
2217 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2219 _e_comp_object_transform_obj_stack_update(obj);
2220 _e_comp_object_transform_obj_stack_update(above);
2227 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2229 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2230 if (evas_object_above_get(obj) == below)
2232 e_comp_object_layer_update(obj, NULL, below);
2236 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2237 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2238 if (evas_object_smart_smart_get(obj))
2239 _e_comp_object_transform_obj_stack_update(obj);
2240 if (evas_object_smart_smart_get(below))
2241 _e_comp_object_transform_obj_stack_update(below);
2246 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2248 E_Comp_Object *cw = data;
2251 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2253 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2255 if (cw->ec->layer_pending)
2256 e_comp_object_layer_update(obj, NULL, obj);
2258 _e_comp_object_lower(cw, obj);
2261 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2262 o = evas_object_below_get(obj);
2263 _e_comp_object_layers_remove(cw);
2264 /* prepend to client list since this client should be the first item now */
2265 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2266 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2267 evas_object_data_set(obj, "client_restack", (void*)1);
2268 _e_comp_object_lower(cw, obj);
2269 evas_object_data_del(obj, "client_restack");
2270 if (!cw->visible) goto end;
2271 e_comp_render_queue();
2272 _e_comp_object_transform_obj_stack_update(obj);
2279 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2281 E_Comp_Object *cw = data;
2285 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2287 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2289 if (cw->ec->layer_pending)
2291 int obj_layer = evas_object_layer_get(obj);
2292 if (cw->ec->layer != obj_layer)
2293 e_comp_object_layer_update(obj, NULL, NULL);
2296 _e_comp_object_raise(obj);
2299 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2300 o = evas_object_above_get(obj);
2301 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2303 /* still stack below override below the layer marker */
2304 for (op = o = e_comp->layers[cw->layer].obj;
2305 o && o != e_comp->layers[cw->layer - 1].obj;
2306 op = o, o = evas_object_below_get(o))
2308 if (evas_object_smart_smart_get(o))
2312 ec = e_comp_object_client_get(o);
2313 if (ec && (!ec->override)) break;
2316 _e_comp_object_stack_below(obj, op);
2317 e_client_focus_defer_set(cw->ec);
2319 if (!cw->visible) goto end;
2320 e_comp_render_queue();
2321 _e_comp_object_transform_obj_stack_update(obj);
2328 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2330 E_Comp_Object *cw = data;
2332 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2333 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2335 ELOGF("COMP", "Hide. intercepted", cw->ec);
2340 if (cw->ec->launching == EINA_TRUE)
2342 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2343 cw->ec->launching = EINA_FALSE;
2348 /* hidden flag = just do it */
2349 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2350 evas_object_hide(obj);
2352 wl_signal_emit_mutable(&cw->events.hide, NULL);
2357 if (cw->ec->input_only)
2359 /* input_only = who cares */
2360 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2361 evas_object_hide(obj);
2363 wl_signal_emit_mutable(&cw->events.hide, NULL);
2367 /* already hidden or currently animating */
2368 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2370 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2374 /* don't try hiding during shutdown */
2375 cw->defer_hide |= stopping;
2376 if (!cw->defer_hide)
2378 if ((!cw->ec->iconic) && (!cw->ec->override))
2379 /* unset delete requested so the client doesn't break */
2380 cw->ec->delete_requested = 0;
2381 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2383 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2384 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2387 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2390 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2392 _e_comp_object_animating_begin(cw);
2393 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2395 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2396 cw->defer_hide = !!cw->animating;
2398 e_comp_object_effect_set(obj, NULL);
2401 if (cw->animating) return;
2402 /* if we have no animations running, go ahead and hide */
2404 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2405 evas_object_hide(obj);
2407 wl_signal_emit_mutable(&cw->events.hide, NULL);
2411 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2413 E_Client *ec = cw->ec;
2416 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2418 if (ec->show_pending.count > 0)
2420 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2421 ec->show_pending.running = EINA_TRUE;
2425 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2426 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2428 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2433 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,
2434 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2435 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2438 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2441 if (ec->iconic && cw->animating)
2443 /* triggered during iconify animation */
2444 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2447 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2450 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2451 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2453 evas_object_move(cw->smart_obj, ec->x, ec->y);
2454 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2455 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2457 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2458 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2461 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2462 evas_object_show(cw->smart_obj);
2465 e_client_focus_defer_set(ec);
2469 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2473 pw = ec->client.w, ph = ec->client.h;
2475 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2477 ec->changes.visible = !ec->hidden;
2480 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2484 cw->updates = eina_tiler_new(pw, ph);
2487 ec->changes.visible = !ec->hidden;
2490 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2495 eina_tiler_tile_size_set(cw->updates, 1, 1);
2498 /* ignore until client idler first run */
2499 ec->changes.visible = !ec->hidden;
2502 ELOGF("COMP", "show_helper. return. new_client", ec);
2509 evas_object_move(cw->smart_obj, ec->x, ec->y);
2510 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2511 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2512 evas_object_show(cw->smart_obj);
2515 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2517 /* start_drag not received */
2518 ec->changes.visible = 1;
2521 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2524 /* re-set geometry */
2525 evas_object_move(cw->smart_obj, ec->x, ec->y);
2526 /* force resize in case it hasn't happened yet, or just to update size */
2527 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2528 if ((cw->w < 1) || (cw->h < 1))
2530 /* if resize didn't go through, try again */
2531 ec->visible = ec->changes.visible = 1;
2533 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2536 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2537 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2538 e_pixmap_clear(ec->pixmap);
2540 if (cw->real_hid && w && h)
2543 /* force comp theming in case it didn't happen already */
2544 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2545 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2546 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2549 /* only do the show if show is allowed */
2552 if (ec->internal) //internal clients render when they feel like it
2553 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2555 if (!e_client_is_iconified_by_client(ec)||
2556 e_policy_visibility_client_is_uniconic(ec))
2558 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2559 evas_object_show(cw->smart_obj);
2561 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2562 it is rendered in idle callback without native surface and
2563 compositor shows an empty frame if other objects aren't shown
2564 because job callback of e_comp called at the next loop.
2565 it causes a visual defect when windows are switched.
2569 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2570 e_comp_object_dirty(cw->smart_obj);
2571 e_comp_object_render(cw->smart_obj);
2576 wl_signal_emit_mutable(&cw->events.show, NULL);
2580 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2582 E_Comp_Object *cw = data;
2583 E_Client *ec = cw->ec;
2585 E_Input_Rect_Data *input_rect_data;
2586 E_Input_Rect_Smart_Data *input_rect_sd;
2589 if (ec->ignored) return;
2593 //INF("SHOW2 %p", ec);
2594 _e_comp_intercept_show_helper(cw);
2597 //INF("SHOW %p", ec);
2600 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2601 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2602 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2603 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2607 if ((!cw->obj) && (cw->external_content))
2609 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2613 _e_comp_object_setup(cw);
2616 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2617 cw->obj = evas_object_image_filled_add(e_comp->evas);
2618 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2619 e_util_size_debug_set(cw->obj, 1);
2620 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2621 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2622 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2623 evas_object_name_set(cw->obj, "cw->obj");
2624 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2626 _e_comp_object_alpha_set(cw);
2629 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2632 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2633 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2636 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2639 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2641 if (input_rect_data->obj)
2643 evas_object_geometry_set(input_rect_data->obj,
2644 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2645 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2646 input_rect_data->rect.w, input_rect_data->rect.h);
2653 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2655 _e_comp_intercept_show_helper(cw);
2659 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2661 E_Comp_Object *cw = data;
2665 /* note: this is here as it seems there are enough apps that do not even
2666 * expect us to emulate a look of focus but not actually set x input
2667 * focus as we do - so simply abort any focus set on such windows */
2668 /* be strict about accepting focus hint */
2669 /* be strict about accepting focus hint */
2670 if ((!ec->icccm.accepts_focus) &&
2671 (!ec->icccm.take_focus))
2675 if (e_client_focused_get() == ec)
2676 e_client_focused_set(NULL);
2678 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2679 evas_object_focus_set(obj, focus);
2683 if (focus && ec->lock_focus_out) return;
2684 if (e_object_is_del(E_OBJECT(ec)) && focus)
2685 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2687 /* filter focus setting based on current state */
2692 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2693 evas_object_focus_set(obj, focus);
2696 if ((ec->iconic) && (!ec->deskshow))
2698 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2700 /* don't focus an iconified window. that's silly! */
2701 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2702 e_client_uniconify(ec);
2703 e_client_focus_latest_set(ec);
2717 /* not yet visible, wait till the next time... */
2718 ec->want_focus = !ec->hidden;
2723 e_client_focused_set(ec);
2727 if (e_client_focused_get() == ec)
2728 e_client_focused_set(NULL);
2732 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2734 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2736 evas_object_focus_set(obj, focus);
2740 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2742 E_Comp_Object *cw = data;
2744 if (cw->transparent.set)
2746 cw->transparent.user_r = r;
2747 cw->transparent.user_g = g;
2748 cw->transparent.user_b = b;
2749 cw->transparent.user_a = a;
2751 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2753 cw->transparent.user_r,
2754 cw->transparent.user_g,
2755 cw->transparent.user_b,
2756 cw->transparent.user_a);
2760 evas_object_color_set(obj, r, g, b, a);
2763 ////////////////////////////////////////////////////
2766 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2768 int w, h, ox, oy, ow, oh;
2770 Eina_Bool pass_event_flag = EINA_FALSE;
2771 E_Input_Rect_Data *input_rect_data;
2772 E_Input_Rect_Smart_Data *input_rect_sd;
2774 if (cw->frame_object)
2776 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2777 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2778 /* set a fixed size, force edje calc, check size difference */
2779 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2780 edje_object_message_signal_process(cw->frame_object);
2781 edje_object_calc_force(cw->frame_object);
2782 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2783 cw->client_inset.l = ox;
2784 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2785 cw->client_inset.t = oy;
2786 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2787 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2788 evas_object_resize(cw->frame_object, w, h);
2792 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2795 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2797 if (input_rect_data->obj)
2799 pass_event_flag = EINA_TRUE;
2805 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2806 evas_object_pass_events_set(cw->obj, pass_event_flag);
2810 cw->client_inset.l = 0;
2811 cw->client_inset.r = 0;
2812 cw->client_inset.t = 0;
2813 cw->client_inset.b = 0;
2815 cw->client_inset.calc = !!cw->frame_object;
2819 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2821 E_Comp_Object *cw = data;
2825 /* - get current size
2827 * - readjust for new frame size
2830 w = cw->ec->w, h = cw->ec->h;
2831 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2833 _e_comp_object_frame_recalc(cw);
2835 if (!cw->ec->fullscreen)
2836 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2838 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2839 if (cw->ec->fullscreen)
2841 zone = e_comp_zone_find_by_ec(cw->ec);
2843 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2845 else if (cw->ec->new_client)
2847 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2848 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2849 evas_object_resize(cw->ec->frame, w, h);
2851 else if ((w != cw->ec->w) || (h != cw->ec->h))
2852 evas_object_resize(cw->ec->frame, w, h);
2856 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2858 E_Comp_Object *cw = data;
2860 _e_comp_object_shadow_setup(cw);
2861 if (cw->frame_object)
2863 _e_comp_object_shadow(cw);
2864 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2865 _e_comp_object_frame_recalc(cw);
2866 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2871 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2873 E_Comp_Object *cw = data;
2875 if (_e_comp_object_shadow_setup(cw))
2876 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2877 if (cw->frame_object)
2879 _e_comp_object_shadow(cw);
2880 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2881 _e_comp_object_frame_recalc(cw);
2882 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2887 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2889 E_Comp_Object *cw = data;
2891 if (cw->frame_object)
2893 _e_comp_object_shadow(cw);
2894 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2895 _e_comp_object_frame_recalc(cw);
2896 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2901 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2903 E_Comp_Object *cw = data;
2905 if (_e_comp_object_shadow_setup(cw))
2908 cw->ec->changes.size = 1;
2910 if (cw->frame_object)
2912 _e_comp_object_shadow(cw);
2913 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2914 _e_comp_object_frame_recalc(cw);
2915 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2920 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2922 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2926 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2928 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2932 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2934 E_Comp_Object *cw = data;
2936 if (!cw->ec) return; //NYI
2937 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2941 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2943 E_Comp_Object *cw = data;
2945 if (!cw->ec) return; //NYI
2946 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2950 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2952 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2956 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2958 E_Comp_Object *cw = data;
2960 if (!e_object_is_del(E_OBJECT(cw->ec)))
2961 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2965 _e_comp_input_obj_smart_add(Evas_Object *obj)
2967 E_Input_Rect_Smart_Data *input_rect_sd;
2968 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2970 if (!input_rect_sd) return;
2971 evas_object_smart_data_set(obj, input_rect_sd);
2975 _e_comp_input_obj_smart_del(Evas_Object *obj)
2977 E_Input_Rect_Smart_Data *input_rect_sd;
2978 E_Input_Rect_Data *input_rect_data;
2980 input_rect_sd = evas_object_smart_data_get(obj);
2981 if (!input_rect_sd) return;
2983 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2985 if (input_rect_data->obj)
2987 evas_object_smart_member_del(input_rect_data->obj);
2988 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2990 E_FREE(input_rect_data);
2992 E_FREE(input_rect_sd);
2996 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2998 E_Input_Rect_Smart_Data *input_rect_sd;
2999 E_Input_Rect_Data *input_rect_data;
3003 input_rect_sd = evas_object_smart_data_get(obj);
3004 if (!input_rect_sd) return;
3006 cw = input_rect_sd->cw;
3007 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3009 if (input_rect_data->obj)
3011 evas_object_geometry_set(input_rect_data->obj,
3012 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3013 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3014 input_rect_data->rect.w, input_rect_data->rect.h);
3020 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3022 E_Input_Rect_Smart_Data *input_rect_sd;
3023 E_Input_Rect_Data *input_rect_data;
3027 input_rect_sd = evas_object_smart_data_get(obj);
3028 if (!input_rect_sd) return;
3030 cw = input_rect_sd->cw;
3031 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3033 if (input_rect_data->obj)
3035 evas_object_geometry_set(input_rect_data->obj,
3036 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3037 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3038 input_rect_data->rect.w, input_rect_data->rect.h);
3044 _e_comp_input_obj_smart_show(Evas_Object *obj)
3046 E_Input_Rect_Smart_Data *input_rect_sd;
3047 E_Input_Rect_Data *input_rect_data;
3050 input_rect_sd = evas_object_smart_data_get(obj);
3051 if (!input_rect_sd) return;
3053 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3055 if (input_rect_data->obj)
3057 evas_object_show(input_rect_data->obj);
3063 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3065 E_Input_Rect_Smart_Data *input_rect_sd;
3066 E_Input_Rect_Data *input_rect_data;
3069 input_rect_sd = evas_object_smart_data_get(obj);
3070 if (!input_rect_sd) return;
3072 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3074 if (input_rect_data->obj)
3076 evas_object_hide(input_rect_data->obj);
3082 _e_comp_input_obj_smart_init(void)
3084 if (_e_comp_input_obj_smart) return;
3086 static const Evas_Smart_Class sc =
3088 INPUT_OBJ_SMART_NAME,
3089 EVAS_SMART_CLASS_VERSION,
3090 _e_comp_input_obj_smart_add,
3091 _e_comp_input_obj_smart_del,
3092 _e_comp_input_obj_smart_move,
3093 _e_comp_input_obj_smart_resize,
3094 _e_comp_input_obj_smart_show,
3095 _e_comp_input_obj_smart_hide,
3108 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3114 _e_comp_smart_add(Evas_Object *obj)
3118 cw = E_NEW(E_Comp_Object, 1);
3119 EINA_SAFETY_ON_NULL_RETURN(cw);
3121 wl_signal_init(&cw->events.lower);
3122 #ifdef REFACTOR_DESK_AREA
3123 wl_signal_init(&cw->events.raise);
3125 wl_signal_init(&cw->events.show);
3126 wl_signal_init(&cw->events.hide);
3127 #ifdef REFACTOR_DESK_AREA
3128 wl_signal_init(&cw->events.set_layer);
3129 wl_signal_init(&cw->events.stack_above);
3130 wl_signal_init(&cw->events.stack_below);
3133 cw->smart_obj = obj;
3134 cw->x = cw->y = cw->w = cw->h = -1;
3135 evas_object_smart_data_set(obj, cw);
3136 cw->opacity = 255.0;
3137 cw->external_content = 0;
3138 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3139 cw->transform_bg_color.r = 0;
3140 cw->transform_bg_color.g = 0;
3141 cw->transform_bg_color.b = 0;
3142 cw->transform_bg_color.a = 255;
3143 evas_object_data_set(obj, "comp_obj", cw);
3144 evas_object_move(obj, -1, -1);
3145 /* intercept ALL the callbacks! */
3146 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3147 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3148 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3149 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3150 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3151 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3152 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3153 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3154 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3155 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3156 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3158 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3159 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3160 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3161 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3163 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3164 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3166 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3167 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3169 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3171 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3172 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3176 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3179 evas_object_color_set(cw->clip, r, g, b, a);
3180 evas_object_smart_callback_call(obj, "color_set", NULL);
3185 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3188 evas_object_clip_set(cw->clip, clip);
3192 _e_comp_smart_clip_unset(Evas_Object *obj)
3195 evas_object_clip_unset(cw->clip);
3199 _e_comp_smart_hide(Evas_Object *obj)
3201 TRACE_DS_BEGIN(COMP:SMART HIDE);
3206 evas_object_hide(cw->clip);
3207 if (cw->input_obj) evas_object_hide(cw->input_obj);
3208 evas_object_hide(cw->effect_obj);
3209 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3210 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3211 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3218 /* unset native surface if current displaying buffer was destroied */
3219 if (!cw->buffer_destroy_listener.notify)
3221 Evas_Native_Surface *ns;
3222 ns = evas_object_image_native_surface_get(cw->obj);
3223 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3224 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3227 if (!cw->ec->input_only)
3229 edje_object_freeze(cw->effect_obj);
3230 edje_object_freeze(cw->shobj);
3231 edje_object_play_set(cw->shobj, 0);
3232 if (cw->frame_object)
3233 edje_object_play_set(cw->frame_object, 0);
3236 e_comp_render_queue(); //force nocomp recheck
3242 _e_comp_smart_show(Evas_Object *obj)
3250 if ((cw->w < 0) || (cw->h < 0))
3251 CRI("ACK! ec:%p", cw->ec);
3253 TRACE_DS_BEGIN(COMP:SMART SHOW);
3255 e_comp_object_map_update(obj);
3257 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3258 evas_object_show(tmp->frame);
3260 evas_object_show(cw->clip);
3261 if (cw->input_obj) evas_object_show(cw->input_obj);
3262 if (!cw->ec->input_only)
3264 edje_object_thaw(cw->effect_obj);
3265 edje_object_thaw(cw->shobj);
3266 edje_object_play_set(cw->shobj, 1);
3267 if (cw->frame_object)
3268 edje_object_play_set(cw->frame_object, 1);
3270 evas_object_show(cw->effect_obj);
3271 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3272 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3273 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3274 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3275 e_comp_render_queue();
3276 if (cw->ec->input_only)
3281 if (cw->ec->iconic && (!cw->ec->new_client))
3283 if (e_client_is_iconified_by_client(cw->ec))
3285 ELOGF("COMP", "Set launching flag..", cw->ec);
3286 cw->ec->launching = EINA_TRUE;
3289 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3291 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3294 ELOGF("COMP", "Set launching flag..", cw->ec);
3295 cw->ec->launching = EINA_TRUE;
3297 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3298 _e_comp_object_animating_begin(cw);
3299 if (!_e_comp_object_effect_visibility_start(cw, 1))
3305 /* ensure some random effect doesn't lock the client offscreen */
3309 e_comp_object_effect_set(obj, NULL);
3312 _e_comp_object_dim_update(cw);
3318 _e_comp_smart_del(Evas_Object *obj)
3324 if (cw->buffer_destroy_listener.notify)
3326 wl_list_remove(&cw->buffer_destroy_listener.link);
3327 cw->buffer_destroy_listener.notify = NULL;
3330 if (cw->tbm_surface)
3332 tbm_surface_internal_unref(cw->tbm_surface);
3333 cw->tbm_surface = NULL;
3336 if (cw->render_update_lock.buffer_ref.buffer)
3338 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3339 cw->ec, cw->render_update_lock.lock);
3340 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3343 e_comp_object_render_update_del(cw->smart_obj);
3344 E_FREE_FUNC(cw->updates, eina_tiler_free);
3345 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3352 EINA_LIST_FREE(cw->obj_mirror, o)
3354 evas_object_image_data_set(o, NULL);
3355 evas_object_freeze_events_set(o, 1);
3356 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3360 _e_comp_object_layers_remove(cw);
3361 l = evas_object_data_get(obj, "comp_object-to_del");
3362 E_FREE_LIST(l, evas_object_del);
3363 _e_comp_object_mouse_event_callback_unset(cw);
3364 evas_object_del(cw->clip);
3365 evas_object_del(cw->obj);
3366 evas_object_del(cw->shobj);
3367 evas_object_del(cw->effect_obj);
3368 evas_object_del(cw->frame_object);
3369 evas_object_del(cw->input_obj);
3370 evas_object_del(cw->mask.obj);
3371 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3372 evas_object_del(cw->transform_bg_obj);
3373 evas_object_del(cw->transform_tranp_obj);
3374 evas_object_del(cw->default_input_obj);
3375 eina_stringshare_del(cw->frame_theme);
3376 eina_stringshare_del(cw->frame_name);
3380 e_comp->animating--;
3382 e_object_unref(E_OBJECT(cw->ec));
3384 cw->ec->frame = NULL;
3389 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3393 cw->x = x, cw->y = y;
3394 evas_object_move(cw->effect_obj, x, y);
3395 evas_object_move(cw->default_input_obj, x, y);
3396 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3398 e_comp_object_map_update(obj);
3402 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3404 Eina_Bool first = EINA_FALSE;
3409 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3411 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3413 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3415 if (cw->w != w || cw->h != h)
3416 e_comp_object_map_update(obj);
3418 first = ((cw->w < 1) || (cw->h < 1));
3419 cw->w = w, cw->h = h;
3423 if (cw->frame_object)
3424 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3427 /* verify pixmap:object size */
3428 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3430 if ((ww != pw) || (hh != ph))
3431 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3433 evas_object_resize(cw->effect_obj, tw, th);
3434 evas_object_resize(cw->default_input_obj, w, h);
3436 evas_object_resize(cw->input_obj, w, h);
3438 evas_object_resize(cw->mask.obj, w, h);
3439 /* resize render update tiler */
3442 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3443 cw->updates_full = 0;
3444 if (cw->updates) eina_tiler_clear(cw->updates);
3448 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3449 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3457 e_comp_render_queue();
3463 _e_comp_smart_init(void)
3465 if (_e_comp_smart) return;
3467 static const Evas_Smart_Class sc =
3470 EVAS_SMART_CLASS_VERSION,
3474 _e_comp_smart_resize,
3477 _e_comp_smart_color_set,
3478 _e_comp_smart_clip_set,
3479 _e_comp_smart_clip_unset,
3489 _e_comp_smart = evas_smart_class_new(&sc);
3494 e_comp_object_init(void)
3496 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3497 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3498 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3499 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3503 e_comp_object_shutdown(void)
3509 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3511 API_ENTRY EINA_FALSE;
3512 return !!cw->force_visible;
3514 /////////////////////////////////////////////////////////
3517 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3520 Eina_Bool comp_object;
3522 comp_object = !!evas_object_data_get(obj, "comp_object");
3527 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3529 e_comp_render_queue();
3531 l = evas_object_data_get(obj, "comp_object-to_del");
3532 E_FREE_LIST(l, evas_object_del);
3536 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3538 if (e_comp_util_object_is_above_nocomp(obj) &&
3539 (!evas_object_data_get(obj, "comp_override")))
3541 evas_object_data_set(obj, "comp_override", (void*)1);
3542 e_comp_override_add();
3547 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3549 Eina_Bool ref = EINA_TRUE;
3550 if (evas_object_visible_get(obj))
3554 d = evas_object_data_del(obj, "comp_hiding");
3556 /* currently trying to hide */
3559 /* already visible */
3563 evas_object_show(obj);
3566 evas_object_ref(obj);
3567 evas_object_data_set(obj, "comp_ref", (void*)1);
3569 edje_object_signal_emit(obj, "e,state,visible", "e");
3570 evas_object_data_set(obj, "comp_showing", (void*)1);
3571 if (e_comp_util_object_is_above_nocomp(obj))
3573 evas_object_data_set(obj, "comp_override", (void*)1);
3574 e_comp_override_add();
3579 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3581 if (!evas_object_visible_get(obj)) return;
3582 /* already hiding */
3583 if (evas_object_data_get(obj, "comp_hiding")) return;
3584 if (!evas_object_data_del(obj, "comp_showing"))
3586 evas_object_ref(obj);
3587 evas_object_data_set(obj, "comp_ref", (void*)1);
3589 edje_object_signal_emit(obj, "e,state,hidden", "e");
3590 evas_object_data_set(obj, "comp_hiding", (void*)1);
3592 if (evas_object_data_del(obj, "comp_override"))
3593 e_comp_override_timed_pop();
3597 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3599 if (!e_util_strcmp(emission, "e,action,hide,done"))
3601 if (!evas_object_data_del(obj, "comp_hiding")) return;
3602 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3603 evas_object_hide(obj);
3604 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3607 evas_object_data_del(obj, "comp_showing");
3608 if (evas_object_data_del(obj, "comp_ref"))
3609 evas_object_unref(obj);
3613 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3619 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3623 E_API E_Comp_Object_Hook *
3624 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3626 E_Comp_Object_Hook *ch;
3628 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3629 ch = E_NEW(E_Comp_Object_Hook, 1);
3630 if (!ch) return NULL;
3631 ch->hookpoint = hookpoint;
3633 ch->data = (void*)data;
3634 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3639 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3642 if (_e_comp_object_hooks_walking == 0)
3644 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3648 _e_comp_object_hooks_delete++;
3651 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3652 E_API E_Comp_Object_Intercept_Hook *
3653 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3655 E_Comp_Object_Intercept_Hook *ch;
3657 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3658 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3659 if (!ch) return NULL;
3660 ch->hookpoint = hookpoint;
3662 ch->data = (void*)data;
3663 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3668 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3671 if (_e_comp_object_intercept_hooks_walking == 0)
3673 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3677 _e_comp_object_intercept_hooks_delete++;
3682 e_comp_object_util_add(Evas_Object *obj)
3686 E_Comp_Config *conf = e_comp_config_get();
3687 Eina_Bool skip = EINA_FALSE;
3693 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3695 name = evas_object_name_get(obj);
3696 vis = evas_object_visible_get(obj);
3697 o = edje_object_add(e_comp->evas);
3698 evas_object_data_set(o, "comp_object", (void*)1);
3700 skip = (!strncmp(name, "noshadow", 8));
3702 evas_object_data_set(o, "comp_object_skip", (void*)1);
3704 if (conf->shadow_style)
3706 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3707 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3710 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3711 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3712 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3714 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3716 evas_object_geometry_get(obj, &x, &y, &w, &h);
3717 evas_object_geometry_set(o, x, y, w, h);
3718 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3720 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3722 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3723 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3724 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3725 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3726 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3727 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3729 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3731 edje_object_part_swallow(o, "e.swallow.content", obj);
3733 _e_comp_object_event_add(o);
3736 evas_object_show(o);
3741 /* utility functions for deleting objects when their "owner" is deleted */
3743 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3748 EINA_SAFETY_ON_NULL_RETURN(to_del);
3749 l = evas_object_data_get(obj, "comp_object-to_del");
3750 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3751 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3752 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3756 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3761 EINA_SAFETY_ON_NULL_RETURN(to_del);
3762 l = evas_object_data_get(obj, "comp_object-to_del");
3764 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3767 /////////////////////////////////////////////////////////
3769 EINTERN Evas_Object *
3770 e_comp_object_client_add(E_Client *ec)
3775 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3776 if (ec->frame) return NULL;
3777 _e_comp_smart_init();
3778 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3779 cw = evas_object_smart_data_get(o);
3780 if (!cw) return NULL;
3781 evas_object_data_set(o, "E_Client", ec);
3784 evas_object_data_set(o, "comp_object", (void*)1);
3786 _e_comp_object_event_add(o);
3791 /* utility functions for getting client inset */
3793 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3796 if (!cw->client_inset.calc)
3802 if (ax) *ax = x - cw->client_inset.l;
3803 if (ay) *ay = y - cw->client_inset.t;
3807 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3810 if (!cw->client_inset.calc)
3816 if (ax) *ax = x + cw->client_inset.l;
3817 if (ay) *ay = y + cw->client_inset.t;
3821 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3824 if (!cw->client_inset.calc)
3830 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3831 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3835 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3838 if (!cw->client_inset.calc)
3844 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3845 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3849 e_comp_object_client_get(Evas_Object *obj)
3854 /* FIXME: remove this when eo is used */
3855 o = evas_object_data_get(obj, "comp_smart_obj");
3857 return e_comp_object_client_get(o);
3858 return cw ? cw->ec : NULL;
3862 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3865 if (cw->frame_extends)
3866 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3871 if (w) *w = cw->ec->w;
3872 if (h) *h = cw->ec->h;
3877 e_comp_object_util_zone_get(Evas_Object *obj)
3879 E_Zone *zone = NULL;
3883 zone = e_comp_zone_find_by_ec(cw->ec);
3888 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3889 zone = e_comp_zone_xy_get(x, y);
3895 e_comp_object_util_center(Evas_Object *obj)
3897 int x, y, w, h, ow, oh;
3902 zone = e_comp_object_util_zone_get(obj);
3903 EINA_SAFETY_ON_NULL_RETURN(zone);
3904 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3905 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3906 ow = cw->ec->w, oh = cw->ec->h;
3908 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3909 x = x + (w - ow) / 2;
3910 y = y + (h - oh) / 2;
3911 evas_object_move(obj, x, y);
3915 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3917 int x, y, w, h, ow, oh;
3920 EINA_SAFETY_ON_NULL_RETURN(on);
3921 evas_object_geometry_get(on, &x, &y, &w, &h);
3922 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3923 ow = cw->ec->w, oh = cw->ec->h;
3925 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3926 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3930 e_comp_object_util_fullscreen(Evas_Object *obj)
3935 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3938 evas_object_move(obj, 0, 0);
3939 evas_object_resize(obj, e_comp->w, e_comp->h);
3944 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3952 ow = cw->w, oh = cw->h;
3954 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3955 zone = e_comp_object_util_zone_get(obj);
3956 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3957 if (x) *x = zx + (zw - ow) / 2;
3958 if (y) *y = zy + (zh - oh) / 2;
3962 e_comp_object_input_objs_del(Evas_Object *obj)
3965 E_Input_Rect_Data *input_rect_data;
3966 E_Input_Rect_Smart_Data *input_rect_sd;
3971 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3972 if (!input_rect_sd) return;
3974 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3976 if (input_rect_data->obj)
3978 evas_object_smart_member_del(input_rect_data->obj);
3979 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3981 E_FREE(input_rect_data);
3986 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3989 E_Input_Rect_Data *input_rect_data = NULL;
3990 E_Input_Rect_Smart_Data *input_rect_sd;
3991 int client_w, client_h;
3993 if (cw->ec->client.w)
3994 client_w = cw->ec->client.w;
3996 client_w = cw->ec->w;
3998 if (cw->ec->client.h)
3999 client_h = cw->ec->client.h;
4001 client_h = cw->ec->h;
4003 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4007 _e_comp_input_obj_smart_init();
4008 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4009 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4010 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4013 input_rect_sd->cw = cw;
4016 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4019 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4020 if (input_rect_data)
4022 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4023 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4027 if ((input_rect_data) &&
4028 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4030 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4031 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4032 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4033 evas_object_clip_set(input_rect_data->obj, cw->clip);
4034 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4035 evas_object_geometry_set(input_rect_data->obj,
4036 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4037 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4038 evas_object_pass_events_set(cw->default_input_obj, 1);
4039 evas_object_pass_events_set(cw->obj, 1);
4042 evas_object_show(input_rect_data->obj);
4043 evas_object_show(cw->input_obj);
4048 evas_object_smart_member_del(cw->input_obj);
4049 E_FREE_FUNC(cw->input_obj, evas_object_del);
4050 evas_object_pass_events_set(cw->default_input_obj, 0);
4051 evas_object_pass_events_set(cw->obj, 0);
4056 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4059 E_Input_Rect_Smart_Data *input_rect_sd;
4060 E_Input_Rect_Data *input_rect_data;
4063 if (!cw->input_obj) return;
4065 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4068 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4070 *list = eina_list_append(*list, &input_rect_data->rect);
4076 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4079 if (l) *l = cw->client_inset.l;
4080 if (r) *r = cw->client_inset.r;
4081 if (t) *t = cw->client_inset.t;
4082 if (b) *b = cw->client_inset.b;
4085 /* set geometry for CSD */
4087 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4093 if (cw->frame_object)
4094 CRI("ACK! ec:%p", cw->ec);
4095 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4096 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4097 calc = cw->client_inset.calc;
4098 cw->client_inset.calc = l || r || t || b;
4099 eina_stringshare_replace(&cw->frame_theme, "borderless");
4100 if (cw->client_inset.calc)
4102 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4103 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4104 e_client_size_set(cw->ec, tw, th);
4106 else if (cw->ec->maximized || cw->ec->fullscreen)
4108 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4109 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4111 if (!cw->ec->new_client)
4113 if (calc && cw->client_inset.calc)
4115 tx = cw->ec->x - (l - cw->client_inset.l);
4116 ty = cw->ec->y - (t - cw->client_inset.t);
4117 e_client_pos_set(cw->ec, tx, ty);
4119 cw->ec->changes.pos = cw->ec->changes.size = 1;
4122 cw->client_inset.l = l;
4123 cw->client_inset.r = r;
4124 cw->client_inset.t = t;
4125 cw->client_inset.b = b;
4129 e_comp_object_frame_allowed(Evas_Object *obj)
4131 API_ENTRY EINA_FALSE;
4132 return (cw->frame_object || (!cw->client_inset.calc));
4136 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4138 API_ENTRY EINA_FALSE;
4139 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4140 eina_stringshare_replace(&cw->frame_name, name);
4141 if (cw->frame_object)
4142 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4147 e_comp_object_frame_exists(Evas_Object *obj)
4149 API_ENTRY EINA_FALSE;
4150 return !!cw->frame_object;
4154 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4156 Evas_Object *o, *pbg;
4159 Eina_Stringshare *theme;
4161 API_ENTRY EINA_FALSE;
4163 if (!e_util_strcmp(cw->frame_theme, name))
4164 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4165 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4166 return _e_comp_object_shadow_setup(cw);
4167 pbg = cw->frame_object;
4168 theme = eina_stringshare_add(name);
4170 if (cw->frame_object)
4174 w = cw->ec->w, h = cw->ec->h;
4175 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4176 if ((cw->ec->w != w) || (cw->ec->h != h))
4178 cw->ec->changes.size = 1;
4181 E_FREE_FUNC(cw->frame_object, evas_object_del);
4182 if (!name) goto reshadow;
4184 o = edje_object_add(e_comp->evas);
4185 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4186 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4187 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4189 cw->frame_object = NULL;
4191 eina_stringshare_del(cw->frame_theme);
4192 cw->frame_theme = theme;
4197 if (theme != e_config->theme_default_border_style)
4199 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4200 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4204 ok = e_theme_edje_object_set(o, "base/theme/border",
4205 "e/widgets/border/default/border");
4206 if (ok && (theme == e_config->theme_default_border_style))
4208 /* Reset default border style to default */
4209 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4210 e_config_save_queue();
4217 cw->frame_object = o;
4218 eina_stringshare_del(cw->frame_theme);
4219 cw->frame_theme = theme;
4220 evas_object_name_set(o, "cw->frame_object");
4223 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4227 cw->ec->changes.icon = 1;
4233 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4238 _e_comp_object_shadow_setup(cw);
4241 int old_x, old_y, new_x = 0, new_y = 0;
4243 old_x = cw->x, old_y = cw->y;
4245 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4247 new_x = cw->ec->x, new_y = cw->ec->y;
4248 else if (cw->ec->placed || (!cw->ec->new_client))
4250 /* if no previous frame:
4251 * - reapply client_inset
4256 if (cw->ec->changes.size)
4264 zone = e_comp_zone_find_by_ec(cw->ec);
4267 x = cw->ec->client.x, y = cw->ec->client.y;
4268 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4269 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4271 new_x = x, new_y = y;
4274 if (old_x != new_x || old_y != new_y)
4276 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4277 cw->y = cw->x = -99999;
4278 evas_object_move(obj, new_x, new_y);
4282 if (cw->ec->maximized)
4284 cw->ec->changes.need_maximize = 1;
4287 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4288 if (cw->frame_object)
4290 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4293 cw->frame_extends = 0;
4294 evas_object_del(pbg);
4299 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4301 E_Comp_Object_Mover *prov;
4304 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4305 edje_object_signal_emit(cw->shobj, sig, src);
4306 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4307 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4308 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4310 /* start with highest priority callback first */
4311 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4313 if (!e_util_glob_match(sig, prov->sig)) continue;
4314 if (prov->func(prov->data, obj, sig)) break;
4319 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4321 /* FIXME: at some point I guess this should use eo to inherit
4322 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4323 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4326 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4330 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4333 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4337 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4340 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4344 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4347 Eina_Rectangle rect;
4350 if (cw->ec->input_only || (!cw->updates)) return;
4351 if (cw->nocomp) return;
4352 rect.x = x, rect.y = y;
4353 rect.w = w, rect.h = h;
4354 evas_object_smart_callback_call(obj, "damage", &rect);
4356 if (e_comp_is_on_overlay(cw->ec))
4358 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4359 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4360 * E module attempts to block screen update due to the particular policy.
4362 if (e_pixmap_resource_get(cw->ec->pixmap))
4363 cw->hwc_need_update = EINA_TRUE;
4366 /* ignore overdraw */
4367 if (cw->updates_full)
4369 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4370 e_comp_object_render_update_add(obj);
4372 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4373 evas_object_show(cw->smart_obj);
4377 /* clip rect to client surface */
4378 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4379 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4380 /* if rect is the total size of the client after clip, clear the updates
4381 * since this is guaranteed to be the whole region anyway
4383 eina_tiler_area_size_get(cw->updates, &tw, &th);
4384 if ((w > tw) || (h > th))
4386 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4387 eina_tiler_clear(cw->updates);
4388 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4390 tw = cw->ec->client.w, th = cw->ec->client.h;
4392 if ((!x) && (!y) && (w == tw) && (h == th))
4394 eina_tiler_clear(cw->updates);
4395 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4396 cw->updates_full = 1;
4397 cw->update_count = 0;
4400 if (cw->update_count > UPDATE_MAX)
4402 /* this is going to get really dumb, so just update the whole thing */
4403 eina_tiler_clear(cw->updates);
4404 cw->update_count = cw->updates_full = 1;
4405 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4406 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4410 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4411 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4413 cw->updates_exist = 1;
4414 e_comp_object_render_update_add(obj);
4416 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4417 evas_object_show(cw->smart_obj);
4421 e_comp_object_damage_exists(Evas_Object *obj)
4423 API_ENTRY EINA_FALSE;
4424 return cw->updates_exist;
4428 e_comp_object_render_update_add(Evas_Object *obj)
4432 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4433 if (cw->render_update_lock.lock) return;
4434 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4438 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4440 e_comp_render_queue();
4444 e_comp_object_render_update_del(Evas_Object *obj)
4448 if (cw->ec->input_only || (!cw->updates)) return;
4449 if (!cw->update) return;
4451 /* this gets called during comp animating to clear the update flag */
4452 if (e_comp->grabbed) return;
4453 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4454 if (!e_comp->updates)
4456 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4457 if (e_comp->render_animator)
4458 ecore_animator_freeze(e_comp->render_animator);
4463 e_comp_object_shape_apply(Evas_Object *obj)
4467 unsigned int i, *pix, *p;
4471 if (!cw->ec) return; //NYI
4472 if (cw->external_content) return;
4475 if ((cw->ec->shape_rects_num >= 1) &&
4476 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4481 ERR("BUGGER: shape with native surface? cw=%p", cw);
4484 evas_object_image_size_get(cw->obj, &w, &h);
4485 if ((w < 1) || (h < 1)) return;
4488 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4489 _e_comp_object_alpha_set(cw);
4490 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4491 evas_object_image_alpha_set(o, 1);
4493 p = pix = evas_object_image_data_get(cw->obj, 1);
4496 evas_object_image_data_set(cw->obj, pix);
4501 unsigned char *spix, *sp;
4503 spix = calloc(w * h, sizeof(unsigned char));
4505 for (i = 0; i < cw->ec->shape_rects_num; i++)
4509 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4510 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4511 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4512 sp = spix + (w * ry) + rx;
4513 for (py = 0; py < rh; py++)
4515 for (px = 0; px < rw; px++)
4523 for (py = 0; py < h; py++)
4525 for (px = 0; px < w; px++)
4527 unsigned int mask, imask;
4529 mask = ((unsigned int)(*sp)) << 24;
4531 imask |= imask >> 8;
4532 imask |= imask >> 8;
4533 *p = mask | (*p & imask);
4534 //if (*sp) *p = 0xff000000 | *p;
4535 //else *p = 0x00000000;
4544 for (py = 0; py < h; py++)
4546 for (px = 0; px < w; px++)
4550 evas_object_image_data_set(cw->obj, pix);
4551 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4552 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4554 evas_object_image_data_set(o, pix);
4555 evas_object_image_data_update_add(o, 0, 0, w, h);
4557 // don't need to fix alpha chanel as blending
4558 // should be totally off here regardless of
4559 // alpha channel content
4563 _e_comp_object_clear(E_Comp_Object *cw)
4568 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4570 if (cw->render_update_lock.lock) return;
4573 e_pixmap_clear(cw->ec->pixmap);
4575 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4576 evas_object_image_size_set(cw->obj, 1, 1);
4577 evas_object_image_data_set(cw->obj, NULL);
4578 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4580 evas_object_image_size_set(o, 1, 1);
4581 evas_object_image_data_set(o, NULL);
4584 e_comp_object_render_update_del(cw->smart_obj);
4588 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4592 API_ENTRY EINA_FALSE;
4594 if (cw->transparent.set == set)
4599 evas_object_color_get(obj, &r, &g, &b, &a);
4600 evas_object_color_set(obj, 0, 0, 0, 0);
4602 cw->transparent.user_r = r;
4603 cw->transparent.user_g = g;
4604 cw->transparent.user_b = b;
4605 cw->transparent.user_a = a;
4607 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4609 cw->transparent.user_r,
4610 cw->transparent.user_g,
4611 cw->transparent.user_b,
4612 cw->transparent.user_a);
4614 cw->transparent.set = EINA_TRUE;
4618 cw->transparent.set = EINA_FALSE;
4620 evas_object_color_set(obj,
4621 cw->transparent.user_r,
4622 cw->transparent.user_g,
4623 cw->transparent.user_b,
4624 cw->transparent.user_a);
4626 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4628 cw->transparent.user_r,
4629 cw->transparent.user_g,
4630 cw->transparent.user_b,
4631 cw->transparent.user_a);
4637 /* helper function to simplify toggling of redirection for display servers which support it */
4639 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4644 if (cw->redirected == set) return;
4645 cw->redirected = set;
4646 if (cw->external_content) return;
4648 e_comp_object_map_update(obj);
4652 if (cw->updates_exist)
4653 e_comp_object_render_update_add(obj);
4655 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4657 _e_comp_object_transparent_set(obj, EINA_FALSE);
4658 evas_object_smart_callback_call(obj, "redirected", NULL);
4662 _e_comp_object_clear(cw);
4663 _e_comp_object_transparent_set(obj, EINA_TRUE);
4664 evas_object_smart_callback_call(obj, "unredirected", NULL);
4669 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4672 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4674 if (cw->buffer_destroy_listener.notify)
4676 cw->buffer_destroy_listener.notify = NULL;
4677 wl_list_remove(&cw->buffer_destroy_listener.link);
4680 if (e_object_is_del(E_OBJECT(cw->ec)))
4682 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4687 /* if it's current displaying buffer, do not remove its content */
4688 if (!evas_object_visible_get(cw->ec->frame))
4689 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4694 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4699 if (cw->buffer_destroy_listener.notify)
4701 wl_list_remove(&cw->buffer_destroy_listener.link);
4702 cw->buffer_destroy_listener.notify = NULL;
4705 if (cw->tbm_surface)
4707 tbm_surface_internal_unref(cw->tbm_surface);
4708 cw->tbm_surface = NULL;
4713 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4715 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4716 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4718 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4720 tbm_surface_internal_ref(ns->data.tbm.buffer);
4721 cw->tbm_surface = ns->data.tbm.buffer;
4725 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4726 evas_object_image_native_surface_set(cw->obj, ns);
4730 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4732 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4733 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4734 evas_object_image_native_surface_set(o, ns);
4741 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4743 Evas_Native_Surface ns;
4746 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4747 if (cw->ec->input_only) return;
4748 if (cw->external_content) return;
4749 if (cw->render_update_lock.lock) return;
4752 memset(&ns, 0, sizeof(Evas_Native_Surface));
4756 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4757 set = (!cw->ec->shaped);
4759 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4763 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4767 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4770 if (cw->ec->input_only) return;
4773 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4774 _e_comp_object_alpha_set(cw);
4776 e_comp_object_native_surface_set(obj, cw->native);
4777 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4781 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4787 if (cw->blanked == set) return;
4789 _e_comp_object_alpha_set(cw);
4792 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4793 evas_object_image_data_set(cw->obj, NULL);
4797 e_comp_object_native_surface_set(obj, 1);
4798 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4802 _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)
4807 if (!_damage_trace) return;
4811 if (!evas_object_visible_get(cw->obj)) return;
4813 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4815 o = evas_object_rectangle_add(e_comp->evas);
4816 evas_object_layer_set(o, E_LAYER_MAX);
4817 evas_object_name_set(o, "damage_trace");
4818 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4819 evas_object_resize(o, dmg_w, dmg_h);
4820 evas_object_color_set(o, 0, 128, 0, 128);
4821 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4822 evas_object_pass_events_set(o, EINA_TRUE);
4823 evas_object_show(o);
4825 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4827 dmg_w, dmg_h, dmg_x, dmg_y,
4828 origin->w, origin->h, origin->x, origin->y);
4830 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4833 /* mark an object as dirty and setup damages */
4835 e_comp_object_dirty(Evas_Object *obj)
4838 Eina_Rectangle *rect;
4842 Eina_Bool dirty, visible;
4846 if (cw->external_content) return;
4847 if (!cw->redirected) return;
4848 if (cw->render_update_lock.lock)
4850 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4853 /* only actually dirty if pixmap is available */
4854 if (!e_pixmap_resource_get(cw->ec->pixmap))
4856 // e_pixmap_size_get returns last attached buffer size
4857 // eventhough it is destroyed
4858 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4861 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4862 visible = cw->visible;
4863 if (!dirty) w = h = 1;
4864 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4866 evas_object_image_data_set(cw->obj, NULL);
4867 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4868 evas_object_image_size_set(cw->obj, tw, th);
4869 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4870 if (cw->pending_updates)
4871 eina_tiler_area_size_set(cw->pending_updates, w, h);
4872 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4874 evas_object_image_pixels_dirty_set(o, dirty);
4876 evas_object_image_data_set(o, NULL);
4877 evas_object_image_size_set(o, tw, th);
4878 visible |= evas_object_visible_get(o);
4882 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4886 e_comp_object_native_surface_set(obj, 1);
4888 m = _e_comp_object_map_damage_transform_get(cw->ec);
4889 it = eina_tiler_iterator_new(cw->updates);
4890 EINA_ITERATOR_FOREACH(it, rect)
4892 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4893 * of evas engine and doesn't convert damage according to evas_map.
4894 * so damage of evas_object_image use surface coordinate.
4898 int damage_x, damage_y, damage_w, damage_h;
4900 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4901 &damage_x, &damage_y, &damage_w, &damage_h);
4902 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4903 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4907 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4908 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4911 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4912 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4913 if (cw->pending_updates)
4914 eina_tiler_rect_add(cw->pending_updates, rect);
4916 eina_iterator_free(it);
4917 if (m) e_map_free(m);
4918 if (cw->pending_updates)
4919 eina_tiler_clear(cw->updates);
4922 cw->pending_updates = cw->updates;
4923 cw->updates = eina_tiler_new(w, h);
4924 eina_tiler_tile_size_set(cw->updates, 1, 1);
4926 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4927 evas_object_smart_callback_call(obj, "dirty", NULL);
4928 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4929 /* force render if main object is hidden but mirrors are visible */
4930 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4931 e_comp_object_render(obj);
4935 e_comp_object_render(Evas_Object *obj)
4942 API_ENTRY EINA_FALSE;
4944 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4945 if (cw->ec->input_only) return EINA_TRUE;
4946 if (cw->external_content) return EINA_TRUE;
4947 if (cw->native) return EINA_FALSE;
4948 /* if comp object is not redirected state, comp object should not be set by newly committed data
4949 because image size of comp object is 1x1 and it should not be shown on canvas */
4950 if (!cw->redirected) return EINA_TRUE;
4951 if (cw->render_update_lock.lock)
4953 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4956 e_comp_object_render_update_del(obj);
4957 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4959 if (!cw->pending_updates)
4961 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4962 evas_object_image_data_set(cw->obj, NULL);
4963 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4964 evas_object_image_data_set(o, NULL);
4968 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4970 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4972 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4975 e_pixmap_image_refresh(cw->ec->pixmap);
4976 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4979 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4980 e_pixmap_image_data_ref(cw->ec->pixmap);
4982 /* set pixel data */
4983 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4984 _e_comp_object_alpha_set(cw);
4985 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4987 evas_object_image_data_set(o, pix);
4988 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4989 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4992 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4994 e_comp_client_post_update_add(cw->ec);
4999 /* create a duplicate of an evas object */
5001 e_comp_object_util_mirror_add(Evas_Object *obj)
5005 unsigned int *pix = NULL;
5006 Eina_Bool argb = EINA_FALSE;
5011 cw = evas_object_data_get(obj, "comp_mirror");
5014 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5015 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5016 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5017 evas_object_image_alpha_set(o, 1);
5018 evas_object_image_source_set(o, obj);
5021 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5022 if (cw->external_content)
5024 ERR("%p of client %p is external content.", obj, cw->ec);
5027 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5028 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5029 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5030 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5031 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5032 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5033 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5034 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5035 evas_object_data_set(o, "comp_mirror", cw);
5037 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5038 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5040 evas_object_image_size_set(o, tw, th);
5043 pix = evas_object_image_data_get(cw->obj, 0);
5049 evas_object_image_native_surface_set(o, cw->ns);
5052 Evas_Native_Surface ns;
5053 memset(&ns, 0, sizeof(Evas_Native_Surface));
5054 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5055 evas_object_image_native_surface_set(o, &ns);
5060 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5061 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5063 (e_pixmap_image_exists(cw->ec->pixmap)))
5064 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5066 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5073 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5074 evas_object_image_pixels_dirty_set(o, dirty);
5075 evas_object_image_data_set(o, pix);
5076 evas_object_image_data_set(cw->obj, pix);
5078 evas_object_image_data_update_add(o, 0, 0, tw, th);
5083 //////////////////////////////////////////////////////
5086 e_comp_object_effect_allowed_get(Evas_Object *obj)
5088 API_ENTRY EINA_FALSE;
5090 if (!cw->shobj) return EINA_FALSE;
5091 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5092 return !e_comp_config_get()->match.disable_borders;
5095 /* setup an api effect for a client */
5097 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5100 Eina_Stringshare *grp;
5101 E_Comp_Config *config;
5102 Eina_Bool loaded = EINA_FALSE;
5104 API_ENTRY EINA_FALSE;
5105 if (!cw->shobj) return EINA_FALSE; //input window
5107 if (!effect) effect = "none";
5108 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5110 config = e_comp_config_get();
5111 if ((config) && (config->effect_file))
5113 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5115 cw->effect_set = EINA_TRUE;
5122 edje_object_file_get(cw->effect_obj, NULL, &grp);
5123 cw->effect_set = !eina_streq(effect, "none");
5124 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5125 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5127 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5128 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5129 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5131 if (cw->effect_running)
5133 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5136 cw->effect_set = EINA_FALSE;
5137 return cw->effect_set;
5141 if (cw->effect_running)
5143 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5146 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5147 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5148 if (cw->effect_clip)
5150 evas_object_clip_unset(cw->clip);
5151 cw->effect_clip = 0;
5153 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5155 _e_comp_object_dim_update(cw);
5157 return cw->effect_set;
5160 /* set params for embryo scripts in effect */
5162 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5164 Edje_Message_Int_Set *msg;
5168 EINA_SAFETY_ON_NULL_RETURN(params);
5169 EINA_SAFETY_ON_FALSE_RETURN(count);
5170 if (!cw->effect_set) return;
5172 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5173 msg->count = (int)count;
5174 for (x = 0; x < count; x++)
5175 msg->val[x] = params[x];
5176 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5177 edje_object_message_signal_process(cw->effect_obj);
5181 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5183 Edje_Signal_Cb end_cb;
5185 E_Comp_Object *cw = data;
5187 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5188 cw->effect_running = 0;
5189 if (!_e_comp_object_animating_end(cw)) return;
5191 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5193 evas_object_data_del(cw->smart_obj, "effect_running");
5194 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5195 e_comp_visibility_calculation_set(EINA_TRUE);
5198 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5199 if (!end_cb) return;
5200 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5201 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5202 end_cb(end_data, cw->smart_obj, emission, source);
5205 /* clip effect to client's zone */
5207 e_comp_object_effect_clip(Evas_Object *obj)
5211 zone = e_comp_zone_find_by_ec(cw->ec);
5213 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5214 if (!cw->effect_clip_able) return;
5215 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5216 cw->effect_clip = 1;
5219 /* unclip effect from client's zone */
5221 e_comp_object_effect_unclip(Evas_Object *obj)
5224 if (!cw->effect_clip) return;
5225 evas_object_clip_unset(cw->smart_obj);
5226 cw->effect_clip = 0;
5229 /* start effect, running end_cb after */
5231 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5233 API_ENTRY EINA_FALSE;
5234 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5235 if (!cw->effect_set) return EINA_FALSE;
5237 if (cw->effect_running)
5239 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5242 e_comp_object_effect_clip(obj);
5243 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5245 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5246 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5247 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5248 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5250 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5251 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5253 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5254 _e_comp_object_animating_begin(cw);
5255 cw->effect_running = 1;
5259 /* stop a currently-running effect immediately */
5261 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5264 Edje_Signal_Cb end_cb_before = NULL;
5265 void *end_data_before = NULL;
5266 API_ENTRY EINA_FALSE;
5268 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5269 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5271 if (end_cb_before != end_cb) return EINA_TRUE;
5272 e_comp_object_effect_unclip(obj);
5273 if (cw->effect_clip)
5275 evas_object_clip_unset(cw->effect_obj);
5276 cw->effect_clip = 0;
5278 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5279 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5281 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5283 evas_object_data_del(cw->smart_obj, "effect_running");
5284 e_comp_visibility_calculation_set(EINA_TRUE);
5287 cw->effect_running = 0;
5288 ret = _e_comp_object_animating_end(cw);
5290 if ((ret) && (end_cb_before))
5292 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5293 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5300 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5302 return a->pri - b->pri;
5305 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5306 E_API E_Comp_Object_Mover *
5307 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5309 E_Comp_Object_Mover *prov;
5311 prov = E_NEW(E_Comp_Object_Mover, 1);
5312 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5313 prov->func = provider;
5314 prov->data = (void*)data;
5317 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5318 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5323 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5325 EINA_SAFETY_ON_NULL_RETURN(prov);
5326 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5331 e_comp_object_effect_object_get(Evas_Object *obj)
5335 return cw->effect_obj;
5339 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5341 API_ENTRY EINA_FALSE;
5342 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5343 if (!cw->effect_set) return EINA_FALSE;
5350 ////////////////////////////////////
5353 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5355 if (e_comp->autoclose.obj)
5357 e_comp_ungrab_input(0, 1);
5358 if (e_comp->autoclose.del_cb)
5359 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5360 else if (!already_del)
5362 evas_object_hide(e_comp->autoclose.obj);
5363 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5365 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5367 e_comp->autoclose.obj = NULL;
5368 e_comp->autoclose.data = NULL;
5369 e_comp->autoclose.del_cb = NULL;
5370 e_comp->autoclose.key_cb = NULL;
5371 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5375 _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)
5377 _e_comp_object_autoclose_cleanup(0);
5381 _e_comp_object_autoclose_setup(Evas_Object *obj)
5383 if (!e_comp->autoclose.rect)
5385 /* create rect just below autoclose object to catch mouse events */
5386 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5387 evas_object_move(e_comp->autoclose.rect, 0, 0);
5388 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5389 evas_object_show(e_comp->autoclose.rect);
5390 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5391 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5392 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5393 e_comp_grab_input(0, 1);
5395 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5396 evas_object_focus_set(obj, 1);
5400 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5402 _e_comp_object_autoclose_setup(obj);
5403 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5407 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5409 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5410 _e_comp_object_autoclose_cleanup(1);
5411 if (e_client_focused_get()) return;
5413 E_Zone *zone = e_zone_current_get();
5416 e_zone_focus_reset(zone);
5420 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5424 if (e_comp->autoclose.obj)
5426 if (e_comp->autoclose.obj == obj) return;
5427 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5428 e_comp->autoclose.obj = obj;
5429 e_comp->autoclose.del_cb = del_cb;
5430 e_comp->autoclose.key_cb = cb;
5431 e_comp->autoclose.data = (void*)data;
5432 if (evas_object_visible_get(obj))
5433 _e_comp_object_autoclose_setup(obj);
5435 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5436 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5439 e_comp->autoclose.obj = obj;
5440 e_comp->autoclose.del_cb = del_cb;
5441 e_comp->autoclose.key_cb = cb;
5442 e_comp->autoclose.data = (void*)data;
5443 if (evas_object_visible_get(obj))
5444 _e_comp_object_autoclose_setup(obj);
5446 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5447 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5451 e_comp_object_is_animating(Evas_Object *obj)
5455 return cw->animating;
5459 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5463 if ((cw->external_content) &&
5464 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5466 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5467 "But current external content is %d object for %p.",
5468 cw->content_type, cw->ec);
5472 cw->user_alpha_set = EINA_TRUE;
5473 cw->user_alpha = alpha;
5475 if (!cw->obj) return;
5477 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5479 evas_object_image_alpha_set(cw->obj, alpha);
5481 if ((!cw->native) && (!cw->external_content))
5482 evas_object_image_data_set(cw->obj, NULL);
5486 e_comp_object_alpha_get(Evas_Object *obj)
5488 API_ENTRY EINA_FALSE;
5490 return evas_object_image_alpha_get(cw->obj);
5494 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5496 Eina_Bool mask_set = EINA_FALSE;
5500 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5501 if (cw->ec->input_only) return;
5508 o = evas_object_rectangle_add(e_comp->evas);
5509 evas_object_color_set(o, 0, 0, 0, 0);
5510 evas_object_clip_set(o, cw->clip);
5511 evas_object_smart_member_add(o, obj);
5512 evas_object_move(o, 0, 0);
5513 evas_object_resize(o, cw->w, cw->h);
5514 /* save render op value to restore when clear a mask.
5516 * NOTE: DO NOT change the render op on ec->frame while mask object
5517 * is set. it will overwrite the changed op value. */
5518 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5519 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5520 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5521 if (cw->visible) evas_object_show(o);
5524 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5525 ELOGF("COMP", " |mask_obj", cw->ec);
5526 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5533 evas_object_smart_member_del(cw->mask.obj);
5534 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5536 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5537 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5543 e_comp_object_mask_has(Evas_Object *obj)
5545 API_ENTRY EINA_FALSE;
5547 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5551 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5556 if ((cw->external_content) &&
5557 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5559 WRN("Can set up size to ONLY evas \"image\" object. "
5560 "But current external content is %d object for %p.",
5561 cw->content_type, cw->ec);
5565 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5567 evas_object_image_size_set(cw->obj, tw, th);
5571 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5573 Eina_Bool transform_set = EINA_FALSE;
5575 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5576 if (cw->ec->input_only) return;
5578 transform_set = !!set;
5582 if (!cw->transform_bg_obj)
5584 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5585 evas_object_move(o, 0, 0);
5586 evas_object_resize(o, 1, 1);
5587 if (cw->transform_bg_color.a >= 255)
5588 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5590 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5591 evas_object_color_set(o,
5592 cw->transform_bg_color.r,
5593 cw->transform_bg_color.g,
5594 cw->transform_bg_color.b,
5595 cw->transform_bg_color.a);
5596 if (cw->visible) evas_object_show(o);
5598 cw->transform_bg_obj = o;
5599 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5601 _e_comp_object_transform_obj_stack_update(obj);
5605 if (cw->transform_bg_obj)
5607 evas_object_smart_member_del(cw->transform_bg_obj);
5608 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5614 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5618 cw->transform_bg_color.r = r;
5619 cw->transform_bg_color.g = g;
5620 cw->transform_bg_color.b = b;
5621 cw->transform_bg_color.a = a;
5623 if (cw->transform_bg_obj)
5625 evas_object_color_set(cw->transform_bg_obj,
5626 cw->transform_bg_color.r,
5627 cw->transform_bg_color.g,
5628 cw->transform_bg_color.b,
5629 cw->transform_bg_color.a);
5634 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5637 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5638 if (cw->ec->input_only) return;
5639 if (!cw->transform_bg_obj) return;
5641 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5645 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5648 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5649 if (cw->ec->input_only) return;
5650 if (!cw->transform_bg_obj) return;
5652 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5656 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5658 Eina_Bool transform_set = EINA_FALSE;
5660 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5661 if (cw->ec->input_only) return;
5663 transform_set = !!set;
5667 if (!cw->transform_tranp_obj)
5669 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5670 evas_object_move(o, 0, 0);
5671 evas_object_resize(o, 1, 1);
5672 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5673 evas_object_color_set(o, 0, 0, 0, 0);
5674 if (cw->visible) evas_object_show(o);
5676 cw->transform_tranp_obj = o;
5677 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5678 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5679 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5681 _e_comp_object_transform_obj_stack_update(obj);
5685 if (cw->transform_tranp_obj)
5687 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5688 evas_object_smart_member_del(cw->transform_tranp_obj);
5689 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5695 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5698 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5699 if (cw->ec->input_only) return;
5700 if (!cw->transform_tranp_obj) return;
5702 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5706 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5709 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5710 if (cw->ec->input_only) return;
5711 if (!cw->transform_tranp_obj) return;
5713 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5717 e_comp_object_layer_update(Evas_Object *obj,
5718 Evas_Object *above, Evas_Object *below)
5720 E_Comp_Object *cw2 = NULL;
5721 Evas_Object *o = NULL;
5726 if (cw->ec->layer_block) return;
5727 if ((above) && (below))
5729 ERR("Invalid layer update request! cw=%p", cw);
5737 layer = evas_object_layer_get(o);
5738 cw2 = evas_object_data_get(o, "comp_obj");
5741 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5743 o = evas_object_above_get(o);
5744 if ((!o) || (o == cw->smart_obj)) break;
5745 if (evas_object_layer_get(o) != layer)
5747 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5752 ec = e_client_top_get();
5753 if (ec) o = ec->frame;
5756 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5760 _e_comp_object_layers_remove(cw);
5763 if (cw2->layer > cw->layer)
5764 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5765 else if (cw2->layer == cw->layer)
5768 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5770 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5772 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5775 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5778 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5782 e_comp_object_layer_get(Evas_Object *obj)
5789 e_comp_object_content_set(Evas_Object *obj,
5790 Evas_Object *content,
5791 E_Comp_Object_Content_Type type)
5793 API_ENTRY EINA_FALSE;
5795 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5796 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5797 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5801 ERR("Can't set e.swallow.content to requested content. "
5802 "Previous comp object should not be changed at all.");
5806 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5808 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5809 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5811 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5812 type, content, cw->ec, cw->ec->pixmap);
5816 cw->external_content = EINA_TRUE;
5819 cw->content_type = type;
5820 e_util_size_debug_set(cw->obj, 1);
5821 evas_object_name_set(cw->obj, "cw->obj");
5822 _e_comp_object_alpha_set(cw);
5825 _e_comp_object_shadow_setup(cw);
5831 e_comp_object_content_unset(Evas_Object *obj)
5833 API_ENTRY EINA_FALSE;
5835 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5836 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5838 if (!cw->obj && !cw->ec->visible)
5840 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5844 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5846 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5852 if (cw->frame_object)
5853 edje_object_part_unswallow(cw->frame_object, cw->obj);
5855 edje_object_part_unswallow(cw->shobj, cw->obj);
5857 evas_object_del(cw->obj);
5858 evas_object_hide(cw->obj);
5862 cw->external_content = EINA_FALSE;
5863 if (cw->ec->is_cursor)
5866 DBG("%p is cursor surface..", cw->ec);
5867 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5869 evas_object_resize(cw->ec->frame, pw, ph);
5870 evas_object_hide(cw->ec->frame);
5875 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5876 cw->obj = evas_object_image_filled_add(e_comp->evas);
5877 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5878 e_util_size_debug_set(cw->obj, 1);
5879 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5880 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5881 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5882 evas_object_name_set(cw->obj, "cw->obj");
5883 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5884 _e_comp_object_alpha_set(cw);
5887 _e_comp_object_shadow_setup(cw);
5892 _e_comp_intercept_show_helper(cw);
5896 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5897 e_comp_object_dirty(cw->smart_obj);
5898 e_comp_object_render(cw->smart_obj);
5899 e_comp_object_render_update_add(obj);
5904 EINTERN Evas_Object *
5905 e_comp_object_content_get(Evas_Object *obj)
5909 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5911 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5913 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5920 E_API E_Comp_Object_Content_Type
5921 e_comp_object_content_type_get(Evas_Object *obj)
5923 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5925 return cw->content_type;
5929 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5932 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5933 E_Comp_Config *conf = e_comp_config_get();
5934 if (cw->ec->input_only) return;
5935 if (!conf->dim_rect_enable) return;
5937 cw->dim.mask_set = mask_set;
5943 if (!cw->dim.enable) return;
5944 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5948 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5950 Eina_Bool mask_set = EINA_FALSE;
5954 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5955 E_Comp_Config *conf = e_comp_config_get();
5956 if (cw->ec->input_only) return;
5957 if (!conf->dim_rect_enable) return;
5963 if (cw->dim.mask_obj)
5965 evas_object_smart_member_del(cw->dim.mask_obj);
5966 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5969 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);
5970 o = evas_object_rectangle_add(e_comp->evas);
5971 evas_object_color_set(o, 0, 0, 0, 0);
5972 evas_object_smart_member_add(o, obj);
5973 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5974 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5976 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5977 if (cw->visible) evas_object_show(o);
5979 cw->dim.mask_obj = o;
5980 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5982 evas_object_layer_set(cw->dim.mask_obj, 9998);
5986 if (cw->dim.mask_obj)
5988 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5989 evas_object_smart_member_del(cw->dim.mask_obj);
5990 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5996 e_comp_object_dim_client_set(E_Client *ec)
5998 E_Comp_Config *conf = e_comp_config_get();
6000 if (!conf->dim_rect_enable) return ;
6001 if (dim_client == ec) return;
6003 Eina_Bool prev_dim = EINA_FALSE;
6004 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6006 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6007 prev_dim = EINA_TRUE;
6009 if (prev_dim && dim_client->visible && ec)
6011 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6012 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6016 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6017 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6023 e_comp_object_dim_client_get(void)
6025 E_Comp_Config *conf = e_comp_config_get();
6027 if (!conf->dim_rect_enable ) return NULL;
6033 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6036 char emit[32] = "\0";
6037 E_Comp_Config *conf = e_comp_config_get();
6040 if (!conf->dim_rect_enable) return;
6041 if (!cw->effect_obj) return;
6042 if (enable == cw->dim.enable) return;
6044 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6045 if (noeffect || !conf->dim_rect_effect)
6047 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6051 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6054 cw->dim.enable = enable;
6056 if (cw->dim.mask_set && !enable)
6058 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6059 edje_object_signal_emit(cw->effect_obj, emit, "e");
6061 else if (cw->dim.mask_set && enable)
6063 edje_object_signal_emit(cw->effect_obj, emit, "e");
6064 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6068 edje_object_signal_emit(cw->effect_obj, emit, "e");
6073 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6075 API_ENTRY EINA_FALSE;
6076 E_Comp_Config *conf = e_comp_config_get();
6078 if (!ec) return EINA_FALSE;
6079 if (!conf->dim_rect_enable) return EINA_FALSE;
6081 if (cw->dim.enable) return EINA_TRUE;
6087 _e_comp_object_dim_update(E_Comp_Object *cw)
6089 E_Comp_Config *conf = e_comp_config_get();
6092 if (!conf->dim_rect_enable) return;
6093 if (!cw->effect_obj) return;
6096 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6097 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6099 if (cw->dim.mask_set)
6101 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6107 e_comp_object_clear(Evas_Object *obj)
6111 _e_comp_object_clear(cw);
6115 e_comp_object_hwc_update_exists(Evas_Object *obj)
6117 API_ENTRY EINA_FALSE;
6118 return cw->hwc_need_update;
6123 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6126 cw->hwc_need_update = set;
6130 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6132 API_ENTRY EINA_FALSE;
6133 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6137 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6140 if (cw->indicator.obj != indicator)
6141 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6142 cw->indicator.obj = indicator;
6143 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6147 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6150 if (cw->indicator.obj != indicator) return;
6151 cw->indicator.obj = NULL;
6152 edje_object_part_unswallow(cw->shobj, indicator);
6156 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6159 Edje_Message_Int_Set *msg;
6161 if (!cw->indicator.obj) return;
6163 cw->indicator.w = w;
6164 cw->indicator.h = h;
6166 if (!cw->shobj) return;
6168 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6172 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6173 edje_object_message_signal_process(cw->shobj);
6176 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6178 e_comp_object_map_update(Evas_Object *obj)
6181 E_Client *ec = cw->ec;
6182 E_Comp_Wl_Client_Data *cdata;
6184 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6187 int l, remain = sizeof buffer;
6190 if (e_object_is_del(E_OBJECT(ec))) return;
6191 cdata = e_client_cdata_get(ec);
6194 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6195 * when new buffer is attached.
6197 if (!cdata->buffer_ref.buffer) return;
6199 if ((!cw->redirected) ||
6200 (e_client_video_hw_composition_check(ec)) ||
6201 (!e_comp_wl_output_buffer_transform_get(ec) &&
6202 cdata->scaler.buffer_viewport.buffer.scale == 1))
6204 if (evas_object_map_enable_get(cw->effect_obj))
6206 ELOGF("TRANSFORM", "map: disable", cw->ec);
6207 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6208 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6209 evas_object_resize(cw->effect_obj, tw, th);
6216 EINA_SAFETY_ON_NULL_RETURN(map);
6218 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6224 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6226 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6227 e_map_point_image_uv_set(map, 0, x, y);
6228 l = snprintf(p, remain, "%d,%d", x, y);
6229 p += l, remain -= l;
6231 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6232 e_map_point_image_uv_set(map, 1, x, y);
6233 l = snprintf(p, remain, " %d,%d", x, y);
6234 p += l, remain -= l;
6236 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6237 e_map_point_image_uv_set(map, 2, x, y);
6238 l = snprintf(p, remain, " %d,%d", x, y);
6239 p += l, remain -= l;
6241 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6242 e_map_point_image_uv_set(map, 3, x, y);
6243 l = snprintf(p, remain, " %d,%d", x, y);
6244 p += l, remain -= l;
6246 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6248 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6250 e_comp_object_map_set(cw->effect_obj, map);
6251 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6255 /* if there's screen rotation with comp mode, then ec->effect_obj and
6256 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6258 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6259 evas_object_resize(cw->effect_obj, tw, th);
6263 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6265 API_ENTRY EINA_FALSE;
6267 cw->render_trace = set;
6273 e_comp_object_native_usable_get(Evas_Object *obj)
6275 API_ENTRY EINA_FALSE;
6276 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6278 if (cw->ec->input_only) return EINA_FALSE;
6279 if (cw->external_content) return EINA_FALSE;
6280 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6282 /* just return true value, if it is normal case */
6283 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6286 Evas_Native_Surface *ns;
6287 ns = evas_object_image_native_surface_get(cw->obj);
6289 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6292 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6300 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6302 API_ENTRY EINA_FALSE;
6303 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6304 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6305 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6309 case E_COMP_IMAGE_FILTER_BLUR:
6310 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6312 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6313 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6315 case E_COMP_IMAGE_FILTER_INVERSE:
6316 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6318 case E_COMP_IMAGE_FILTER_NONE:
6320 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6324 cw->image_filter = filter;
6329 EINTERN E_Comp_Image_Filter
6330 e_comp_object_image_filter_get(Evas_Object *obj)
6332 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6333 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6334 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6335 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6337 return cw->image_filter;
6341 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6345 if (!_damage_trace) return;
6347 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6348 evas_object_del(obj);
6350 _damage_trace_post_objs = NULL;
6354 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6356 if (!_damage_trace) return;
6358 _damage_trace_post_objs = _damage_trace_objs;
6359 _damage_trace_objs = NULL;
6363 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6365 if (_damage_trace == onoff) return;
6369 evas_event_callback_add(e_comp->evas,
6370 EVAS_CALLBACK_RENDER_PRE,
6371 _e_comp_object_damage_trace_render_pre_cb,
6374 evas_event_callback_add(e_comp->evas,
6375 EVAS_CALLBACK_RENDER_POST,
6376 _e_comp_object_damage_trace_render_post_cb,
6383 EINA_LIST_FREE(_damage_trace_objs, obj)
6384 evas_object_del(obj);
6386 _damage_trace_objs = NULL;
6388 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6389 evas_object_del(obj);
6391 _damage_trace_post_objs = NULL;
6393 evas_event_callback_del(e_comp->evas,
6394 EVAS_CALLBACK_RENDER_PRE,
6395 _e_comp_object_damage_trace_render_pre_cb);
6397 evas_event_callback_del(e_comp->evas,
6398 EVAS_CALLBACK_RENDER_POST,
6399 _e_comp_object_damage_trace_render_post_cb);
6402 _damage_trace = onoff;
6406 e_comp_object_redirected_get(Evas_Object *obj)
6408 API_ENTRY EINA_FALSE;
6409 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6411 return cw->redirected;
6415 e_comp_object_color_visible_get(Evas_Object *obj)
6417 API_ENTRY EINA_FALSE;
6420 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6422 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6426 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6430 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6434 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6442 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6444 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6446 return e_map_set_to_comp_object(em, obj);
6450 e_comp_object_map_get(const Evas_Object *obj)
6452 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6454 return e_map_get_from_comp_object(obj);
6458 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6460 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6462 evas_object_map_enable_set(obj, enable);
6468 e_comp_object_render_update_lock(Evas_Object *obj)
6470 E_Comp_Wl_Buffer *buffer;
6471 struct wayland_tbm_client_queue *cqueue;
6473 API_ENTRY EINA_FALSE;
6475 if (cw->render_update_lock.lock == 0)
6477 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6479 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6480 if ((buffer) && (buffer->resource))
6482 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6484 wayland_tbm_server_client_queue_flush(cqueue);
6487 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6488 e_comp_object_render_update_del(obj);
6490 ELOGF("COMP", "Render update lock enabled", cw->ec);
6493 cw->render_update_lock.lock++;
6499 e_comp_object_render_update_unlock(Evas_Object *obj)
6503 if (cw->render_update_lock.lock == 0)
6506 cw->render_update_lock.lock--;
6508 if (cw->render_update_lock.lock == 0)
6511 if (cw->render_update_lock.pending_move_set)
6513 evas_object_move(obj,
6514 cw->render_update_lock.pending_move_x,
6515 cw->render_update_lock.pending_move_y);
6516 cw->render_update_lock.pending_move_x = 0;
6517 cw->render_update_lock.pending_move_y = 0;
6518 cw->render_update_lock.pending_move_set = EINA_FALSE;
6521 if (cw->render_update_lock.pending_resize_set)
6523 evas_object_resize(obj,
6524 cw->render_update_lock.pending_resize_w,
6525 cw->render_update_lock.pending_resize_h);
6526 cw->render_update_lock.pending_resize_w = 0;
6527 cw->render_update_lock.pending_resize_h = 0;
6528 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6531 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6533 if ((cw->ec->exp_iconify.buffer_flush) &&
6534 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6535 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6536 e_comp_object_clear(obj);
6538 e_comp_object_render_update_add(obj);
6540 ELOGF("COMP", "Render update lock disabled", cw->ec);
6545 e_comp_object_render_update_lock_get(Evas_Object *obj)
6547 API_ENTRY EINA_FALSE;
6549 if (cw->render_update_lock.lock > 0)
6556 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6560 if (cw->transparent.set)
6562 if (r) *r = cw->transparent.user_r;
6563 if (g) *g = cw->transparent.user_g;
6564 if (b) *b = cw->transparent.user_b;
6565 if (a) *a = cw->transparent.user_a;
6569 evas_object_color_get(obj, r, g, b, a);
6574 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6578 evas_object_render_op_set(cw->obj, op);
6581 EINTERN Evas_Render_Op
6582 e_comp_object_render_op_get(Evas_Object *obj)
6584 API_ENTRY EVAS_RENDER_BLEND;
6586 return evas_object_render_op_get(cw->obj);
6590 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6593 wl_signal_add(&cw->events.lower, listener);
6596 #ifdef REFACTOR_DESK_AREA
6598 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6601 wl_signal_add(&cw->events.raise, listener);
6606 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6609 wl_signal_add(&cw->events.show, listener);
6613 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6616 wl_signal_add(&cw->events.hide, listener);
6619 #ifdef REFACTOR_DESK_AREA
6621 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6624 wl_signal_add(&cw->events.set_layer, listener);
6628 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6631 wl_signal_add(&cw->events.stack_above, listener);
6635 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6638 wl_signal_add(&cw->events.stack_below, listener);