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
612 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
614 g_rec_mutex_lock(&e_comp->ec_list_mutex);
617 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));
619 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));
620 if ((!above) && (!below))
623 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
624 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
625 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
627 e_comp->layers[cw->layer].clients_count++;
629 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
633 _e_comp_object_layers_remove(E_Comp_Object *cw)
635 g_rec_mutex_lock(&e_comp->ec_list_mutex);
637 if (cw->ec && e_comp->layers[cw->layer].clients)
639 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
640 e_comp->layers[cw->layer].clients_count--;
643 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
647 /////////////////////////////////////
649 _e_comp_object_alpha_set(E_Comp_Object *cw)
651 Eina_Bool alpha = cw->ec->argb;
653 if ((cw->external_content) &&
654 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
659 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
660 if (cw->user_alpha_set) alpha = cw->user_alpha;
662 evas_object_image_alpha_set(cw->obj, alpha);
666 _e_comp_object_shadow(E_Comp_Object *cw)
668 if (e_client_util_shadow_state_get(cw->ec))
669 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
671 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
672 if (cw->frame_object)
673 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
674 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
677 /* convert from the surface coordinates to the buffer coordinates */
679 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
681 E_Comp_Wl_Buffer_Viewport *vp;
682 E_Comp_Wl_Client_Data *cdata;
686 cdata = e_client_cdata_get(ec);
688 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
695 vp = &cdata->scaler.buffer_viewport;
696 transform = e_comp_wl_output_buffer_transform_get(ec);
698 e_pixmap_size_get(ec->pixmap, &bw, &bh);
700 /* for subsurface, it should be swap 90 and 270 */
701 if (e_comp_wl_subsurface_check(ec))
704 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
705 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
706 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
707 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
713 case WL_OUTPUT_TRANSFORM_NORMAL:
714 default: tx = sx, ty = sy; break;
715 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
716 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
717 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
718 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
719 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
724 tx *= vp->buffer.scale;
725 ty *= vp->buffer.scale;
732 _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)
740 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
741 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
748 if (dw) *dw = MAX(x1, x2) - mx;
749 if (dh) *dh = MAX(y1, y2) - my;
753 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
754 int *dx, int *dy, int *dw, int *dh)
756 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
757 E_Util_Transform_Rect_Vertex sv, dv;
761 e_pixmap_size_get(ec->pixmap, &bw, &bh);
763 sv = e_util_transform_rect_to_vertices(&rect);
765 for (i = 0; i < 4; i++)
767 double x = 0.0, y = 0.0;
769 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
771 /* if evas decide coordinate is outside of map, it returns (0, 0)
772 in this case, full damage is added.
774 if ((i != 0) && (x == 0.0) && (y == 0.0))
777 dv.vertices[i].vertex[0] = x;
778 dv.vertices[i].vertex[1] = y;
779 dv.vertices[i].vertex[2] = 1.0;
780 dv.vertices[i].vertex[3] = 1.0;
783 rect = e_util_transform_vertices_to_rect(&dv);
785 if (dx) *dx = rect.x;
786 if (dy) *dy = rect.y;
787 if (dw) *dw = rect.w;
788 if (dh) *dh = rect.h;
802 _e_comp_object_map_damage_transform_get(E_Client *ec)
809 if (!e_client_transform_core_enable_get(ec))
812 m = e_client_map_get(ec);
816 e_pixmap_size_get(ec->pixmap, &bw, &bh);
817 if ((bw == 0) || (bh == 0))
830 e_map_point_coord_set(m2, 0, 0, 0, 0);
831 e_map_point_coord_set(m2, 1, bw, 0, 0);
832 e_map_point_coord_set(m2, 2, bw, bh, 0);
833 e_map_point_coord_set(m2, 3, 0, bh, 0);
835 for (i = 0; i < 4; i++)
839 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
840 e_map_point_image_uv_set(m2, i, map_x, map_y);
847 /////////////////////////////////////
849 /* handle evas mouse-in events on client object */
851 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
853 Evas_Event_Mouse_In *ev = event_info;
854 E_Comp_Object *cw = data;
856 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
859 /* handle evas mouse-out events on client object */
861 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
863 Evas_Event_Mouse_Out *ev = event_info;
864 E_Comp_Object *cw = data;
866 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
869 /* handle evas mouse wheel events on client object */
871 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
873 Evas_Event_Mouse_Wheel *ev = event_info;
874 E_Comp_Object *cw = data;
875 E_Binding_Event_Wheel ev2;
878 if (e_client_action_get()) return;
879 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
880 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
883 /* handle evas mouse down events on client object */
885 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
887 Evas_Event_Mouse_Down *ev = event_info;
888 E_Comp_Object *cw = data;
889 E_Binding_Event_Mouse_Button ev2;
892 if (e_client_action_get()) return;
893 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
894 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
897 /* handle evas mouse up events on client object */
899 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
901 Evas_Event_Mouse_Up *ev = event_info;
902 E_Comp_Object *cw = data;
903 E_Binding_Event_Mouse_Button ev2;
906 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
907 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
908 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
911 /* handle evas mouse movement events on client object */
913 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
915 Evas_Event_Mouse_Move *ev = event_info;
916 E_Comp_Object *cw = data;
919 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
920 e_client_mouse_move(cw->ec, &ev->cur.output);
922 /////////////////////////////////////
924 /* helper function for checking compositor themes based on user-defined matches */
926 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
928 if (((m->title) && (!ec->netwm.name)) ||
929 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
931 #if defined(__cplusplus) || defined(c_plusplus)
932 if (((m->clas) && (!ec->icccm.cpp_class)) ||
933 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
936 if (((m->clas) && (!ec->icccm.class)) ||
937 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
941 if (((m->role) && (!ec->icccm.window_role)) ||
942 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
948 if ((int)ec->netwm.type != m->primary_type)
951 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
954 if (m->borderless != 0)
958 if (e_client_util_borderless(ec))
960 if (!(((m->borderless == -1) && (!borderless)) ||
961 ((m->borderless == 1) && (borderless))))
968 if (((ec->icccm.transient_for != 0) ||
971 if (!(((m->dialog == -1) && (!dialog)) ||
972 ((m->dialog == 1) && (dialog))))
975 if (m->accepts_focus != 0)
977 int accepts_focus = 0;
979 if (ec->icccm.accepts_focus)
981 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
982 ((m->accepts_focus == 1) && (accepts_focus))))
991 if (!(((m->vkbd == -1) && (!vkbd)) ||
992 ((m->vkbd == 1) && (vkbd))))
997 if (!(((m->argb == -1) && (!ec->argb)) ||
998 ((m->argb == 1) && (ec->argb))))
1001 if (m->fullscreen != 0)
1003 int fullscreen = ec->fullscreen;
1005 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1006 ((m->fullscreen == 1) && (fullscreen))))
1011 if (!(m->modal == -1))
1017 /* function for setting up a client's compositor frame theme (cw->shobj) */
1019 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1023 Eina_List *list = NULL, *l;
1024 E_Input_Rect_Data *input_rect_data;
1025 E_Input_Rect_Smart_Data *input_rect_sd;
1027 Eina_Stringshare *reshadow_group = NULL;
1028 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1029 Eina_Stringshare *name, *title;
1030 E_Comp_Config *conf = e_comp_config_get();
1032 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1033 /* match correct client type */
1034 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1035 name = cw->ec->icccm.name;
1036 title = cw->ec->icccm.title;
1037 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1038 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1040 /* skipping here is mostly a hack for systray because I hate it */
1043 EINA_LIST_FOREACH(list, l, m)
1045 if (((m->name) && (!name)) ||
1046 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1048 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1051 no_shadow = m->no_shadow;
1052 if (m->shadow_style)
1054 /* fast effects are just themes with "/fast" appended and shorter effect times */
1057 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1058 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1060 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1062 /* default to non-fast style if fast not available */
1065 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1066 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1068 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1070 if (ok && m->visibility_effect)
1071 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1078 if (skip || (cw->ec->e.state.video))
1080 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1082 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1085 if (conf->shadow_style)
1089 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1090 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1092 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1096 snprintf(buf, sizeof(buf), "e/comp/frame/%s", 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);
1106 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1108 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1112 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1114 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1119 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1124 if (cw->ec->override)
1126 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1127 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1129 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1130 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
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);
1140 _e_comp_object_shadow(cw);
1143 if (focus || cw->ec->focused || cw->ec->override)
1144 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1146 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1148 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1150 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1151 /* visibility must always be enabled for re_manage clients to prevent
1152 * pop-in animations every time the user sees a persistent client again;
1153 * applying visibility for iconic clients prevents the client from getting
1156 if (cw->visible || cw->ec->re_manage)
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1161 /* breaks animation counter */
1162 if (cw->frame_object)
1164 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1165 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1166 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1167 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1177 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1180 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1182 if (input_rect_data->obj)
1184 pass_event_flag = EINA_TRUE;
1190 if (cw->indicator.obj)
1192 Evas_Object *indicator;
1193 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1194 if (indicator != cw->indicator.obj)
1196 edje_object_part_unswallow(cw->shobj, indicator);
1197 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1198 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1202 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1203 evas_object_pass_events_set(cw->obj, pass_event_flag);
1208 /////////////////////////////////////////////
1211 _e_comp_object_animating_begin(E_Comp_Object *cw)
1214 if (cw->animating == 1)
1216 e_comp->animating++;
1218 e_object_ref(E_OBJECT(cw->ec));
1223 _e_comp_object_animating_end(E_Comp_Object *cw)
1232 if (cw->ec->launching)
1234 if (!cw->ec->extra_animating)
1236 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1237 cw->ec->launching = EINA_FALSE;
1238 if (cw->ec->first_mapped)
1240 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1241 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1244 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1248 e_comp->animating--;
1249 cw->showing = cw->hiding = 0;
1251 if (e_comp->animating == 0)
1252 e_comp_visibility_calculation_set(EINA_TRUE);
1253 /* remove ref from animation start, account for possibility of deletion from unref */
1254 return !!e_object_unref(E_OBJECT(cw->ec));
1260 /* handle the end of a compositor animation */
1262 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1264 E_Comp_Object *cw = data;
1266 /* visible clients which have never been sized are a bug */
1267 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1268 CRI("ACK! ec:%p", cw->ec);
1269 if (!_e_comp_object_animating_end(cw)) return;
1270 if (cw->animating) return;
1271 /* hide only after animation finishes to guarantee a full run of the animation */
1272 if (!cw->defer_hide) return;
1273 if ((!strcmp(emission, "e,action,hide,done")) ||
1274 (!strcmp(emission, "e,action,done")) ||
1275 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1277 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1278 evas_object_hide(cw->smart_obj);
1282 /* run a visibility compositor effect if available, return false if object is dead */
1284 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1290 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1291 if (!cw->effect_running)
1292 _e_comp_object_animating_begin(cw);
1293 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1294 return _e_comp_object_animating_end(cw);
1295 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1296 return _e_comp_object_animating_end(cw);
1298 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1301 zone = e_comp_zone_find_by_ec(cw->ec);
1303 zw = zone->w, zh = zone->h;
1308 zone = e_comp_object_util_zone_get(cw->smart_obj);
1309 if (!zone) zone = e_zone_current_get();
1316 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1317 cw->w, cw->h, zw, zh, x, y}, 8);
1318 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1319 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1322 /////////////////////////////////////////////
1324 /* create necessary objects for clients that e manages */
1326 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1328 if (cw->set_mouse_callbacks) return;
1329 if (!cw->smart_obj) return;
1331 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1332 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1336 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1338 cw->set_mouse_callbacks = EINA_TRUE;
1342 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1344 if (!cw->set_mouse_callbacks) return;
1345 if (!cw->smart_obj) return;
1347 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1348 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1352 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1354 cw->set_mouse_callbacks = EINA_FALSE;
1358 _e_comp_object_setup(E_Comp_Object *cw)
1360 cw->clip = evas_object_rectangle_add(e_comp->evas);
1361 evas_object_move(cw->clip, -9999, -9999);
1362 evas_object_resize(cw->clip, 999999, 999999);
1363 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1364 cw->effect_obj = edje_object_add(e_comp->evas);
1365 evas_object_move(cw->effect_obj, cw->x, cw->y);
1366 evas_object_clip_set(cw->effect_obj, cw->clip);
1367 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1368 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1369 cw->shobj = edje_object_add(e_comp->evas);
1370 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1371 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1372 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1374 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1375 if (cw->ec->override)
1377 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1378 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1379 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1381 else if (!cw->ec->input_only)
1383 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1384 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1385 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1387 cw->real_hid = !cw->ec->input_only;
1388 if (!cw->ec->input_only)
1390 e_util_size_debug_set(cw->effect_obj, 1);
1391 _e_comp_object_mouse_event_callback_set(cw);
1394 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1395 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1396 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1397 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1398 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1399 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1401 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1404 /////////////////////////////////////////////
1406 /* for fast path evas rendering; only called during render */
1408 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1410 E_Comp_Object *cw = data;
1411 E_Client *ec = cw->ec;
1413 int bx, by, bxx, byy;
1415 if (e_object_is_del(E_OBJECT(ec))) return;
1416 if (cw->external_content) return;
1417 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1418 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1421 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1422 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1424 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1426 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1427 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1431 bx = by = bxx = byy = 0;
1432 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1435 Edje_Message_Int_Set *msg;
1436 Edje_Message_Int msg2;
1437 Eina_Bool id = (bx || by || bxx || byy);
1439 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1445 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1447 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1451 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1452 e_comp_client_post_update_add(cw->ec);
1454 else if (e_comp_object_render(ec->frame))
1456 /* apply shape mask if necessary */
1457 if ((!cw->native) && (ec->shaped))
1458 e_comp_object_shape_apply(ec->frame);
1460 /* shaped clients get precise mouse events to handle transparent pixels */
1461 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1463 /* queue another render if client is still dirty; cannot refresh here. */
1464 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1465 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1467 if (cw->render_trace)
1469 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1475 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1477 E_Comp_Object *cw = data;
1478 E_Client *ec = cw->ec;
1480 if (e_object_is_del(E_OBJECT(ec))) return;
1481 if (cw->external_content) return;
1482 if (!e_comp->hwc) return;
1484 e_comp_client_render_list_add(cw->ec);
1486 if (!ec->hwc_window) return;
1488 e_hwc_windows_rendered_window_add(ec->hwc_window);
1491 /////////////////////////////////////////////
1494 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1496 E_Comp_Object *cw = data;
1499 if (cw->render_update_lock.lock)
1501 cw->render_update_lock.pending_move_x = x;
1502 cw->render_update_lock.pending_move_y = y;
1503 cw->render_update_lock.pending_move_set = EINA_TRUE;
1507 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1508 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1509 (cw->external_content))
1511 /* delay to move until the external content is unset */
1512 cw->ec->changes.pos = 1;
1517 if (cw->ec->move_after_resize)
1519 if ((x != cw->ec->x) || (y != cw->ec->y))
1521 if (!cw->ec->is_cursor)
1522 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1523 e_client_pos_set(cw->ec, x, y);
1524 cw->ec->changes.pos = 1;
1530 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1531 (cw->ec->manage_resize.resize_obj))
1533 e_client_pos_set(cw->ec, x, y);
1534 cw->ec->client.x = x + cw->client_inset.l;
1535 cw->ec->client.y = y + cw->client_inset.t;
1536 e_policy_visibility_client_defer_move(cw->ec);
1540 /* if frame_object does not exist, client_inset indicates CSD.
1541 * this means that ec->client matches cw->x/y, the opposite
1544 fx = (!cw->frame_object) * cw->client_inset.l;
1545 fy = (!cw->frame_object) * cw->client_inset.t;
1546 if ((cw->x == x + fx) && (cw->y == y + fy))
1548 if ((cw->ec->x != x) || (cw->ec->y != y))
1550 /* handle case where client tries to move to position and back very quickly */
1551 e_client_pos_set(cw->ec, x, y);
1552 cw->ec->client.x = x + cw->client_inset.l;
1553 cw->ec->client.y = y + cw->client_inset.t;
1557 if (!cw->ec->maximize_override)
1559 /* prevent moving in some directions while directionally maximized */
1560 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1562 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1565 ix = x + cw->client_inset.l;
1566 iy = y + cw->client_inset.t;
1567 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1568 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1569 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1571 /* prevent moving at all if move isn't allowed in current maximize state */
1572 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1573 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1576 zone = e_comp_zone_find_by_ec(cw->ec);
1579 cw->ec->changes.need_unmaximize = 1;
1580 cw->ec->saved.x = ix - zone->x;
1581 cw->ec->saved.y = iy - zone->y;
1582 cw->ec->saved.w = cw->ec->client.w;
1583 cw->ec->saved.h = cw->ec->client.h;
1587 /* only update during resize if triggered by resize */
1588 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1589 /* delay to move while surface waits paired commit serial*/
1590 if (e_client_pending_geometry_has(cw->ec))
1592 /* do nothing while waiting paired commit serial*/
1596 e_client_pos_set(cw->ec, x, y);
1597 if (cw->ec->new_client)
1599 /* don't actually do anything until first client idler loop */
1600 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1601 cw->ec->changes.pos = 1;
1606 /* only update xy position of client to avoid invalid
1607 * first damage region if it is not a new_client. */
1608 cw->ec->client.x = ix;
1609 cw->ec->client.y = iy;
1612 if (!cw->frame_object)
1614 evas_object_move(obj, x, y);
1619 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1621 E_Comp_Object *cw = data;
1622 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1625 if (cw->render_update_lock.lock)
1627 cw->render_update_lock.pending_resize_w = w;
1628 cw->render_update_lock.pending_resize_h = h;
1629 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1633 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1635 e_client_size_set(cw->ec, w, h);
1636 evas_object_resize(obj, w, h);
1640 /* if frame_object does not exist, client_inset indicates CSD.
1641 * this means that ec->client matches cw->w/h, the opposite
1644 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1645 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1646 if ((cw->w == w + fw) && (cw->h == h + fh))
1648 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1649 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1650 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1652 /* handle case where client tries to resize itself and back very quickly */
1653 e_client_size_set(cw->ec, w, h);
1654 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1655 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1656 evas_object_smart_callback_call(obj, "client_resize", NULL);
1660 /* guarantee that fullscreen is fullscreen */
1661 zone = e_comp_zone_find_by_ec(cw->ec);
1663 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1665 if (!e_client_transform_core_enable_get(cw->ec))
1668 /* calculate client size */
1669 iw = w - cw->client_inset.l - cw->client_inset.r;
1670 ih = h - cw->client_inset.t - cw->client_inset.b;
1671 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1673 /* prevent resizing while maximized depending on direction and config */
1674 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1676 Eina_Bool reject = EINA_FALSE;
1677 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1679 if (cw->ec->client.h != ih)
1681 cw->ec->saved.h = ih;
1682 cw->ec->saved.y = cw->ec->client.y - zone->y;
1683 reject = cw->ec->changes.need_unmaximize = 1;
1686 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1688 if (cw->ec->client.w != iw)
1690 cw->ec->saved.w = iw;
1691 cw->ec->saved.x = cw->ec->client.x - zone->x;
1692 reject = cw->ec->changes.need_unmaximize = 1;
1701 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1703 /* do nothing until client idler loops */
1704 if ((cw->ec->w != w) || (cw->ec->h != h))
1706 e_client_size_set(cw->ec, w, h);
1707 cw->ec->changes.size = 1;
1712 if (e_client_pending_geometry_has(cw->ec))
1714 /* do nothing while waiting paired commit serial*/
1718 e_client_size_set(cw->ec, w, h);
1720 cw->ec->client.w = iw;
1721 cw->ec->client.h = ih;
1722 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1724 /* The size of non-compositing window can be changed, so there is a
1725 * need to check that cw is H/W composited if cw is not redirected.
1726 * And of course we have to change size of evas object of H/W composited cw,
1727 * otherwise cw can't receive input events even if it is shown on the screen.
1729 Eina_Bool redirected = cw->redirected;
1731 redirected = e_comp_is_on_overlay(cw->ec);
1733 if ((!cw->ec->input_only) && (redirected) &&
1734 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1735 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1736 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1737 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1740 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1741 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1743 prev_w = cw->w, prev_h = cw->h;
1744 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1745 /* check shading and clamp to pixmap size for regular clients */
1746 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1747 (((w - fw != pw) || (h - fh != ph))))
1749 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1750 evas_object_smart_callback_call(obj, "client_resize", NULL);
1752 if (cw->frame_object || cw->ec->input_only)
1753 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1756 if ((cw->w == w) && (cw->h == h))
1758 /* going to be a noop resize which won't trigger smart resize */
1759 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1760 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1762 evas_object_resize(obj, w, h);
1766 evas_object_smart_callback_call(obj, "client_resize", NULL);
1769 if ((!cw->frame_object) && (!cw->ec->input_only))
1771 /* "just do it" for overrides */
1772 evas_object_resize(obj, w, h);
1774 if (!cw->ec->override)
1776 /* shape probably changed for non-overrides */
1781 /* this fixes positioning jiggles when using a resize mode
1782 * which also changes the client's position
1785 if (cw->frame_object)
1786 x = cw->x, y = cw->y;
1788 x = cw->ec->x, y = cw->ec->y;
1789 switch (cw->ec->resize_mode)
1791 case E_POINTER_RESIZE_BL:
1792 case E_POINTER_RESIZE_L:
1793 evas_object_move(obj, x + prev_w - cw->w, y);
1795 case E_POINTER_RESIZE_TL:
1796 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1798 case E_POINTER_RESIZE_T:
1799 case E_POINTER_RESIZE_TR:
1800 evas_object_move(obj, x, y + prev_h - cw->h);
1809 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1811 #ifdef REFACTOR_DESK_AREA
1812 E_Comp_Object *cw = data;
1813 E_Comp_Object_Data_Set_Layer layer_set_data;
1815 layer_set_data.cw = cw;
1816 layer_set_data.layer = layer;
1818 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1822 e_comp_render_queue();
1823 _e_comp_object_transform_obj_stack_update(obj);
1827 E_Comp_Object *cw = data;
1828 E_Comp_Wl_Client_Data *child_cdata;
1829 unsigned int l = e_comp_canvas_layer_map(layer);
1832 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1834 /* doing a compositor effect, follow directions */
1835 _e_comp_object_layer_set(obj, layer);
1836 if (layer == cw->ec->layer) //trying to put layer back
1840 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1841 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1842 if (cw->layer != l) goto layer_set;
1846 e_comp_render_queue();
1848 ec = e_client_above_get(cw->ec);
1849 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1850 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1851 ec = e_client_above_get(ec);
1852 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1854 ec = e_client_below_get(cw->ec);
1855 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1856 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1857 ec = e_client_below_get(ec);
1858 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1860 evas_object_stack_above(obj, ec->frame);
1865 if (ec && (cw->ec->parent == ec))
1867 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1868 evas_object_stack_above(obj, ec->frame);
1870 evas_object_stack_below(obj, ec->frame);
1873 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1879 if (cw->layer == l) return;
1880 if (e_comp_canvas_client_layer_map(layer) == 9999)
1881 return; //invalid layer for clients not doing comp effects
1882 if (cw->ec->fullscreen)
1884 cw->ec->saved.layer = layer;
1887 oldraise = e_config->transient.raise;
1889 /* clamp to valid client layer */
1890 layer = e_comp_canvas_client_layer_map_nearest(layer);
1891 cw->ec->layer = layer;
1892 if (e_config->transient.layer)
1895 Eina_List *list = eina_list_clone(cw->ec->transients);
1897 /* We need to set raise to one, else the child wont
1898 * follow to the new layer. It should be like this,
1899 * even if the user usually doesn't want to raise
1902 e_config->transient.raise = 1;
1903 EINA_LIST_FREE(list, child)
1905 child_cdata = e_client_cdata_get(child);
1906 if (child_cdata && !child_cdata->mapped)
1908 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1911 e_client_layer_set(child, layer);
1915 e_config->transient.raise = oldraise;
1917 _e_comp_object_layers_remove(cw);
1918 cw->layer = e_comp_canvas_layer_map(layer);
1919 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1920 //if (cw->ec->new_client)
1921 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1922 _e_comp_object_layer_set(obj, layer);
1923 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1924 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1925 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1927 /* can't stack a client above its own layer marker */
1928 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1930 if (!cw->visible) return;
1931 e_comp_render_queue();
1932 _e_comp_object_transform_obj_stack_update(obj);
1936 #ifdef REFACTOR_DESK_AREA
1938 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1941 #ifdef REFACTOR_DESK_AREA
1943 _e_comp_object_raise(Evas_Object *obj)
1946 _e_comp_object_raise(Evas_Object *obj)
1949 evas_object_raise(obj);
1951 if (evas_object_smart_smart_get(obj))
1953 E_Client *ec = e_comp_object_client_get(obj);
1955 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1959 #ifdef REFACTOR_DESK_AREA
1961 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1964 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1967 evas_object_lower(obj);
1969 if (evas_object_smart_smart_get(obj))
1971 E_Client *ec = e_comp_object_client_get(obj);
1974 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1975 #ifdef REFACTOR_DESK_AREA
1976 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1978 wl_signal_emit_mutable(&cw->events.lower, NULL);
1984 #ifdef REFACTOR_DESK_AREA
1986 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1989 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1992 evas_object_stack_above(obj, target);
1994 if (evas_object_smart_smart_get(obj))
1996 E_Client *ec = e_comp_object_client_get(obj);
1998 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2002 #ifdef REFACTOR_DESK_AREA
2004 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2007 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2010 evas_object_stack_below(obj, target);
2012 if (evas_object_smart_smart_get(obj))
2014 E_Client *ec = e_comp_object_client_get(obj);
2016 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2020 #ifdef REFACTOR_DESK_AREA
2022 e_comp_object_layer_set(Evas_Object *obj, short layer)
2025 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2028 evas_object_layer_set(obj, layer);
2030 if (evas_object_smart_smart_get(obj))
2032 E_Client *ec = e_comp_object_client_get(obj);
2034 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2038 #ifdef REFACTOR_DESK_AREA
2041 _e_comp_object_is_pending(E_Client *ec)
2045 if (!ec) return EINA_FALSE;
2047 topmost = e_comp_wl_topmost_parent_get(ec);
2049 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2053 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2055 E_Comp_Object *cw2 = NULL;
2058 Evas_Object *o = stack;
2059 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2061 /* We should consider topmost's layer_pending for subsurface */
2062 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2064 if (_e_comp_object_is_pending(cw->ec))
2065 e_comp_object_layer_update(cw->smart_obj,
2066 raising? stack : NULL,
2067 raising? NULL : stack);
2069 /* obey compositor effects! */
2070 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2071 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2072 stack_cb(cw->smart_obj, stack);
2073 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2074 evas_object_data_del(cw->smart_obj, "client_restack");
2078 cw2 = evas_object_data_get(o, "comp_obj");
2080 /* assume someone knew what they were doing during client init */
2081 if (cw->ec->new_client)
2082 layer = cw->ec->layer;
2083 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2084 layer = cw2->ec->layer;
2086 layer = evas_object_layer_get(stack);
2087 ecstack = e_client_below_get(cw->ec);
2088 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2090 evas_object_layer_set(cw->smart_obj, layer);
2091 /* we got our layer wrangled, return now! */
2092 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2095 /* check if we're stacking below another client */
2098 /* check for non-client layer object */
2099 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2101 /* find an existing client to use for layering
2102 * by walking up the object stack
2104 * this is guaranteed to be pretty quick since we'll either:
2105 * - run out of client layers
2106 * - find a stacking client
2108 o = evas_object_above_get(o);
2109 if ((!o) || (o == cw->smart_obj)) break;
2110 if (evas_object_layer_get(o) != layer)
2112 /* reached the top client layer somehow
2113 * use top client object
2115 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2118 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2119 * return here since the top client layer window
2124 ec = e_client_top_get();
2129 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2132 if (cw2 && cw->layer != cw2->layer)
2135 /* remove existing layers */
2136 _e_comp_object_layers_remove(cw);
2139 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2140 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2141 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2142 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2143 else //if no stacking objects found, either raise or lower
2144 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2147 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2149 /* find new object for stacking if cw2 is on state of layer_pending */
2150 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2152 E_Client *new_stack = NULL, *current_ec = NULL;
2153 current_ec = cw2->ec;
2156 while ((new_stack = e_client_below_get(current_ec)))
2158 current_ec = new_stack;
2159 if (new_stack == cw->ec) continue;
2160 if (new_stack->layer != cw2->ec->layer) break;
2161 if (!_e_comp_object_is_pending(new_stack)) break;
2163 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2164 stack = new_stack->frame;
2167 /* stack it above layer object */
2169 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2170 stack = e_comp->layers[below_layer].obj;
2175 while ((new_stack = e_client_above_get(current_ec)))
2177 current_ec = new_stack;
2178 if (new_stack == cw->ec) continue;
2179 if (new_stack->layer != cw2->ec->layer) break;
2180 if (!_e_comp_object_is_pending(new_stack)) break;
2182 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2183 stack = new_stack->frame;
2185 stack = e_comp->layers[cw2->layer].obj;
2189 /* set restack if stacking has changed */
2190 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2191 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2192 stack_cb(cw->smart_obj, stack);
2193 if (e_comp->layers[cw->layer].obj)
2194 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2196 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2198 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2199 evas_object_data_del(cw->smart_obj, "client_restack");
2200 if (!cw->visible) return;
2201 e_comp_render_queue();
2206 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2208 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2210 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2212 #ifdef REFACTOR_DESK_AREA
2213 E_Comp_Object *cw = data;
2214 E_Comp_Object_Data_Stack_Above stack_above_data;
2216 stack_above_data.cw = cw;
2217 stack_above_data.above_obj = above;
2219 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2221 if (evas_object_below_get(obj) == above)
2223 e_comp_object_layer_update(obj, above, NULL);
2227 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2229 _e_comp_object_transform_obj_stack_update(obj);
2230 _e_comp_object_transform_obj_stack_update(above);
2237 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2239 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2241 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2243 #ifdef REFACTOR_DESK_AREA
2244 E_Comp_Object *cw = data;
2245 E_Comp_Object_Data_Stack_Below stack_below_data;
2247 stack_below_data.cw = cw;
2248 stack_below_data.below_obj = below;
2250 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2253 e_comp_render_queue();
2255 if (evas_object_above_get(obj) == below)
2257 e_comp_object_layer_update(obj, NULL, below);
2261 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2263 if (evas_object_smart_smart_get(obj))
2264 _e_comp_object_transform_obj_stack_update(obj);
2265 if (evas_object_smart_smart_get(below))
2266 _e_comp_object_transform_obj_stack_update(below);
2273 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2275 E_Comp_Object *cw = data;
2277 #ifdef REFACTOR_DESK_AREA
2282 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2284 #ifdef REFACTOR_DESK_AREA
2285 wl_signal_emit_mutable(&cw->events.lower, cw);
2287 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2289 if (cw->ec->layer_pending)
2290 e_comp_object_layer_update(obj, NULL, obj);
2292 _e_comp_object_lower(cw, obj);
2295 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2296 o = evas_object_below_get(obj);
2297 _e_comp_object_layers_remove(cw);
2298 /* prepend to client list since this client should be the first item now */
2299 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2300 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2301 evas_object_data_set(obj, "client_restack", (void*)1);
2302 _e_comp_object_lower(cw, obj);
2303 evas_object_data_del(obj, "client_restack");
2304 if (!cw->visible) goto end;
2305 e_comp_render_queue();
2306 _e_comp_object_transform_obj_stack_update(obj);
2314 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2316 E_Comp_Object *cw = data;
2317 #ifdef REFACTOR_DESK_AREA
2323 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2325 #ifdef REFACTOR_DESK_AREA
2326 wl_signal_emit_mutable(&cw->events.raise, cw);
2328 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2330 if (cw->ec->layer_pending)
2332 int obj_layer = evas_object_layer_get(obj);
2333 if (cw->ec->layer != obj_layer)
2334 e_comp_object_layer_update(obj, NULL, NULL);
2337 _e_comp_object_raise(obj);
2340 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2341 o = evas_object_above_get(obj);
2342 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2344 /* still stack below override below the layer marker */
2345 for (op = o = e_comp->layers[cw->layer].obj;
2346 o && o != e_comp->layers[cw->layer - 1].obj;
2347 op = o, o = evas_object_below_get(o))
2349 if (evas_object_smart_smart_get(o))
2353 ec = e_comp_object_client_get(o);
2354 if (ec && (!ec->override)) break;
2357 _e_comp_object_stack_below(obj, op);
2358 e_client_focus_defer_set(cw->ec);
2360 if (!cw->visible) goto end;
2361 e_comp_render_queue();
2362 _e_comp_object_transform_obj_stack_update(obj);
2370 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2372 E_Comp_Object *cw = data;
2374 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2375 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2377 ELOGF("COMP", "Hide. intercepted", cw->ec);
2382 if (cw->ec->launching == EINA_TRUE)
2384 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2385 cw->ec->launching = EINA_FALSE;
2390 /* hidden flag = just do it */
2391 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2392 evas_object_hide(obj);
2394 wl_signal_emit_mutable(&cw->events.hide, NULL);
2399 if (cw->ec->input_only)
2401 /* input_only = who cares */
2402 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2403 evas_object_hide(obj);
2405 wl_signal_emit_mutable(&cw->events.hide, NULL);
2409 /* already hidden or currently animating */
2410 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2412 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2416 /* don't try hiding during shutdown */
2417 cw->defer_hide |= stopping;
2418 if (!cw->defer_hide)
2420 if ((!cw->ec->iconic) && (!cw->ec->override))
2421 /* unset delete requested so the client doesn't break */
2422 cw->ec->delete_requested = 0;
2423 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2425 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2426 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2429 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2432 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2434 _e_comp_object_animating_begin(cw);
2435 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2437 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2438 cw->defer_hide = !!cw->animating;
2440 e_comp_object_effect_set(obj, NULL);
2443 if (cw->animating) return;
2444 /* if we have no animations running, go ahead and hide */
2446 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2447 evas_object_hide(obj);
2449 wl_signal_emit_mutable(&cw->events.hide, NULL);
2453 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2455 E_Client *ec = cw->ec;
2458 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2460 if (ec->show_pending.count > 0)
2462 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2463 ec->show_pending.running = EINA_TRUE;
2467 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2468 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2470 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2475 ELOGF("COMP", "show_helper. cw(v:%d,a:%d,dh:%d,ct:%d,u:%p,s(%d,%d)), ec(i:%d(%d,%d),o:%d,g:%d,n:%d)", ec,
2476 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2477 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2480 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2483 if (ec->iconic && cw->animating)
2485 /* triggered during iconify animation */
2486 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2489 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2492 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2493 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2495 evas_object_move(cw->smart_obj, ec->x, ec->y);
2496 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2497 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2499 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2500 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2503 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2504 evas_object_show(cw->smart_obj);
2507 e_client_focus_defer_set(ec);
2511 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2515 pw = ec->client.w, ph = ec->client.h;
2517 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2519 ec->changes.visible = !ec->hidden;
2522 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2526 cw->updates = eina_tiler_new(pw, ph);
2529 ec->changes.visible = !ec->hidden;
2532 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2537 eina_tiler_tile_size_set(cw->updates, 1, 1);
2540 /* ignore until client idler first run */
2541 ec->changes.visible = !ec->hidden;
2544 ELOGF("COMP", "show_helper. return. new_client", ec);
2551 evas_object_move(cw->smart_obj, ec->x, ec->y);
2552 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2553 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2554 evas_object_show(cw->smart_obj);
2557 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2559 /* start_drag not received */
2560 ec->changes.visible = 1;
2563 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2566 /* re-set geometry */
2567 evas_object_move(cw->smart_obj, ec->x, ec->y);
2568 /* force resize in case it hasn't happened yet, or just to update size */
2569 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2570 if ((cw->w < 1) || (cw->h < 1))
2572 /* if resize didn't go through, try again */
2573 ec->visible = ec->changes.visible = 1;
2575 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2578 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2579 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2580 e_pixmap_clear(ec->pixmap);
2582 if (cw->real_hid && w && h)
2585 /* force comp theming in case it didn't happen already */
2586 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2587 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2588 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2591 /* only do the show if show is allowed */
2594 if (ec->internal) //internal clients render when they feel like it
2595 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2597 if (!e_client_is_iconified_by_client(ec)||
2598 e_policy_visibility_client_is_uniconic(ec))
2600 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2601 evas_object_show(cw->smart_obj);
2603 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2604 it is rendered in idle callback without native surface and
2605 compositor shows an empty frame if other objects aren't shown
2606 because job callback of e_comp called at the next loop.
2607 it causes a visual defect when windows are switched.
2611 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2612 e_comp_object_dirty(cw->smart_obj);
2613 e_comp_object_render(cw->smart_obj);
2618 wl_signal_emit_mutable(&cw->events.show, NULL);
2622 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2624 E_Comp_Object *cw = data;
2625 E_Client *ec = cw->ec;
2627 E_Input_Rect_Data *input_rect_data;
2628 E_Input_Rect_Smart_Data *input_rect_sd;
2631 if (ec->ignored) return;
2635 //INF("SHOW2 %p", ec);
2636 _e_comp_intercept_show_helper(cw);
2639 //INF("SHOW %p", ec);
2642 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2643 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2644 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2645 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2649 if ((!cw->obj) && (cw->external_content))
2651 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2655 _e_comp_object_setup(cw);
2658 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2659 cw->obj = evas_object_image_filled_add(e_comp->evas);
2660 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2661 e_util_size_debug_set(cw->obj, 1);
2662 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2663 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2664 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2665 evas_object_name_set(cw->obj, "cw->obj");
2666 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2668 _e_comp_object_alpha_set(cw);
2671 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2674 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2675 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2678 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2681 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2683 if (input_rect_data->obj)
2685 evas_object_geometry_set(input_rect_data->obj,
2686 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2687 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2688 input_rect_data->rect.w, input_rect_data->rect.h);
2695 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2697 _e_comp_intercept_show_helper(cw);
2701 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2703 E_Comp_Object *cw = data;
2707 /* note: this is here as it seems there are enough apps that do not even
2708 * expect us to emulate a look of focus but not actually set x input
2709 * focus as we do - so simply abort any focus set on such windows */
2710 /* be strict about accepting focus hint */
2711 /* be strict about accepting focus hint */
2712 if ((!ec->icccm.accepts_focus) &&
2713 (!ec->icccm.take_focus))
2717 if (e_client_focused_get() == ec)
2718 e_client_focused_set(NULL);
2720 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2721 evas_object_focus_set(obj, focus);
2725 if (focus && ec->lock_focus_out) return;
2726 if (e_object_is_del(E_OBJECT(ec)) && focus)
2727 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2729 /* filter focus setting based on current state */
2734 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2735 evas_object_focus_set(obj, focus);
2738 if ((ec->iconic) && (!ec->deskshow))
2740 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2742 /* don't focus an iconified window. that's silly! */
2743 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2744 e_client_uniconify(ec);
2745 e_client_focus_latest_set(ec);
2759 /* not yet visible, wait till the next time... */
2760 ec->want_focus = !ec->hidden;
2765 e_client_focused_set(ec);
2769 if (e_client_focused_get() == ec)
2770 e_client_focused_set(NULL);
2774 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2776 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2778 evas_object_focus_set(obj, focus);
2782 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2784 E_Comp_Object *cw = data;
2786 if (cw->transparent.set)
2788 cw->transparent.user_r = r;
2789 cw->transparent.user_g = g;
2790 cw->transparent.user_b = b;
2791 cw->transparent.user_a = a;
2793 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2795 cw->transparent.user_r,
2796 cw->transparent.user_g,
2797 cw->transparent.user_b,
2798 cw->transparent.user_a);
2802 evas_object_color_set(obj, r, g, b, a);
2805 ////////////////////////////////////////////////////
2808 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2810 int w, h, ox, oy, ow, oh;
2812 Eina_Bool pass_event_flag = EINA_FALSE;
2813 E_Input_Rect_Data *input_rect_data;
2814 E_Input_Rect_Smart_Data *input_rect_sd;
2816 if (cw->frame_object)
2818 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2819 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2820 /* set a fixed size, force edje calc, check size difference */
2821 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2822 edje_object_message_signal_process(cw->frame_object);
2823 edje_object_calc_force(cw->frame_object);
2824 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2825 cw->client_inset.l = ox;
2826 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2827 cw->client_inset.t = oy;
2828 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2829 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2830 evas_object_resize(cw->frame_object, w, h);
2834 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2837 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2839 if (input_rect_data->obj)
2841 pass_event_flag = EINA_TRUE;
2847 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2848 evas_object_pass_events_set(cw->obj, pass_event_flag);
2852 cw->client_inset.l = 0;
2853 cw->client_inset.r = 0;
2854 cw->client_inset.t = 0;
2855 cw->client_inset.b = 0;
2857 cw->client_inset.calc = !!cw->frame_object;
2861 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2863 E_Comp_Object *cw = data;
2867 /* - get current size
2869 * - readjust for new frame size
2872 w = cw->ec->w, h = cw->ec->h;
2873 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2875 _e_comp_object_frame_recalc(cw);
2877 if (!cw->ec->fullscreen)
2878 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2880 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2881 if (cw->ec->fullscreen)
2883 zone = e_comp_zone_find_by_ec(cw->ec);
2885 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2887 else if (cw->ec->new_client)
2889 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2890 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2891 evas_object_resize(cw->ec->frame, w, h);
2893 else if ((w != cw->ec->w) || (h != cw->ec->h))
2894 evas_object_resize(cw->ec->frame, w, h);
2898 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2900 E_Comp_Object *cw = data;
2902 _e_comp_object_shadow_setup(cw);
2903 if (cw->frame_object)
2905 _e_comp_object_shadow(cw);
2906 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2907 _e_comp_object_frame_recalc(cw);
2908 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2913 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2915 E_Comp_Object *cw = data;
2917 if (_e_comp_object_shadow_setup(cw))
2918 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2919 if (cw->frame_object)
2921 _e_comp_object_shadow(cw);
2922 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2923 _e_comp_object_frame_recalc(cw);
2924 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2929 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2931 E_Comp_Object *cw = data;
2933 if (cw->frame_object)
2935 _e_comp_object_shadow(cw);
2936 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2937 _e_comp_object_frame_recalc(cw);
2938 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2943 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2945 E_Comp_Object *cw = data;
2947 if (_e_comp_object_shadow_setup(cw))
2950 cw->ec->changes.size = 1;
2952 if (cw->frame_object)
2954 _e_comp_object_shadow(cw);
2955 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2956 _e_comp_object_frame_recalc(cw);
2957 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2962 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2964 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2968 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2970 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2974 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2976 E_Comp_Object *cw = data;
2978 if (!cw->ec) return; //NYI
2979 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2983 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2985 E_Comp_Object *cw = data;
2987 if (!cw->ec) return; //NYI
2988 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2992 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2994 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2998 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3000 E_Comp_Object *cw = data;
3002 if (!e_object_is_del(E_OBJECT(cw->ec)))
3003 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3007 _e_comp_input_obj_smart_add(Evas_Object *obj)
3009 E_Input_Rect_Smart_Data *input_rect_sd;
3010 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3012 if (!input_rect_sd) return;
3013 evas_object_smart_data_set(obj, input_rect_sd);
3017 _e_comp_input_obj_smart_del(Evas_Object *obj)
3019 E_Input_Rect_Smart_Data *input_rect_sd;
3020 E_Input_Rect_Data *input_rect_data;
3022 input_rect_sd = evas_object_smart_data_get(obj);
3023 if (!input_rect_sd) return;
3025 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3027 if (input_rect_data->obj)
3029 evas_object_smart_member_del(input_rect_data->obj);
3030 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3032 E_FREE(input_rect_data);
3034 E_FREE(input_rect_sd);
3038 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3040 E_Input_Rect_Smart_Data *input_rect_sd;
3041 E_Input_Rect_Data *input_rect_data;
3045 input_rect_sd = evas_object_smart_data_get(obj);
3046 if (!input_rect_sd) return;
3048 cw = input_rect_sd->cw;
3049 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3051 if (input_rect_data->obj)
3053 evas_object_geometry_set(input_rect_data->obj,
3054 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3055 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3056 input_rect_data->rect.w, input_rect_data->rect.h);
3062 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3064 E_Input_Rect_Smart_Data *input_rect_sd;
3065 E_Input_Rect_Data *input_rect_data;
3069 input_rect_sd = evas_object_smart_data_get(obj);
3070 if (!input_rect_sd) return;
3072 cw = input_rect_sd->cw;
3073 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3075 if (input_rect_data->obj)
3077 evas_object_geometry_set(input_rect_data->obj,
3078 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3079 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3080 input_rect_data->rect.w, input_rect_data->rect.h);
3086 _e_comp_input_obj_smart_show(Evas_Object *obj)
3088 E_Input_Rect_Smart_Data *input_rect_sd;
3089 E_Input_Rect_Data *input_rect_data;
3092 input_rect_sd = evas_object_smart_data_get(obj);
3093 if (!input_rect_sd) return;
3095 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3097 if (input_rect_data->obj)
3099 evas_object_show(input_rect_data->obj);
3105 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3107 E_Input_Rect_Smart_Data *input_rect_sd;
3108 E_Input_Rect_Data *input_rect_data;
3111 input_rect_sd = evas_object_smart_data_get(obj);
3112 if (!input_rect_sd) return;
3114 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3116 if (input_rect_data->obj)
3118 evas_object_hide(input_rect_data->obj);
3124 _e_comp_input_obj_smart_init(void)
3126 if (_e_comp_input_obj_smart) return;
3128 static const Evas_Smart_Class sc =
3130 INPUT_OBJ_SMART_NAME,
3131 EVAS_SMART_CLASS_VERSION,
3132 _e_comp_input_obj_smart_add,
3133 _e_comp_input_obj_smart_del,
3134 _e_comp_input_obj_smart_move,
3135 _e_comp_input_obj_smart_resize,
3136 _e_comp_input_obj_smart_show,
3137 _e_comp_input_obj_smart_hide,
3150 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3156 _e_comp_smart_add(Evas_Object *obj)
3160 cw = E_NEW(E_Comp_Object, 1);
3161 EINA_SAFETY_ON_NULL_RETURN(cw);
3163 wl_signal_init(&cw->events.lower);
3164 #ifdef REFACTOR_DESK_AREA
3165 wl_signal_init(&cw->events.lower_done);
3166 wl_signal_init(&cw->events.raise);
3168 wl_signal_init(&cw->events.show);
3169 wl_signal_init(&cw->events.hide);
3170 #ifdef REFACTOR_DESK_AREA
3171 wl_signal_init(&cw->events.set_layer);
3172 wl_signal_init(&cw->events.stack_above);
3173 wl_signal_init(&cw->events.stack_below);
3176 cw->smart_obj = obj;
3177 cw->x = cw->y = cw->w = cw->h = -1;
3178 evas_object_smart_data_set(obj, cw);
3179 cw->opacity = 255.0;
3180 cw->external_content = 0;
3181 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3182 cw->transform_bg_color.r = 0;
3183 cw->transform_bg_color.g = 0;
3184 cw->transform_bg_color.b = 0;
3185 cw->transform_bg_color.a = 255;
3186 evas_object_data_set(obj, "comp_obj", cw);
3187 evas_object_move(obj, -1, -1);
3188 /* intercept ALL the callbacks! */
3189 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3190 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3191 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3192 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3193 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3194 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3195 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3196 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3197 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3198 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3199 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3201 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3202 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3203 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3204 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3206 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3207 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3209 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3210 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3212 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3214 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3215 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3219 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3222 evas_object_color_set(cw->clip, r, g, b, a);
3223 evas_object_smart_callback_call(obj, "color_set", NULL);
3228 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3231 evas_object_clip_set(cw->clip, clip);
3235 _e_comp_smart_clip_unset(Evas_Object *obj)
3238 evas_object_clip_unset(cw->clip);
3242 _e_comp_smart_hide(Evas_Object *obj)
3244 TRACE_DS_BEGIN(COMP:SMART HIDE);
3249 evas_object_hide(cw->clip);
3250 if (cw->input_obj) evas_object_hide(cw->input_obj);
3251 evas_object_hide(cw->effect_obj);
3252 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3253 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3254 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3261 /* unset native surface if current displaying buffer was destroied */
3262 if (!cw->buffer_destroy_listener.notify)
3264 Evas_Native_Surface *ns;
3265 ns = evas_object_image_native_surface_get(cw->obj);
3266 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3267 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3270 if (!cw->ec->input_only)
3272 edje_object_freeze(cw->effect_obj);
3273 edje_object_freeze(cw->shobj);
3274 edje_object_play_set(cw->shobj, 0);
3275 if (cw->frame_object)
3276 edje_object_play_set(cw->frame_object, 0);
3279 e_comp_render_queue(); //force nocomp recheck
3285 _e_comp_smart_show(Evas_Object *obj)
3293 if ((cw->w < 0) || (cw->h < 0))
3294 CRI("ACK! ec:%p", cw->ec);
3296 TRACE_DS_BEGIN(COMP:SMART SHOW);
3298 e_comp_object_map_update(obj);
3300 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3301 evas_object_show(tmp->frame);
3303 evas_object_show(cw->clip);
3304 if (cw->input_obj) evas_object_show(cw->input_obj);
3305 if (!cw->ec->input_only)
3307 edje_object_thaw(cw->effect_obj);
3308 edje_object_thaw(cw->shobj);
3309 edje_object_play_set(cw->shobj, 1);
3310 if (cw->frame_object)
3311 edje_object_play_set(cw->frame_object, 1);
3313 evas_object_show(cw->effect_obj);
3314 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3315 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3316 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3317 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3318 e_comp_render_queue();
3319 if (cw->ec->input_only)
3324 if (cw->ec->iconic && (!cw->ec->new_client))
3326 if (e_client_is_iconified_by_client(cw->ec))
3328 ELOGF("COMP", "Set launching flag..", cw->ec);
3329 cw->ec->launching = EINA_TRUE;
3332 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3334 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3337 ELOGF("COMP", "Set launching flag..", cw->ec);
3338 cw->ec->launching = EINA_TRUE;
3340 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3341 _e_comp_object_animating_begin(cw);
3342 if (!_e_comp_object_effect_visibility_start(cw, 1))
3348 /* ensure some random effect doesn't lock the client offscreen */
3352 e_comp_object_effect_set(obj, NULL);
3355 _e_comp_object_dim_update(cw);
3361 _e_comp_smart_del(Evas_Object *obj)
3367 if (cw->buffer_destroy_listener.notify)
3369 wl_list_remove(&cw->buffer_destroy_listener.link);
3370 cw->buffer_destroy_listener.notify = NULL;
3373 if (cw->tbm_surface)
3375 tbm_surface_internal_unref(cw->tbm_surface);
3376 cw->tbm_surface = NULL;
3379 if (cw->render_update_lock.buffer_ref.buffer)
3381 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3382 cw->ec, cw->render_update_lock.lock);
3383 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3386 e_comp_object_render_update_del(cw->smart_obj);
3387 E_FREE_FUNC(cw->updates, eina_tiler_free);
3388 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3395 EINA_LIST_FREE(cw->obj_mirror, o)
3397 evas_object_image_data_set(o, NULL);
3398 evas_object_freeze_events_set(o, 1);
3399 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3403 #ifdef REFACTOR_DESK_AREA
3405 _e_comp_object_layers_remove(cw);
3407 l = evas_object_data_get(obj, "comp_object-to_del");
3408 E_FREE_LIST(l, evas_object_del);
3409 _e_comp_object_mouse_event_callback_unset(cw);
3410 evas_object_del(cw->clip);
3411 evas_object_del(cw->obj);
3412 evas_object_del(cw->shobj);
3413 evas_object_del(cw->effect_obj);
3414 evas_object_del(cw->frame_object);
3415 evas_object_del(cw->input_obj);
3416 evas_object_del(cw->mask.obj);
3417 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3418 evas_object_del(cw->transform_bg_obj);
3419 evas_object_del(cw->transform_tranp_obj);
3420 evas_object_del(cw->default_input_obj);
3421 eina_stringshare_del(cw->frame_theme);
3422 eina_stringshare_del(cw->frame_name);
3426 e_comp->animating--;
3428 e_object_unref(E_OBJECT(cw->ec));
3430 cw->ec->frame = NULL;
3435 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3439 cw->x = x, cw->y = y;
3440 evas_object_move(cw->effect_obj, x, y);
3441 evas_object_move(cw->default_input_obj, x, y);
3442 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3444 e_comp_object_map_update(obj);
3448 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3450 Eina_Bool first = EINA_FALSE;
3455 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3457 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3459 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3461 if (cw->w != w || cw->h != h)
3462 e_comp_object_map_update(obj);
3464 first = ((cw->w < 1) || (cw->h < 1));
3465 cw->w = w, cw->h = h;
3469 if (cw->frame_object)
3470 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3473 /* verify pixmap:object size */
3474 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3476 if ((ww != pw) || (hh != ph))
3477 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3479 evas_object_resize(cw->effect_obj, tw, th);
3480 evas_object_resize(cw->default_input_obj, w, h);
3482 evas_object_resize(cw->input_obj, w, h);
3484 evas_object_resize(cw->mask.obj, w, h);
3485 /* resize render update tiler */
3488 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3489 cw->updates_full = 0;
3490 if (cw->updates) eina_tiler_clear(cw->updates);
3494 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3495 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3503 e_comp_render_queue();
3509 _e_comp_smart_init(void)
3511 if (_e_comp_smart) return;
3513 static const Evas_Smart_Class sc =
3516 EVAS_SMART_CLASS_VERSION,
3520 _e_comp_smart_resize,
3523 _e_comp_smart_color_set,
3524 _e_comp_smart_clip_set,
3525 _e_comp_smart_clip_unset,
3535 _e_comp_smart = evas_smart_class_new(&sc);
3540 e_comp_object_init(void)
3542 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3543 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3544 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3545 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3549 e_comp_object_shutdown(void)
3555 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3557 API_ENTRY EINA_FALSE;
3558 return !!cw->force_visible;
3560 /////////////////////////////////////////////////////////
3563 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3566 Eina_Bool comp_object;
3568 comp_object = !!evas_object_data_get(obj, "comp_object");
3573 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3575 e_comp_render_queue();
3577 l = evas_object_data_get(obj, "comp_object-to_del");
3578 E_FREE_LIST(l, evas_object_del);
3582 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3584 if (e_comp_util_object_is_above_nocomp(obj) &&
3585 (!evas_object_data_get(obj, "comp_override")))
3587 evas_object_data_set(obj, "comp_override", (void*)1);
3588 e_comp_override_add();
3593 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3595 Eina_Bool ref = EINA_TRUE;
3596 if (evas_object_visible_get(obj))
3600 d = evas_object_data_del(obj, "comp_hiding");
3602 /* currently trying to hide */
3605 /* already visible */
3609 evas_object_show(obj);
3612 evas_object_ref(obj);
3613 evas_object_data_set(obj, "comp_ref", (void*)1);
3615 edje_object_signal_emit(obj, "e,state,visible", "e");
3616 evas_object_data_set(obj, "comp_showing", (void*)1);
3617 if (e_comp_util_object_is_above_nocomp(obj))
3619 evas_object_data_set(obj, "comp_override", (void*)1);
3620 e_comp_override_add();
3625 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3627 if (!evas_object_visible_get(obj)) return;
3628 /* already hiding */
3629 if (evas_object_data_get(obj, "comp_hiding")) return;
3630 if (!evas_object_data_del(obj, "comp_showing"))
3632 evas_object_ref(obj);
3633 evas_object_data_set(obj, "comp_ref", (void*)1);
3635 edje_object_signal_emit(obj, "e,state,hidden", "e");
3636 evas_object_data_set(obj, "comp_hiding", (void*)1);
3638 if (evas_object_data_del(obj, "comp_override"))
3639 e_comp_override_timed_pop();
3643 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3645 if (!e_util_strcmp(emission, "e,action,hide,done"))
3647 if (!evas_object_data_del(obj, "comp_hiding")) return;
3648 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3649 evas_object_hide(obj);
3650 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3653 evas_object_data_del(obj, "comp_showing");
3654 if (evas_object_data_del(obj, "comp_ref"))
3655 evas_object_unref(obj);
3659 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3665 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3669 E_API E_Comp_Object_Hook *
3670 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3672 E_Comp_Object_Hook *ch;
3674 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3675 ch = E_NEW(E_Comp_Object_Hook, 1);
3676 if (!ch) return NULL;
3677 ch->hookpoint = hookpoint;
3679 ch->data = (void*)data;
3680 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3685 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3688 if (_e_comp_object_hooks_walking == 0)
3690 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3694 _e_comp_object_hooks_delete++;
3697 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3698 E_API E_Comp_Object_Intercept_Hook *
3699 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3701 E_Comp_Object_Intercept_Hook *ch;
3703 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3704 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3705 if (!ch) return NULL;
3706 ch->hookpoint = hookpoint;
3708 ch->data = (void*)data;
3709 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3714 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3717 if (_e_comp_object_intercept_hooks_walking == 0)
3719 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3723 _e_comp_object_intercept_hooks_delete++;
3728 e_comp_object_util_add(Evas_Object *obj)
3732 E_Comp_Config *conf = e_comp_config_get();
3733 Eina_Bool skip = EINA_FALSE;
3739 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3741 name = evas_object_name_get(obj);
3742 vis = evas_object_visible_get(obj);
3743 o = edje_object_add(e_comp->evas);
3744 evas_object_data_set(o, "comp_object", (void*)1);
3746 skip = (!strncmp(name, "noshadow", 8));
3748 evas_object_data_set(o, "comp_object_skip", (void*)1);
3750 if (conf->shadow_style)
3752 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3753 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3756 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3757 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3758 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3760 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3762 evas_object_geometry_get(obj, &x, &y, &w, &h);
3763 evas_object_geometry_set(o, x, y, w, h);
3764 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3766 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3768 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3769 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3770 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3771 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3772 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3773 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3775 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3777 edje_object_part_swallow(o, "e.swallow.content", obj);
3779 _e_comp_object_event_add(o);
3782 evas_object_show(o);
3787 /* utility functions for deleting objects when their "owner" is deleted */
3789 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3794 EINA_SAFETY_ON_NULL_RETURN(to_del);
3795 l = evas_object_data_get(obj, "comp_object-to_del");
3796 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3797 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3798 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3802 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3807 EINA_SAFETY_ON_NULL_RETURN(to_del);
3808 l = evas_object_data_get(obj, "comp_object-to_del");
3810 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3813 /////////////////////////////////////////////////////////
3815 EINTERN Evas_Object *
3816 e_comp_object_client_add(E_Client *ec)
3821 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3822 if (ec->frame) return NULL;
3823 _e_comp_smart_init();
3824 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3825 cw = evas_object_smart_data_get(o);
3826 if (!cw) return NULL;
3827 evas_object_data_set(o, "E_Client", ec);
3830 evas_object_data_set(o, "comp_object", (void*)1);
3832 _e_comp_object_event_add(o);
3837 /* utility functions for getting client inset */
3839 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3842 if (!cw->client_inset.calc)
3848 if (ax) *ax = x - cw->client_inset.l;
3849 if (ay) *ay = y - cw->client_inset.t;
3853 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3856 if (!cw->client_inset.calc)
3862 if (ax) *ax = x + cw->client_inset.l;
3863 if (ay) *ay = y + cw->client_inset.t;
3867 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3870 if (!cw->client_inset.calc)
3876 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3877 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3881 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3884 if (!cw->client_inset.calc)
3890 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3891 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3895 e_comp_object_client_get(Evas_Object *obj)
3900 /* FIXME: remove this when eo is used */
3901 o = evas_object_data_get(obj, "comp_smart_obj");
3903 return e_comp_object_client_get(o);
3904 return cw ? cw->ec : NULL;
3908 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3911 if (cw->frame_extends)
3912 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3917 if (w) *w = cw->ec->w;
3918 if (h) *h = cw->ec->h;
3923 e_comp_object_util_zone_get(Evas_Object *obj)
3925 E_Zone *zone = NULL;
3929 zone = e_comp_zone_find_by_ec(cw->ec);
3934 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3935 zone = e_comp_zone_xy_get(x, y);
3941 e_comp_object_util_center(Evas_Object *obj)
3943 int x, y, w, h, ow, oh;
3948 zone = e_comp_object_util_zone_get(obj);
3949 EINA_SAFETY_ON_NULL_RETURN(zone);
3950 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3951 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3952 ow = cw->ec->w, oh = cw->ec->h;
3954 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3955 x = x + (w - ow) / 2;
3956 y = y + (h - oh) / 2;
3957 evas_object_move(obj, x, y);
3961 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3963 int x, y, w, h, ow, oh;
3966 EINA_SAFETY_ON_NULL_RETURN(on);
3967 evas_object_geometry_get(on, &x, &y, &w, &h);
3968 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3969 ow = cw->ec->w, oh = cw->ec->h;
3971 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3972 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3976 e_comp_object_util_fullscreen(Evas_Object *obj)
3981 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3984 evas_object_move(obj, 0, 0);
3985 evas_object_resize(obj, e_comp->w, e_comp->h);
3990 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3998 ow = cw->w, oh = cw->h;
4000 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4001 zone = e_comp_object_util_zone_get(obj);
4002 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4003 if (x) *x = zx + (zw - ow) / 2;
4004 if (y) *y = zy + (zh - oh) / 2;
4008 e_comp_object_input_objs_del(Evas_Object *obj)
4011 E_Input_Rect_Data *input_rect_data;
4012 E_Input_Rect_Smart_Data *input_rect_sd;
4017 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4018 if (!input_rect_sd) return;
4020 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4022 if (input_rect_data->obj)
4024 evas_object_smart_member_del(input_rect_data->obj);
4025 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4027 E_FREE(input_rect_data);
4032 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4035 E_Input_Rect_Data *input_rect_data = NULL;
4036 E_Input_Rect_Smart_Data *input_rect_sd;
4037 int client_w, client_h;
4039 if (cw->ec->client.w)
4040 client_w = cw->ec->client.w;
4042 client_w = cw->ec->w;
4044 if (cw->ec->client.h)
4045 client_h = cw->ec->client.h;
4047 client_h = cw->ec->h;
4049 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4053 _e_comp_input_obj_smart_init();
4054 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4055 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4056 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4059 input_rect_sd->cw = cw;
4062 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4065 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4066 if (input_rect_data)
4068 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4069 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4073 if ((input_rect_data) &&
4074 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4076 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4077 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4078 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4079 evas_object_clip_set(input_rect_data->obj, cw->clip);
4080 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4081 evas_object_geometry_set(input_rect_data->obj,
4082 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4083 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4084 evas_object_pass_events_set(cw->default_input_obj, 1);
4085 evas_object_pass_events_set(cw->obj, 1);
4088 evas_object_show(input_rect_data->obj);
4089 evas_object_show(cw->input_obj);
4094 evas_object_smart_member_del(cw->input_obj);
4095 E_FREE_FUNC(cw->input_obj, evas_object_del);
4096 evas_object_pass_events_set(cw->default_input_obj, 0);
4097 evas_object_pass_events_set(cw->obj, 0);
4102 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4105 E_Input_Rect_Smart_Data *input_rect_sd;
4106 E_Input_Rect_Data *input_rect_data;
4109 if (!cw->input_obj) return;
4111 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4114 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4116 *list = eina_list_append(*list, &input_rect_data->rect);
4122 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4125 if (l) *l = cw->client_inset.l;
4126 if (r) *r = cw->client_inset.r;
4127 if (t) *t = cw->client_inset.t;
4128 if (b) *b = cw->client_inset.b;
4131 /* set geometry for CSD */
4133 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4139 if (cw->frame_object)
4140 CRI("ACK! ec:%p", cw->ec);
4141 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4142 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4143 calc = cw->client_inset.calc;
4144 cw->client_inset.calc = l || r || t || b;
4145 eina_stringshare_replace(&cw->frame_theme, "borderless");
4146 if (cw->client_inset.calc)
4148 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4149 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4150 e_client_size_set(cw->ec, tw, th);
4152 else if (cw->ec->maximized || cw->ec->fullscreen)
4154 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4155 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4157 if (!cw->ec->new_client)
4159 if (calc && cw->client_inset.calc)
4161 tx = cw->ec->x - (l - cw->client_inset.l);
4162 ty = cw->ec->y - (t - cw->client_inset.t);
4163 e_client_pos_set(cw->ec, tx, ty);
4165 cw->ec->changes.pos = cw->ec->changes.size = 1;
4168 cw->client_inset.l = l;
4169 cw->client_inset.r = r;
4170 cw->client_inset.t = t;
4171 cw->client_inset.b = b;
4175 e_comp_object_frame_allowed(Evas_Object *obj)
4177 API_ENTRY EINA_FALSE;
4178 return (cw->frame_object || (!cw->client_inset.calc));
4182 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4184 API_ENTRY EINA_FALSE;
4185 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4186 eina_stringshare_replace(&cw->frame_name, name);
4187 if (cw->frame_object)
4188 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4193 e_comp_object_frame_exists(Evas_Object *obj)
4195 API_ENTRY EINA_FALSE;
4196 return !!cw->frame_object;
4200 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4202 Evas_Object *o, *pbg;
4205 Eina_Stringshare *theme;
4207 API_ENTRY EINA_FALSE;
4209 if (!e_util_strcmp(cw->frame_theme, name))
4210 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4211 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4212 return _e_comp_object_shadow_setup(cw);
4213 pbg = cw->frame_object;
4214 theme = eina_stringshare_add(name);
4216 if (cw->frame_object)
4220 w = cw->ec->w, h = cw->ec->h;
4221 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4222 if ((cw->ec->w != w) || (cw->ec->h != h))
4224 cw->ec->changes.size = 1;
4227 E_FREE_FUNC(cw->frame_object, evas_object_del);
4228 if (!name) goto reshadow;
4230 o = edje_object_add(e_comp->evas);
4231 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4232 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4233 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4235 cw->frame_object = NULL;
4237 eina_stringshare_del(cw->frame_theme);
4238 cw->frame_theme = theme;
4243 if (theme != e_config->theme_default_border_style)
4245 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4246 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4250 ok = e_theme_edje_object_set(o, "base/theme/border",
4251 "e/widgets/border/default/border");
4252 if (ok && (theme == e_config->theme_default_border_style))
4254 /* Reset default border style to default */
4255 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4256 e_config_save_queue();
4263 cw->frame_object = o;
4264 eina_stringshare_del(cw->frame_theme);
4265 cw->frame_theme = theme;
4266 evas_object_name_set(o, "cw->frame_object");
4269 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4273 cw->ec->changes.icon = 1;
4279 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4284 _e_comp_object_shadow_setup(cw);
4287 int old_x, old_y, new_x = 0, new_y = 0;
4289 old_x = cw->x, old_y = cw->y;
4291 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4293 new_x = cw->ec->x, new_y = cw->ec->y;
4294 else if (cw->ec->placed || (!cw->ec->new_client))
4296 /* if no previous frame:
4297 * - reapply client_inset
4302 if (cw->ec->changes.size)
4310 zone = e_comp_zone_find_by_ec(cw->ec);
4313 x = cw->ec->client.x, y = cw->ec->client.y;
4314 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4315 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4317 new_x = x, new_y = y;
4320 if (old_x != new_x || old_y != new_y)
4322 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4323 cw->y = cw->x = -99999;
4324 evas_object_move(obj, new_x, new_y);
4328 if (cw->ec->maximized)
4330 cw->ec->changes.need_maximize = 1;
4333 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4334 if (cw->frame_object)
4336 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4339 cw->frame_extends = 0;
4340 evas_object_del(pbg);
4345 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4347 E_Comp_Object_Mover *prov;
4350 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4351 edje_object_signal_emit(cw->shobj, sig, src);
4352 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4353 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4354 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4356 /* start with highest priority callback first */
4357 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4359 if (!e_util_glob_match(sig, prov->sig)) continue;
4360 if (prov->func(prov->data, obj, sig)) break;
4365 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4367 /* FIXME: at some point I guess this should use eo to inherit
4368 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4369 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4372 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4376 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4379 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4383 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4386 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4390 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4393 Eina_Rectangle rect;
4396 if (cw->ec->input_only || (!cw->updates)) return;
4397 if (cw->nocomp) return;
4398 rect.x = x, rect.y = y;
4399 rect.w = w, rect.h = h;
4400 evas_object_smart_callback_call(obj, "damage", &rect);
4402 if (e_comp_is_on_overlay(cw->ec))
4404 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4405 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4406 * E module attempts to block screen update due to the particular policy.
4408 if (e_pixmap_resource_get(cw->ec->pixmap))
4409 cw->hwc_need_update = EINA_TRUE;
4412 /* ignore overdraw */
4413 if (cw->updates_full)
4415 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4416 e_comp_object_render_update_add(obj);
4418 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4419 evas_object_show(cw->smart_obj);
4423 /* clip rect to client surface */
4424 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4425 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4426 /* if rect is the total size of the client after clip, clear the updates
4427 * since this is guaranteed to be the whole region anyway
4429 eina_tiler_area_size_get(cw->updates, &tw, &th);
4430 if ((w > tw) || (h > th))
4432 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4433 eina_tiler_clear(cw->updates);
4434 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4436 tw = cw->ec->client.w, th = cw->ec->client.h;
4438 if ((!x) && (!y) && (w == tw) && (h == th))
4440 eina_tiler_clear(cw->updates);
4441 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4442 cw->updates_full = 1;
4443 cw->update_count = 0;
4446 if (cw->update_count > UPDATE_MAX)
4448 /* this is going to get really dumb, so just update the whole thing */
4449 eina_tiler_clear(cw->updates);
4450 cw->update_count = cw->updates_full = 1;
4451 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4452 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4456 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4457 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4459 cw->updates_exist = 1;
4460 e_comp_object_render_update_add(obj);
4462 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4463 evas_object_show(cw->smart_obj);
4467 e_comp_object_damage_exists(Evas_Object *obj)
4469 API_ENTRY EINA_FALSE;
4470 return cw->updates_exist;
4474 e_comp_object_render_update_add(Evas_Object *obj)
4478 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4479 if (cw->render_update_lock.lock) return;
4480 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4484 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4486 e_comp_render_queue();
4490 e_comp_object_render_update_del(Evas_Object *obj)
4494 if (cw->ec->input_only || (!cw->updates)) return;
4495 if (!cw->update) return;
4497 /* this gets called during comp animating to clear the update flag */
4498 if (e_comp->grabbed) return;
4499 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4500 if (!e_comp->updates)
4502 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4503 if (e_comp->render_animator)
4504 ecore_animator_freeze(e_comp->render_animator);
4509 e_comp_object_shape_apply(Evas_Object *obj)
4513 unsigned int i, *pix, *p;
4517 if (!cw->ec) return; //NYI
4518 if (cw->external_content) return;
4521 if ((cw->ec->shape_rects_num >= 1) &&
4522 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4527 ERR("BUGGER: shape with native surface? cw=%p", cw);
4530 evas_object_image_size_get(cw->obj, &w, &h);
4531 if ((w < 1) || (h < 1)) return;
4534 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4535 _e_comp_object_alpha_set(cw);
4536 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4537 evas_object_image_alpha_set(o, 1);
4539 p = pix = evas_object_image_data_get(cw->obj, 1);
4542 evas_object_image_data_set(cw->obj, pix);
4547 unsigned char *spix, *sp;
4549 spix = calloc(w * h, sizeof(unsigned char));
4551 for (i = 0; i < cw->ec->shape_rects_num; i++)
4555 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4556 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4557 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4558 sp = spix + (w * ry) + rx;
4559 for (py = 0; py < rh; py++)
4561 for (px = 0; px < rw; px++)
4569 for (py = 0; py < h; py++)
4571 for (px = 0; px < w; px++)
4573 unsigned int mask, imask;
4575 mask = ((unsigned int)(*sp)) << 24;
4577 imask |= imask >> 8;
4578 imask |= imask >> 8;
4579 *p = mask | (*p & imask);
4580 //if (*sp) *p = 0xff000000 | *p;
4581 //else *p = 0x00000000;
4590 for (py = 0; py < h; py++)
4592 for (px = 0; px < w; px++)
4596 evas_object_image_data_set(cw->obj, pix);
4597 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4598 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4600 evas_object_image_data_set(o, pix);
4601 evas_object_image_data_update_add(o, 0, 0, w, h);
4603 // don't need to fix alpha chanel as blending
4604 // should be totally off here regardless of
4605 // alpha channel content
4609 _e_comp_object_clear(E_Comp_Object *cw)
4614 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4616 if (cw->render_update_lock.lock) return;
4619 e_pixmap_clear(cw->ec->pixmap);
4621 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4622 evas_object_image_size_set(cw->obj, 1, 1);
4623 evas_object_image_data_set(cw->obj, NULL);
4624 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4626 evas_object_image_size_set(o, 1, 1);
4627 evas_object_image_data_set(o, NULL);
4630 e_comp_object_render_update_del(cw->smart_obj);
4634 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4638 API_ENTRY EINA_FALSE;
4640 if (cw->transparent.set == set)
4645 evas_object_color_get(obj, &r, &g, &b, &a);
4646 evas_object_color_set(obj, 0, 0, 0, 0);
4648 cw->transparent.user_r = r;
4649 cw->transparent.user_g = g;
4650 cw->transparent.user_b = b;
4651 cw->transparent.user_a = a;
4653 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4655 cw->transparent.user_r,
4656 cw->transparent.user_g,
4657 cw->transparent.user_b,
4658 cw->transparent.user_a);
4660 cw->transparent.set = EINA_TRUE;
4664 cw->transparent.set = EINA_FALSE;
4666 evas_object_color_set(obj,
4667 cw->transparent.user_r,
4668 cw->transparent.user_g,
4669 cw->transparent.user_b,
4670 cw->transparent.user_a);
4672 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4674 cw->transparent.user_r,
4675 cw->transparent.user_g,
4676 cw->transparent.user_b,
4677 cw->transparent.user_a);
4683 /* helper function to simplify toggling of redirection for display servers which support it */
4685 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4690 if (cw->redirected == set) return;
4691 cw->redirected = set;
4692 if (cw->external_content) return;
4694 e_comp_object_map_update(obj);
4698 if (cw->updates_exist)
4699 e_comp_object_render_update_add(obj);
4701 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4703 _e_comp_object_transparent_set(obj, EINA_FALSE);
4704 evas_object_smart_callback_call(obj, "redirected", NULL);
4708 _e_comp_object_clear(cw);
4709 _e_comp_object_transparent_set(obj, EINA_TRUE);
4710 evas_object_smart_callback_call(obj, "unredirected", NULL);
4715 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4718 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4720 if (cw->buffer_destroy_listener.notify)
4722 cw->buffer_destroy_listener.notify = NULL;
4723 wl_list_remove(&cw->buffer_destroy_listener.link);
4726 if (e_object_is_del(E_OBJECT(cw->ec)))
4728 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4733 /* if it's current displaying buffer, do not remove its content */
4734 if (!evas_object_visible_get(cw->ec->frame))
4735 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4740 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4745 if (cw->buffer_destroy_listener.notify)
4747 wl_list_remove(&cw->buffer_destroy_listener.link);
4748 cw->buffer_destroy_listener.notify = NULL;
4751 if (cw->tbm_surface)
4753 tbm_surface_internal_unref(cw->tbm_surface);
4754 cw->tbm_surface = NULL;
4759 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4761 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4762 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4764 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4766 tbm_surface_internal_ref(ns->data.tbm.buffer);
4767 cw->tbm_surface = ns->data.tbm.buffer;
4771 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4772 evas_object_image_native_surface_set(cw->obj, ns);
4776 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4778 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4779 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4780 evas_object_image_native_surface_set(o, ns);
4787 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4789 Evas_Native_Surface ns;
4792 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4793 if (cw->ec->input_only) return;
4794 if (cw->external_content) return;
4795 if (cw->render_update_lock.lock) return;
4798 memset(&ns, 0, sizeof(Evas_Native_Surface));
4802 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4803 set = (!cw->ec->shaped);
4805 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4809 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4813 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4816 if (cw->ec->input_only) return;
4819 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4820 _e_comp_object_alpha_set(cw);
4822 e_comp_object_native_surface_set(obj, cw->native);
4823 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4827 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4833 if (cw->blanked == set) return;
4835 _e_comp_object_alpha_set(cw);
4838 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4839 evas_object_image_data_set(cw->obj, NULL);
4843 e_comp_object_native_surface_set(obj, 1);
4844 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4848 _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)
4853 if (!_damage_trace) return;
4857 if (!evas_object_visible_get(cw->obj)) return;
4859 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4861 o = evas_object_rectangle_add(e_comp->evas);
4862 evas_object_layer_set(o, E_LAYER_MAX);
4863 evas_object_name_set(o, "damage_trace");
4864 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4865 evas_object_resize(o, dmg_w, dmg_h);
4866 evas_object_color_set(o, 0, 128, 0, 128);
4867 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4868 evas_object_pass_events_set(o, EINA_TRUE);
4869 evas_object_show(o);
4871 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4873 dmg_w, dmg_h, dmg_x, dmg_y,
4874 origin->w, origin->h, origin->x, origin->y);
4876 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4879 /* mark an object as dirty and setup damages */
4881 e_comp_object_dirty(Evas_Object *obj)
4884 Eina_Rectangle *rect;
4888 Eina_Bool dirty, visible;
4892 if (cw->external_content) return;
4893 if (!cw->redirected) return;
4894 if (cw->render_update_lock.lock)
4896 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4899 /* only actually dirty if pixmap is available */
4900 if (!e_pixmap_resource_get(cw->ec->pixmap))
4902 // e_pixmap_size_get returns last attached buffer size
4903 // eventhough it is destroyed
4904 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4907 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4908 visible = cw->visible;
4909 if (!dirty) w = h = 1;
4910 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4912 evas_object_image_data_set(cw->obj, NULL);
4913 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4914 evas_object_image_size_set(cw->obj, tw, th);
4915 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4916 if (cw->pending_updates)
4917 eina_tiler_area_size_set(cw->pending_updates, w, h);
4918 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4920 evas_object_image_pixels_dirty_set(o, dirty);
4922 evas_object_image_data_set(o, NULL);
4923 evas_object_image_size_set(o, tw, th);
4924 visible |= evas_object_visible_get(o);
4928 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4932 e_comp_object_native_surface_set(obj, 1);
4934 m = _e_comp_object_map_damage_transform_get(cw->ec);
4935 it = eina_tiler_iterator_new(cw->updates);
4936 EINA_ITERATOR_FOREACH(it, rect)
4938 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4939 * of evas engine and doesn't convert damage according to evas_map.
4940 * so damage of evas_object_image use surface coordinate.
4944 int damage_x, damage_y, damage_w, damage_h;
4946 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4947 &damage_x, &damage_y, &damage_w, &damage_h);
4948 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4949 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4953 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4954 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4957 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4958 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4959 if (cw->pending_updates)
4960 eina_tiler_rect_add(cw->pending_updates, rect);
4962 eina_iterator_free(it);
4963 if (m) e_map_free(m);
4964 if (cw->pending_updates)
4965 eina_tiler_clear(cw->updates);
4968 cw->pending_updates = cw->updates;
4969 cw->updates = eina_tiler_new(w, h);
4970 eina_tiler_tile_size_set(cw->updates, 1, 1);
4972 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4973 evas_object_smart_callback_call(obj, "dirty", NULL);
4974 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4975 /* force render if main object is hidden but mirrors are visible */
4976 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4977 e_comp_object_render(obj);
4981 e_comp_object_render(Evas_Object *obj)
4988 API_ENTRY EINA_FALSE;
4990 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4991 if (cw->ec->input_only) return EINA_TRUE;
4992 if (cw->external_content) return EINA_TRUE;
4993 if (cw->native) return EINA_FALSE;
4994 /* if comp object is not redirected state, comp object should not be set by newly committed data
4995 because image size of comp object is 1x1 and it should not be shown on canvas */
4996 if (!cw->redirected) return EINA_TRUE;
4997 if (cw->render_update_lock.lock)
4999 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5002 e_comp_object_render_update_del(obj);
5003 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5005 if (!cw->pending_updates)
5007 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5008 evas_object_image_data_set(cw->obj, NULL);
5009 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5010 evas_object_image_data_set(o, NULL);
5014 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5016 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5018 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5021 e_pixmap_image_refresh(cw->ec->pixmap);
5022 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5025 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5026 e_pixmap_image_data_ref(cw->ec->pixmap);
5028 /* set pixel data */
5029 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5030 _e_comp_object_alpha_set(cw);
5031 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5033 evas_object_image_data_set(o, pix);
5034 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5035 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5038 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5040 e_comp_client_post_update_add(cw->ec);
5045 /* create a duplicate of an evas object */
5047 e_comp_object_util_mirror_add(Evas_Object *obj)
5051 unsigned int *pix = NULL;
5052 Eina_Bool argb = EINA_FALSE;
5057 cw = evas_object_data_get(obj, "comp_mirror");
5060 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5061 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5062 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5063 evas_object_image_alpha_set(o, 1);
5064 evas_object_image_source_set(o, obj);
5067 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5068 if (cw->external_content)
5070 ERR("%p of client %p is external content.", obj, cw->ec);
5073 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5074 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5075 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5076 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5077 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5078 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5079 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5080 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5081 evas_object_data_set(o, "comp_mirror", cw);
5083 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5084 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5086 evas_object_image_size_set(o, tw, th);
5089 pix = evas_object_image_data_get(cw->obj, 0);
5095 evas_object_image_native_surface_set(o, cw->ns);
5098 Evas_Native_Surface ns;
5099 memset(&ns, 0, sizeof(Evas_Native_Surface));
5100 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5101 evas_object_image_native_surface_set(o, &ns);
5106 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5107 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5109 (e_pixmap_image_exists(cw->ec->pixmap)))
5110 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5112 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5119 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5120 evas_object_image_pixels_dirty_set(o, dirty);
5121 evas_object_image_data_set(o, pix);
5122 evas_object_image_data_set(cw->obj, pix);
5124 evas_object_image_data_update_add(o, 0, 0, tw, th);
5129 //////////////////////////////////////////////////////
5132 e_comp_object_effect_allowed_get(Evas_Object *obj)
5134 API_ENTRY EINA_FALSE;
5136 if (!cw->shobj) return EINA_FALSE;
5137 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5138 return !e_comp_config_get()->match.disable_borders;
5141 /* setup an api effect for a client */
5143 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5146 Eina_Stringshare *grp;
5147 E_Comp_Config *config;
5148 Eina_Bool loaded = EINA_FALSE;
5150 API_ENTRY EINA_FALSE;
5151 if (!cw->shobj) return EINA_FALSE; //input window
5153 if (!effect) effect = "none";
5154 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5156 config = e_comp_config_get();
5157 if ((config) && (config->effect_file))
5159 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5161 cw->effect_set = EINA_TRUE;
5168 edje_object_file_get(cw->effect_obj, NULL, &grp);
5169 cw->effect_set = !eina_streq(effect, "none");
5170 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5171 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5173 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5174 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5175 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5177 if (cw->effect_running)
5179 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5182 cw->effect_set = EINA_FALSE;
5183 return cw->effect_set;
5187 if (cw->effect_running)
5189 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5192 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5193 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5194 if (cw->effect_clip)
5196 evas_object_clip_unset(cw->clip);
5197 cw->effect_clip = 0;
5199 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5201 _e_comp_object_dim_update(cw);
5203 return cw->effect_set;
5206 /* set params for embryo scripts in effect */
5208 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5210 Edje_Message_Int_Set *msg;
5214 EINA_SAFETY_ON_NULL_RETURN(params);
5215 EINA_SAFETY_ON_FALSE_RETURN(count);
5216 if (!cw->effect_set) return;
5218 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5219 msg->count = (int)count;
5220 for (x = 0; x < count; x++)
5221 msg->val[x] = params[x];
5222 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5223 edje_object_message_signal_process(cw->effect_obj);
5227 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5229 Edje_Signal_Cb end_cb;
5231 E_Comp_Object *cw = data;
5233 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5234 cw->effect_running = 0;
5235 if (!_e_comp_object_animating_end(cw)) return;
5237 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5239 evas_object_data_del(cw->smart_obj, "effect_running");
5240 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5241 e_comp_visibility_calculation_set(EINA_TRUE);
5244 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5245 if (!end_cb) return;
5246 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5247 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5248 end_cb(end_data, cw->smart_obj, emission, source);
5251 /* clip effect to client's zone */
5253 e_comp_object_effect_clip(Evas_Object *obj)
5257 zone = e_comp_zone_find_by_ec(cw->ec);
5259 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5260 if (!cw->effect_clip_able) return;
5261 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5262 cw->effect_clip = 1;
5265 /* unclip effect from client's zone */
5267 e_comp_object_effect_unclip(Evas_Object *obj)
5270 if (!cw->effect_clip) return;
5271 evas_object_clip_unset(cw->smart_obj);
5272 cw->effect_clip = 0;
5275 /* start effect, running end_cb after */
5277 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5279 API_ENTRY EINA_FALSE;
5280 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5281 if (!cw->effect_set) return EINA_FALSE;
5283 if (cw->effect_running)
5285 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5288 e_comp_object_effect_clip(obj);
5289 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5291 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5292 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5293 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5294 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5296 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5297 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5299 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5300 _e_comp_object_animating_begin(cw);
5301 cw->effect_running = 1;
5305 /* stop a currently-running effect immediately */
5307 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5310 Edje_Signal_Cb end_cb_before = NULL;
5311 void *end_data_before = NULL;
5312 API_ENTRY EINA_FALSE;
5314 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5315 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5317 if (end_cb_before != end_cb) return EINA_TRUE;
5318 e_comp_object_effect_unclip(obj);
5319 if (cw->effect_clip)
5321 evas_object_clip_unset(cw->effect_obj);
5322 cw->effect_clip = 0;
5324 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5325 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5327 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5329 evas_object_data_del(cw->smart_obj, "effect_running");
5330 e_comp_visibility_calculation_set(EINA_TRUE);
5333 cw->effect_running = 0;
5334 ret = _e_comp_object_animating_end(cw);
5336 if ((ret) && (end_cb_before))
5338 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5339 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5346 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5348 return a->pri - b->pri;
5351 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5352 E_API E_Comp_Object_Mover *
5353 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5355 E_Comp_Object_Mover *prov;
5357 prov = E_NEW(E_Comp_Object_Mover, 1);
5358 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5359 prov->func = provider;
5360 prov->data = (void*)data;
5363 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5364 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5369 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5371 EINA_SAFETY_ON_NULL_RETURN(prov);
5372 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5377 e_comp_object_effect_object_get(Evas_Object *obj)
5381 return cw->effect_obj;
5385 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5387 API_ENTRY EINA_FALSE;
5388 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5389 if (!cw->effect_set) return EINA_FALSE;
5396 ////////////////////////////////////
5399 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5401 if (e_comp->autoclose.obj)
5403 e_comp_ungrab_input(0, 1);
5404 if (e_comp->autoclose.del_cb)
5405 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5406 else if (!already_del)
5408 evas_object_hide(e_comp->autoclose.obj);
5409 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5411 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5413 e_comp->autoclose.obj = NULL;
5414 e_comp->autoclose.data = NULL;
5415 e_comp->autoclose.del_cb = NULL;
5416 e_comp->autoclose.key_cb = NULL;
5417 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5421 _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)
5423 _e_comp_object_autoclose_cleanup(0);
5427 _e_comp_object_autoclose_setup(Evas_Object *obj)
5429 if (!e_comp->autoclose.rect)
5431 /* create rect just below autoclose object to catch mouse events */
5432 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5433 evas_object_move(e_comp->autoclose.rect, 0, 0);
5434 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5435 evas_object_show(e_comp->autoclose.rect);
5436 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5437 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5438 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5439 e_comp_grab_input(0, 1);
5441 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5442 evas_object_focus_set(obj, 1);
5446 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5448 _e_comp_object_autoclose_setup(obj);
5449 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5453 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5455 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5456 _e_comp_object_autoclose_cleanup(1);
5457 if (e_client_focused_get()) return;
5459 E_Zone *zone = e_zone_current_get();
5462 e_zone_focus_reset(zone);
5466 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5470 if (e_comp->autoclose.obj)
5472 if (e_comp->autoclose.obj == obj) return;
5473 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5474 e_comp->autoclose.obj = obj;
5475 e_comp->autoclose.del_cb = del_cb;
5476 e_comp->autoclose.key_cb = cb;
5477 e_comp->autoclose.data = (void*)data;
5478 if (evas_object_visible_get(obj))
5479 _e_comp_object_autoclose_setup(obj);
5481 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5482 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5485 e_comp->autoclose.obj = obj;
5486 e_comp->autoclose.del_cb = del_cb;
5487 e_comp->autoclose.key_cb = cb;
5488 e_comp->autoclose.data = (void*)data;
5489 if (evas_object_visible_get(obj))
5490 _e_comp_object_autoclose_setup(obj);
5492 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5493 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5497 e_comp_object_is_animating(Evas_Object *obj)
5501 return cw->animating;
5505 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5509 if ((cw->external_content) &&
5510 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5512 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5513 "But current external content is %d object for %p.",
5514 cw->content_type, cw->ec);
5518 cw->user_alpha_set = EINA_TRUE;
5519 cw->user_alpha = alpha;
5521 if (!cw->obj) return;
5523 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5525 evas_object_image_alpha_set(cw->obj, alpha);
5527 if ((!cw->native) && (!cw->external_content))
5528 evas_object_image_data_set(cw->obj, NULL);
5532 e_comp_object_alpha_get(Evas_Object *obj)
5534 API_ENTRY EINA_FALSE;
5536 return evas_object_image_alpha_get(cw->obj);
5540 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5542 Eina_Bool mask_set = EINA_FALSE;
5546 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5547 if (cw->ec->input_only) return;
5554 o = evas_object_rectangle_add(e_comp->evas);
5555 evas_object_color_set(o, 0, 0, 0, 0);
5556 evas_object_clip_set(o, cw->clip);
5557 evas_object_smart_member_add(o, obj);
5558 evas_object_move(o, 0, 0);
5559 evas_object_resize(o, cw->w, cw->h);
5560 /* save render op value to restore when clear a mask.
5562 * NOTE: DO NOT change the render op on ec->frame while mask object
5563 * is set. it will overwrite the changed op value. */
5564 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5565 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5566 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5567 if (cw->visible) evas_object_show(o);
5570 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5571 ELOGF("COMP", " |mask_obj", cw->ec);
5572 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5579 evas_object_smart_member_del(cw->mask.obj);
5580 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5582 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5583 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5589 e_comp_object_mask_has(Evas_Object *obj)
5591 API_ENTRY EINA_FALSE;
5593 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5597 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5602 if ((cw->external_content) &&
5603 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5605 WRN("Can set up size to ONLY evas \"image\" object. "
5606 "But current external content is %d object for %p.",
5607 cw->content_type, cw->ec);
5611 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5613 evas_object_image_size_set(cw->obj, tw, th);
5617 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5619 Eina_Bool transform_set = EINA_FALSE;
5621 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5622 if (cw->ec->input_only) return;
5624 transform_set = !!set;
5628 if (!cw->transform_bg_obj)
5630 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5631 evas_object_move(o, 0, 0);
5632 evas_object_resize(o, 1, 1);
5633 if (cw->transform_bg_color.a >= 255)
5634 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5636 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5637 evas_object_color_set(o,
5638 cw->transform_bg_color.r,
5639 cw->transform_bg_color.g,
5640 cw->transform_bg_color.b,
5641 cw->transform_bg_color.a);
5642 if (cw->visible) evas_object_show(o);
5644 cw->transform_bg_obj = o;
5645 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5647 _e_comp_object_transform_obj_stack_update(obj);
5651 if (cw->transform_bg_obj)
5653 evas_object_smart_member_del(cw->transform_bg_obj);
5654 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5660 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5664 cw->transform_bg_color.r = r;
5665 cw->transform_bg_color.g = g;
5666 cw->transform_bg_color.b = b;
5667 cw->transform_bg_color.a = a;
5669 if (cw->transform_bg_obj)
5671 evas_object_color_set(cw->transform_bg_obj,
5672 cw->transform_bg_color.r,
5673 cw->transform_bg_color.g,
5674 cw->transform_bg_color.b,
5675 cw->transform_bg_color.a);
5680 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5683 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5684 if (cw->ec->input_only) return;
5685 if (!cw->transform_bg_obj) return;
5687 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5691 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5694 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5695 if (cw->ec->input_only) return;
5696 if (!cw->transform_bg_obj) return;
5698 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5702 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5704 Eina_Bool transform_set = EINA_FALSE;
5706 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5707 if (cw->ec->input_only) return;
5709 transform_set = !!set;
5713 if (!cw->transform_tranp_obj)
5715 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5716 evas_object_move(o, 0, 0);
5717 evas_object_resize(o, 1, 1);
5718 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5719 evas_object_color_set(o, 0, 0, 0, 0);
5720 if (cw->visible) evas_object_show(o);
5722 cw->transform_tranp_obj = o;
5723 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5724 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5725 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5727 _e_comp_object_transform_obj_stack_update(obj);
5731 if (cw->transform_tranp_obj)
5733 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5734 evas_object_smart_member_del(cw->transform_tranp_obj);
5735 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5741 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5744 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5745 if (cw->ec->input_only) return;
5746 if (!cw->transform_tranp_obj) return;
5748 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5752 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5755 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5756 if (cw->ec->input_only) return;
5757 if (!cw->transform_tranp_obj) return;
5759 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5762 #ifdef REFACTOR_DESK_AREA
5765 e_comp_object_layer_update(Evas_Object *obj,
5766 Evas_Object *above, Evas_Object *below)
5768 E_Comp_Object *cw2 = NULL;
5769 Evas_Object *o = NULL;
5774 if (cw->ec->layer_block) return;
5775 if ((above) && (below))
5777 ERR("Invalid layer update request! cw=%p", cw);
5785 layer = evas_object_layer_get(o);
5786 cw2 = evas_object_data_get(o, "comp_obj");
5789 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5791 o = evas_object_above_get(o);
5792 if ((!o) || (o == cw->smart_obj)) break;
5793 if (evas_object_layer_get(o) != layer)
5795 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5800 ec = e_client_top_get();
5801 if (ec) o = ec->frame;
5804 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5808 _e_comp_object_layers_remove(cw);
5811 if (cw2->layer > cw->layer)
5812 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5813 else if (cw2->layer == cw->layer)
5816 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5818 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5820 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5823 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5826 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5831 e_comp_object_layer_get(Evas_Object *obj)
5838 e_comp_object_content_set(Evas_Object *obj,
5839 Evas_Object *content,
5840 E_Comp_Object_Content_Type type)
5842 API_ENTRY EINA_FALSE;
5844 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5845 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5846 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5850 ERR("Can't set e.swallow.content to requested content. "
5851 "Previous comp object should not be changed at all.");
5855 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5857 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5858 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5860 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5861 type, content, cw->ec, cw->ec->pixmap);
5865 cw->external_content = EINA_TRUE;
5868 cw->content_type = type;
5869 e_util_size_debug_set(cw->obj, 1);
5870 evas_object_name_set(cw->obj, "cw->obj");
5871 _e_comp_object_alpha_set(cw);
5874 _e_comp_object_shadow_setup(cw);
5880 e_comp_object_content_unset(Evas_Object *obj)
5882 API_ENTRY EINA_FALSE;
5884 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5885 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5887 if (!cw->obj && !cw->ec->visible)
5889 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5893 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5895 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5901 if (cw->frame_object)
5902 edje_object_part_unswallow(cw->frame_object, cw->obj);
5904 edje_object_part_unswallow(cw->shobj, cw->obj);
5906 evas_object_del(cw->obj);
5907 evas_object_hide(cw->obj);
5911 cw->external_content = EINA_FALSE;
5912 if (cw->ec->is_cursor)
5915 DBG("%p is cursor surface..", cw->ec);
5916 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5918 evas_object_resize(cw->ec->frame, pw, ph);
5919 evas_object_hide(cw->ec->frame);
5924 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5925 cw->obj = evas_object_image_filled_add(e_comp->evas);
5926 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5927 e_util_size_debug_set(cw->obj, 1);
5928 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5929 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5930 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5931 evas_object_name_set(cw->obj, "cw->obj");
5932 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5933 _e_comp_object_alpha_set(cw);
5936 _e_comp_object_shadow_setup(cw);
5941 _e_comp_intercept_show_helper(cw);
5945 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5946 e_comp_object_dirty(cw->smart_obj);
5947 e_comp_object_render(cw->smart_obj);
5948 e_comp_object_render_update_add(obj);
5953 EINTERN Evas_Object *
5954 e_comp_object_content_get(Evas_Object *obj)
5958 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5960 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5962 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5969 E_API E_Comp_Object_Content_Type
5970 e_comp_object_content_type_get(Evas_Object *obj)
5972 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5974 return cw->content_type;
5978 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5981 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5982 E_Comp_Config *conf = e_comp_config_get();
5983 if (cw->ec->input_only) return;
5984 if (!conf->dim_rect_enable) return;
5986 cw->dim.mask_set = mask_set;
5992 if (!cw->dim.enable) return;
5993 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5997 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5999 Eina_Bool mask_set = EINA_FALSE;
6003 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6004 E_Comp_Config *conf = e_comp_config_get();
6005 if (cw->ec->input_only) return;
6006 if (!conf->dim_rect_enable) return;
6012 if (cw->dim.mask_obj)
6014 evas_object_smart_member_del(cw->dim.mask_obj);
6015 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6018 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);
6019 o = evas_object_rectangle_add(e_comp->evas);
6020 evas_object_color_set(o, 0, 0, 0, 0);
6021 evas_object_smart_member_add(o, obj);
6022 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6023 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6025 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6026 if (cw->visible) evas_object_show(o);
6028 cw->dim.mask_obj = o;
6029 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6031 evas_object_layer_set(cw->dim.mask_obj, 9998);
6035 if (cw->dim.mask_obj)
6037 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6038 evas_object_smart_member_del(cw->dim.mask_obj);
6039 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6045 e_comp_object_dim_client_set(E_Client *ec)
6047 E_Comp_Config *conf = e_comp_config_get();
6049 if (!conf->dim_rect_enable) return ;
6050 if (dim_client == ec) return;
6052 Eina_Bool prev_dim = EINA_FALSE;
6053 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6055 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6056 prev_dim = EINA_TRUE;
6058 if (prev_dim && dim_client->visible && ec)
6060 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6061 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6065 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6066 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6072 e_comp_object_dim_client_get(void)
6074 E_Comp_Config *conf = e_comp_config_get();
6076 if (!conf->dim_rect_enable ) return NULL;
6082 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6085 char emit[32] = "\0";
6086 E_Comp_Config *conf = e_comp_config_get();
6089 if (!conf->dim_rect_enable) return;
6090 if (!cw->effect_obj) return;
6091 if (enable == cw->dim.enable) return;
6093 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6094 if (noeffect || !conf->dim_rect_effect)
6096 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6100 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6103 cw->dim.enable = enable;
6105 if (cw->dim.mask_set && !enable)
6107 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6108 edje_object_signal_emit(cw->effect_obj, emit, "e");
6110 else if (cw->dim.mask_set && enable)
6112 edje_object_signal_emit(cw->effect_obj, emit, "e");
6113 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6117 edje_object_signal_emit(cw->effect_obj, emit, "e");
6122 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6124 API_ENTRY EINA_FALSE;
6125 E_Comp_Config *conf = e_comp_config_get();
6127 if (!ec) return EINA_FALSE;
6128 if (!conf->dim_rect_enable) return EINA_FALSE;
6130 if (cw->dim.enable) return EINA_TRUE;
6136 _e_comp_object_dim_update(E_Comp_Object *cw)
6138 E_Comp_Config *conf = e_comp_config_get();
6141 if (!conf->dim_rect_enable) return;
6142 if (!cw->effect_obj) return;
6145 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6146 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6148 if (cw->dim.mask_set)
6150 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6156 e_comp_object_clear(Evas_Object *obj)
6160 _e_comp_object_clear(cw);
6164 e_comp_object_hwc_update_exists(Evas_Object *obj)
6166 API_ENTRY EINA_FALSE;
6167 return cw->hwc_need_update;
6172 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6175 cw->hwc_need_update = set;
6179 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6181 API_ENTRY EINA_FALSE;
6182 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6186 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6189 if (cw->indicator.obj != indicator)
6190 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6191 cw->indicator.obj = indicator;
6192 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6196 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6199 if (cw->indicator.obj != indicator) return;
6200 cw->indicator.obj = NULL;
6201 edje_object_part_unswallow(cw->shobj, indicator);
6205 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6208 Edje_Message_Int_Set *msg;
6210 if (!cw->indicator.obj) return;
6212 cw->indicator.w = w;
6213 cw->indicator.h = h;
6215 if (!cw->shobj) return;
6217 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6221 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6222 edje_object_message_signal_process(cw->shobj);
6225 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6227 e_comp_object_map_update(Evas_Object *obj)
6230 E_Client *ec = cw->ec;
6231 E_Comp_Wl_Client_Data *cdata;
6233 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6236 int l, remain = sizeof buffer;
6239 if (e_object_is_del(E_OBJECT(ec))) return;
6240 cdata = e_client_cdata_get(ec);
6243 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6244 * when new buffer is attached.
6246 if (!cdata->buffer_ref.buffer) return;
6248 if ((!cw->redirected) ||
6249 (e_client_video_hw_composition_check(ec)) ||
6250 (!e_comp_wl_output_buffer_transform_get(ec) &&
6251 cdata->scaler.buffer_viewport.buffer.scale == 1))
6253 if (evas_object_map_enable_get(cw->effect_obj))
6255 ELOGF("TRANSFORM", "map: disable", cw->ec);
6256 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6257 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6258 evas_object_resize(cw->effect_obj, tw, th);
6265 EINA_SAFETY_ON_NULL_RETURN(map);
6267 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6273 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6275 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6276 e_map_point_image_uv_set(map, 0, x, y);
6277 l = snprintf(p, remain, "%d,%d", x, y);
6278 p += l, remain -= l;
6280 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6281 e_map_point_image_uv_set(map, 1, x, y);
6282 l = snprintf(p, remain, " %d,%d", x, y);
6283 p += l, remain -= l;
6285 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6286 e_map_point_image_uv_set(map, 2, x, y);
6287 l = snprintf(p, remain, " %d,%d", x, y);
6288 p += l, remain -= l;
6290 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6291 e_map_point_image_uv_set(map, 3, x, y);
6292 l = snprintf(p, remain, " %d,%d", x, y);
6293 p += l, remain -= l;
6295 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6297 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6299 e_comp_object_map_set(cw->effect_obj, map);
6300 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6304 /* if there's screen rotation with comp mode, then ec->effect_obj and
6305 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6307 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6308 evas_object_resize(cw->effect_obj, tw, th);
6312 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6314 API_ENTRY EINA_FALSE;
6316 cw->render_trace = set;
6322 e_comp_object_native_usable_get(Evas_Object *obj)
6324 API_ENTRY EINA_FALSE;
6325 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6327 if (cw->ec->input_only) return EINA_FALSE;
6328 if (cw->external_content) return EINA_FALSE;
6329 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6331 /* just return true value, if it is normal case */
6332 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6335 Evas_Native_Surface *ns;
6336 ns = evas_object_image_native_surface_get(cw->obj);
6338 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6341 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6349 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6351 API_ENTRY EINA_FALSE;
6352 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6353 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6354 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6358 case E_COMP_IMAGE_FILTER_BLUR:
6359 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6361 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6362 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6364 case E_COMP_IMAGE_FILTER_INVERSE:
6365 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6367 case E_COMP_IMAGE_FILTER_NONE:
6369 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6373 cw->image_filter = filter;
6378 EINTERN E_Comp_Image_Filter
6379 e_comp_object_image_filter_get(Evas_Object *obj)
6381 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6382 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6383 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6384 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6386 return cw->image_filter;
6390 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6394 if (!_damage_trace) return;
6396 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6397 evas_object_del(obj);
6399 _damage_trace_post_objs = NULL;
6403 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6405 if (!_damage_trace) return;
6407 _damage_trace_post_objs = _damage_trace_objs;
6408 _damage_trace_objs = NULL;
6412 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6414 if (_damage_trace == onoff) return;
6418 evas_event_callback_add(e_comp->evas,
6419 EVAS_CALLBACK_RENDER_PRE,
6420 _e_comp_object_damage_trace_render_pre_cb,
6423 evas_event_callback_add(e_comp->evas,
6424 EVAS_CALLBACK_RENDER_POST,
6425 _e_comp_object_damage_trace_render_post_cb,
6432 EINA_LIST_FREE(_damage_trace_objs, obj)
6433 evas_object_del(obj);
6435 _damage_trace_objs = NULL;
6437 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6438 evas_object_del(obj);
6440 _damage_trace_post_objs = NULL;
6442 evas_event_callback_del(e_comp->evas,
6443 EVAS_CALLBACK_RENDER_PRE,
6444 _e_comp_object_damage_trace_render_pre_cb);
6446 evas_event_callback_del(e_comp->evas,
6447 EVAS_CALLBACK_RENDER_POST,
6448 _e_comp_object_damage_trace_render_post_cb);
6451 _damage_trace = onoff;
6455 e_comp_object_redirected_get(Evas_Object *obj)
6457 API_ENTRY EINA_FALSE;
6458 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6460 return cw->redirected;
6464 e_comp_object_color_visible_get(Evas_Object *obj)
6466 API_ENTRY EINA_FALSE;
6469 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6471 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6475 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6479 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6483 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6491 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6493 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6495 return e_map_set_to_comp_object(em, obj);
6499 e_comp_object_map_get(const Evas_Object *obj)
6501 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6503 return e_map_get_from_comp_object(obj);
6507 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6509 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6511 evas_object_map_enable_set(obj, enable);
6517 e_comp_object_render_update_lock(Evas_Object *obj)
6519 E_Comp_Wl_Buffer *buffer;
6520 struct wayland_tbm_client_queue *cqueue;
6522 API_ENTRY EINA_FALSE;
6524 if (cw->render_update_lock.lock == 0)
6526 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6528 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6529 if ((buffer) && (buffer->resource))
6531 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6533 wayland_tbm_server_client_queue_flush(cqueue);
6536 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6537 e_comp_object_render_update_del(obj);
6539 ELOGF("COMP", "Render update lock enabled", cw->ec);
6542 cw->render_update_lock.lock++;
6548 e_comp_object_render_update_unlock(Evas_Object *obj)
6552 if (cw->render_update_lock.lock == 0)
6555 cw->render_update_lock.lock--;
6557 if (cw->render_update_lock.lock == 0)
6560 if (cw->render_update_lock.pending_move_set)
6562 evas_object_move(obj,
6563 cw->render_update_lock.pending_move_x,
6564 cw->render_update_lock.pending_move_y);
6565 cw->render_update_lock.pending_move_x = 0;
6566 cw->render_update_lock.pending_move_y = 0;
6567 cw->render_update_lock.pending_move_set = EINA_FALSE;
6570 if (cw->render_update_lock.pending_resize_set)
6572 evas_object_resize(obj,
6573 cw->render_update_lock.pending_resize_w,
6574 cw->render_update_lock.pending_resize_h);
6575 cw->render_update_lock.pending_resize_w = 0;
6576 cw->render_update_lock.pending_resize_h = 0;
6577 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6580 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6582 if ((cw->ec->exp_iconify.buffer_flush) &&
6583 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6584 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6585 e_comp_object_clear(obj);
6587 e_comp_object_render_update_add(obj);
6589 ELOGF("COMP", "Render update lock disabled", cw->ec);
6594 e_comp_object_render_update_lock_get(Evas_Object *obj)
6596 API_ENTRY EINA_FALSE;
6598 if (cw->render_update_lock.lock > 0)
6605 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6609 if (cw->transparent.set)
6611 if (r) *r = cw->transparent.user_r;
6612 if (g) *g = cw->transparent.user_g;
6613 if (b) *b = cw->transparent.user_b;
6614 if (a) *a = cw->transparent.user_a;
6618 evas_object_color_get(obj, r, g, b, a);
6623 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6627 evas_object_render_op_set(cw->obj, op);
6630 EINTERN Evas_Render_Op
6631 e_comp_object_render_op_get(Evas_Object *obj)
6633 API_ENTRY EVAS_RENDER_BLEND;
6635 return evas_object_render_op_get(cw->obj);
6639 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6642 wl_signal_add(&cw->events.lower, listener);
6645 #ifdef REFACTOR_DESK_AREA
6647 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6650 wl_signal_add(&cw->events.lower_done, listener);
6654 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6657 wl_signal_add(&cw->events.raise, listener);
6662 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6665 wl_signal_add(&cw->events.show, listener);
6669 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6672 wl_signal_add(&cw->events.hide, listener);
6675 #ifdef REFACTOR_DESK_AREA
6677 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6680 wl_signal_add(&cw->events.set_layer, listener);
6684 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6687 wl_signal_add(&cw->events.stack_above, listener);
6691 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6694 wl_signal_add(&cw->events.stack_below, listener);