2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
8 = keys that return objects =
9 - E_Client: the client associated with the object (E_Client*)
10 - comp_smart_obj: cw->smart_obj (Evas_Object*)
11 - comp_obj: cw (E_Comp_Object*)
13 = keys that are bool flags =
14 - client_restack: client needs a protocol-level restack
15 - comp_override: object is triggering a nocomp override to force compositing
16 - comp_ref: object has a ref from visibility animations
17 - comp_showing: object is currently running its show animation
18 - comp_hiding: object is currently running its hiding animation
19 - comp_object: object is a compositor-created object
20 - comp_object_skip: object has a name which prohibits theme shadows
21 - comp_object-to_del: list of objects which will be deleted when this object is deleted
22 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
23 - effect_running: object is animating by external module
26 #define UPDATE_MAX 512 // same as evas
27 #define FAILURE_MAX 2 // seems reasonable
28 #define SMART_NAME "e_comp_object"
29 #define INPUT_OBJ_SMART_NAME "input_object"
31 /* for non-util functions */
32 #define API_ENTRY E_Comp_Object *cw; \
33 cw = evas_object_smart_data_get(obj); \
34 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
36 /* for util functions (obj may or may not be E_Comp_Object */
37 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
40 CRI("YOU PASSED NULL! ARGH!"); \
43 cw = evas_object_smart_data_get(obj); \
44 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
46 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
48 /* enable for lots of client size info in console output */
50 # define e_util_size_debug_set(x, y)
53 /* enable along with display-specific damage INF calls to enable render tracing
57 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
59 #define RENDER_DEBUG(...)
62 #ifdef REFACTOR_DESK_AREA
64 typedef struct _E_Comp_Object
68 int x, y, w, h; // geometry
72 E_Comp_Object_Frame client_inset;
74 Eina_Stringshare *frame_theme;
75 Eina_Stringshare *frame_name;
76 Eina_Stringshare *visibility_effect; //effect when toggling visibility
78 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
80 Evas_Object *smart_obj; // smart object
81 Evas_Object *clip; // clipper over effect object
82 Evas_Object *input_obj; // input smart object
83 Evas_Object *obj; // composite object
84 Evas_Object *frame_object; // for client frames
85 Evas_Object *shobj; // shadow object
86 Evas_Object *effect_obj; // effects object
87 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
92 Evas_Object *transform_tranp_obj;// transform transp rect obj
93 Evas_Object *default_input_obj; // default input object
94 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
95 Eina_List *obj_mirror; // extra mirror objects
96 Eina_Tiler *updates; //render update regions
97 Eina_Tiler *pending_updates; //render update regions which are about to render
99 Evas_Native_Surface *ns; //for custom gl rendering
101 struct wl_listener buffer_destroy_listener;
103 unsigned int update_count; // how many updates have happened to this obj
105 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
107 unsigned int animating; // it's busy animating
108 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
109 unsigned int force_visible; //number of visible obj_mirror objects
110 Eina_Bool delete_pending : 1; // delete pending
111 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
112 Eina_Bool showing : 1; // object is currently in "show" animation
113 Eina_Bool hiding : 1; // object is currently in "hide" animation
114 Eina_Bool visible : 1; // is visible
116 Eina_Bool shaped : 1; // is shaped
117 Eina_Bool update : 1; // has updates to fetch
118 Eina_Bool redirected : 1; // has updates to fetch
119 Eina_Bool native : 1; // native
121 Eina_Bool nocomp : 1; // nocomp applied
122 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
123 Eina_Bool real_hid : 1; // last hide was a real window unmap
125 Eina_Bool effect_set : 1; //effect_obj has a valid group
126 Eina_Bool effect_running : 1; //effect_obj is playing an animation
127 Eina_Bool effect_clip : 1; //effect_obj is clipped
128 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
130 Eina_Bool updates_exist : 1;
131 Eina_Bool updates_full : 1; // entire object will be updated
133 Eina_Bool force_move : 1;
134 Eina_Bool frame_extends : 1; //frame may extend beyond object size
135 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
136 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
137 Eina_Bool user_alpha_set : 1;
138 Eina_Bool user_alpha : 1;
142 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
143 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
150 } indicator; //indicator object for internal client
154 Evas_Object *mask_obj;
157 int mask_x, mask_y, mask_w, mask_h;
160 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
162 tbm_surface_h tbm_surface;
163 E_Comp_Image_Filter image_filter;
164 Eina_Bool set_mouse_callbacks;
169 E_Comp_Wl_Buffer_Ref buffer_ref;
170 Eina_Bool pending_move_set;
171 int pending_move_x, pending_move_y;
172 Eina_Bool pending_resize_set;
173 int pending_resize_w, pending_resize_h;
174 } render_update_lock;
187 struct wl_signal lower;
188 //#ifdef REFACTOR_DESK_AREA
189 struct wl_signal raise;
191 struct wl_signal show;
192 struct wl_signal hide;
193 //#ifdef REFACTOR_DESK_AREA
194 struct wl_signal set_layer;
195 struct wl_signal stack_above;
196 struct wl_signal stack_below;
202 typedef struct _E_Input_Rect_Data
208 typedef struct _E_Input_Rect_Smart_Data
210 Eina_List *input_rect_data_list;
212 } E_Input_Rect_Smart_Data;
214 struct E_Comp_Object_Mover
217 E_Comp_Object_Mover_Cb func;
223 static Eina_Inlist *_e_comp_object_movers = NULL;
224 static Evas_Smart *_e_comp_smart = NULL;
225 static Evas_Smart *_e_comp_input_obj_smart = NULL;
227 static int _e_comp_object_hooks_delete = 0;
228 static int _e_comp_object_hooks_walking = 0;
230 static Eina_Inlist *_e_comp_object_hooks[] =
232 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
233 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
234 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
235 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
236 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
237 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
238 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
239 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
242 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
243 static int _e_comp_object_intercept_hooks_delete = 0;
244 static int _e_comp_object_intercept_hooks_walking = 0;
246 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
248 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
249 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
253 static Eina_Bool _damage_trace = EINA_FALSE;
254 static Eina_List *_damage_trace_objs = NULL;
255 static Eina_List *_damage_trace_post_objs = NULL;
257 /* sekrit functionzzz */
258 EINTERN void e_client_focused_set(E_Client *ec);
260 /* emitted every time a new noteworthy comp object is added */
261 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
263 /* ecore event define */
264 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
265 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
266 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
268 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
269 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
270 static void _e_comp_object_dim_update(E_Comp_Object *cw);
271 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
272 #ifdef REFACTOR_DESK_AREA
274 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
277 static E_Client *dim_client = NULL;
280 _e_comp_object_hooks_clean(void)
283 E_Comp_Object_Hook *ch;
286 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
287 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
289 if (!ch->delete_me) continue;
290 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
296 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
298 E_Comp_Object_Hook *ch;
299 Eina_Bool ret = EINA_TRUE;
301 if (e_object_is_del(E_OBJECT(ec)))
303 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
304 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
305 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
306 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
307 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
308 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
309 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
310 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
316 e_object_ref(E_OBJECT(ec));
317 _e_comp_object_hooks_walking++;
318 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
320 if (ch->delete_me) continue;
321 if (!(ch->func(ch->data, ec)))
327 _e_comp_object_hooks_walking--;
328 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
329 _e_comp_object_hooks_clean();
331 e_object_unref(E_OBJECT(ec));
336 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
338 _e_comp_object_intercept_hooks_clean(void)
341 E_Comp_Object_Intercept_Hook *ch;
344 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
345 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
347 if (!ch->delete_me) continue;
348 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
354 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
356 E_Comp_Object_Intercept_Hook *ch;
357 Eina_Bool ret = EINA_TRUE;
359 if (e_object_is_del(E_OBJECT(ec))) return ret;
360 e_object_ref(E_OBJECT(ec));
361 _e_comp_object_intercept_hooks_walking++;
362 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
364 if (ch->delete_me) continue;
365 if (!(ch->func(ch->data, ec)))
371 _e_comp_object_intercept_hooks_walking--;
372 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
373 _e_comp_object_intercept_hooks_clean();
375 e_object_unref(E_OBJECT(ec));
382 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
384 E_Event_Comp_Object *ev = event;
387 ec = evas_object_data_get(ev->comp_object, "E_Client");
391 e_object_unref(E_OBJECT(ec));
393 evas_object_unref(ev->comp_object);
398 _e_comp_object_event_add(Evas_Object *obj)
400 E_Event_Comp_Object *ev;
403 if (stopping) return;
404 ev = E_NEW(E_Event_Comp_Object, 1);
405 EINA_SAFETY_ON_NULL_RETURN(ev);
407 evas_object_ref(obj);
408 ev->comp_object = obj;
409 ec = evas_object_data_get(ev->comp_object, "E_Client");
413 e_object_ref(E_OBJECT(ec));
415 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
419 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
421 E_Event_Comp_Object *ev = event;
424 ec = evas_object_data_get(ev->comp_object, "E_Client");
428 e_object_unref(E_OBJECT(ec));
430 evas_object_unref(ev->comp_object);
435 _e_comp_object_event_simple(Evas_Object *obj, int type)
437 E_Event_Comp_Object *ev;
440 ev = E_NEW(E_Event_Comp_Object, 1);
443 evas_object_ref(obj);
444 ev->comp_object = obj;
445 ec = evas_object_data_get(ev->comp_object, "E_Client");
449 e_object_ref(E_OBJECT(ec));
451 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
453 /////////////////////////////////////
456 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
458 E_Comp_Object *cw = data;
460 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
464 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
466 E_Comp_Object *cw = data;
468 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
469 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
472 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
473 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
477 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
479 E_Comp_Object *cw = data;
482 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
483 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
486 /////////////////////////////////////
488 #ifdef REFACTOR_DESK_AREA
490 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
493 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
498 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
499 if (cw->ec->input_only) return;
501 layer = evas_object_layer_get(obj);
503 if (cw->transform_bg_obj)
505 if (layer != evas_object_layer_get(cw->transform_bg_obj))
507 evas_object_layer_set(cw->transform_bg_obj, layer);
510 evas_object_stack_below(cw->transform_bg_obj, obj);
513 if (cw->transform_tranp_obj)
515 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
517 evas_object_layer_set(cw->transform_tranp_obj, layer);
520 evas_object_stack_below(cw->transform_tranp_obj, obj);
525 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
532 if (!map) return NULL;
534 e_map_util_points_populate_from_object_full(map, obj, 0);
535 e_map_util_points_color_set(map, 255, 255, 255, 255);
537 for (i = 0 ; i < 4 ; ++i)
542 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
543 e_map_point_coord_set(map, i, x, y, 1.0);
550 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_comp_object_map_set(obj, map);
560 e_comp_object_map_enable_set(obj, EINA_TRUE);
567 evas_object_map_enable_set(obj, EINA_FALSE);
572 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
578 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
581 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
583 e_comp_object_map_set(obj, map);
584 e_comp_object_map_enable_set(obj, EINA_TRUE);
591 evas_object_map_enable_set(obj, EINA_FALSE);
594 /////////////////////////////////////
596 static inline Eina_Bool
597 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
599 if (num > 1) return EINA_TRUE;
600 if ((rects[0].x == 0) && (rects[0].y == 0) &&
601 ((int)rects[0].w == w) && ((int)rects[0].h == h))
606 /////////////////////////////////////
608 /* add a client to the layer-client list */
609 #ifdef REFACTOR_DESK_AREA
611 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
614 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
617 g_rec_mutex_lock(&e_comp->ec_list_mutex);
620 e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
622 e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
623 if ((!above) && (!below))
626 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
627 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
628 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
630 e_comp->layers[cw->layer].clients_count++;
632 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
635 #ifdef REFACTOR_DESK_AREA
637 _e_comp_object_layers_remove(E_Comp_Object *cw)
640 _e_comp_object_layers_remove(E_Comp_Object *cw)
643 g_rec_mutex_lock(&e_comp->ec_list_mutex);
645 if (cw->ec && e_comp->layers[cw->layer].clients)
647 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
648 e_comp->layers[cw->layer].clients_count--;
651 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
654 /////////////////////////////////////
656 _e_comp_object_alpha_set(E_Comp_Object *cw)
658 Eina_Bool alpha = cw->ec->argb;
660 if ((cw->external_content) &&
661 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
666 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
667 if (cw->user_alpha_set) alpha = cw->user_alpha;
669 evas_object_image_alpha_set(cw->obj, alpha);
673 _e_comp_object_shadow(E_Comp_Object *cw)
675 if (e_client_util_shadow_state_get(cw->ec))
676 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
678 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
679 if (cw->frame_object)
680 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
681 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
684 /* convert from the surface coordinates to the buffer coordinates */
686 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
688 E_Comp_Wl_Buffer_Viewport *vp;
689 E_Comp_Wl_Client_Data *cdata;
693 cdata = e_client_cdata_get(ec);
695 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
702 vp = &cdata->scaler.buffer_viewport;
703 transform = e_comp_wl_output_buffer_transform_get(ec);
705 e_pixmap_size_get(ec->pixmap, &bw, &bh);
707 /* for subsurface, it should be swap 90 and 270 */
708 if (e_comp_wl_subsurface_check(ec))
711 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
712 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
713 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
714 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
720 case WL_OUTPUT_TRANSFORM_NORMAL:
721 default: tx = sx, ty = sy; break;
722 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
723 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
724 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
725 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
726 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
727 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
728 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
731 tx *= vp->buffer.scale;
732 ty *= vp->buffer.scale;
739 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
747 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
748 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
755 if (dw) *dw = MAX(x1, x2) - mx;
756 if (dh) *dh = MAX(y1, y2) - my;
760 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
761 int *dx, int *dy, int *dw, int *dh)
763 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
764 E_Util_Transform_Rect_Vertex sv, dv;
768 e_pixmap_size_get(ec->pixmap, &bw, &bh);
770 sv = e_util_transform_rect_to_vertices(&rect);
772 for (i = 0; i < 4; i++)
774 double x = 0.0, y = 0.0;
776 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
778 /* if evas decide coordinate is outside of map, it returns (0, 0)
779 in this case, full damage is added.
781 if ((i != 0) && (x == 0.0) && (y == 0.0))
784 dv.vertices[i].vertex[0] = x;
785 dv.vertices[i].vertex[1] = y;
786 dv.vertices[i].vertex[2] = 1.0;
787 dv.vertices[i].vertex[3] = 1.0;
790 rect = e_util_transform_vertices_to_rect(&dv);
792 if (dx) *dx = rect.x;
793 if (dy) *dy = rect.y;
794 if (dw) *dw = rect.w;
795 if (dh) *dh = rect.h;
809 _e_comp_object_map_damage_transform_get(E_Client *ec)
816 if (!e_client_transform_core_enable_get(ec))
819 m = e_client_map_get(ec);
823 e_pixmap_size_get(ec->pixmap, &bw, &bh);
824 if ((bw == 0) || (bh == 0))
837 e_map_point_coord_set(m2, 0, 0, 0, 0);
838 e_map_point_coord_set(m2, 1, bw, 0, 0);
839 e_map_point_coord_set(m2, 2, bw, bh, 0);
840 e_map_point_coord_set(m2, 3, 0, bh, 0);
842 for (i = 0; i < 4; i++)
846 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
847 e_map_point_image_uv_set(m2, i, map_x, map_y);
854 /////////////////////////////////////
856 /* handle evas mouse-in events on client object */
858 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
860 Evas_Event_Mouse_In *ev = event_info;
861 E_Comp_Object *cw = data;
863 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
866 /* handle evas mouse-out events on client object */
868 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
870 Evas_Event_Mouse_Out *ev = event_info;
871 E_Comp_Object *cw = data;
873 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
876 /* handle evas mouse wheel events on client object */
878 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
880 Evas_Event_Mouse_Wheel *ev = event_info;
881 E_Comp_Object *cw = data;
882 E_Binding_Event_Wheel ev2;
885 if (e_client_action_get()) return;
886 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
887 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
890 /* handle evas mouse down events on client object */
892 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
894 Evas_Event_Mouse_Down *ev = event_info;
895 E_Comp_Object *cw = data;
896 E_Binding_Event_Mouse_Button ev2;
899 if (e_client_action_get()) return;
900 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
901 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
904 /* handle evas mouse up events on client object */
906 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
908 Evas_Event_Mouse_Up *ev = event_info;
909 E_Comp_Object *cw = data;
910 E_Binding_Event_Mouse_Button ev2;
913 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
914 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
915 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
918 /* handle evas mouse movement events on client object */
920 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
922 Evas_Event_Mouse_Move *ev = event_info;
923 E_Comp_Object *cw = data;
926 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
927 e_client_mouse_move(cw->ec, &ev->cur.output);
929 /////////////////////////////////////
931 /* helper function for checking compositor themes based on user-defined matches */
933 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
935 if (((m->title) && (!ec->netwm.name)) ||
936 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
938 #if defined(__cplusplus) || defined(c_plusplus)
939 if (((m->clas) && (!ec->icccm.cpp_class)) ||
940 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
943 if (((m->clas) && (!ec->icccm.class)) ||
944 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
948 if (((m->role) && (!ec->icccm.window_role)) ||
949 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
955 if ((int)ec->netwm.type != m->primary_type)
958 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
961 if (m->borderless != 0)
965 if (e_client_util_borderless(ec))
967 if (!(((m->borderless == -1) && (!borderless)) ||
968 ((m->borderless == 1) && (borderless))))
975 if (((ec->icccm.transient_for != 0) ||
978 if (!(((m->dialog == -1) && (!dialog)) ||
979 ((m->dialog == 1) && (dialog))))
982 if (m->accepts_focus != 0)
984 int accepts_focus = 0;
986 if (ec->icccm.accepts_focus)
988 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
989 ((m->accepts_focus == 1) && (accepts_focus))))
998 if (!(((m->vkbd == -1) && (!vkbd)) ||
999 ((m->vkbd == 1) && (vkbd))))
1004 if (!(((m->argb == -1) && (!ec->argb)) ||
1005 ((m->argb == 1) && (ec->argb))))
1008 if (m->fullscreen != 0)
1010 int fullscreen = ec->fullscreen;
1012 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1013 ((m->fullscreen == 1) && (fullscreen))))
1018 if (!(m->modal == -1))
1024 /* function for setting up a client's compositor frame theme (cw->shobj) */
1026 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1030 Eina_List *list = NULL, *l;
1031 E_Input_Rect_Data *input_rect_data;
1032 E_Input_Rect_Smart_Data *input_rect_sd;
1034 Eina_Stringshare *reshadow_group = NULL;
1035 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1036 Eina_Stringshare *name, *title;
1037 E_Comp_Config *conf = e_comp_config_get();
1039 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1040 /* match correct client type */
1041 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1042 name = cw->ec->icccm.name;
1043 title = cw->ec->icccm.title;
1044 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1045 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1047 /* skipping here is mostly a hack for systray because I hate it */
1050 EINA_LIST_FOREACH(list, l, m)
1052 if (((m->name) && (!name)) ||
1053 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1055 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1058 no_shadow = m->no_shadow;
1059 if (m->shadow_style)
1061 /* fast effects are just themes with "/fast" appended and shorter effect times */
1064 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1065 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1067 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1069 /* default to non-fast style if fast not available */
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1077 if (ok && m->visibility_effect)
1078 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1085 if (skip || (cw->ec->e.state.video))
1087 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1089 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1092 if (conf->shadow_style)
1096 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1097 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1099 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1103 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1104 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1106 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1119 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1121 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1126 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1131 if (cw->ec->override)
1133 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1134 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1136 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1137 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1143 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1144 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1147 _e_comp_object_shadow(cw);
1150 if (focus || cw->ec->focused || cw->ec->override)
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1158 /* visibility must always be enabled for re_manage clients to prevent
1159 * pop-in animations every time the user sees a persistent client again;
1160 * applying visibility for iconic clients prevents the client from getting
1163 if (cw->visible || cw->ec->re_manage)
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1168 /* breaks animation counter */
1169 if (cw->frame_object)
1171 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1172 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1184 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1187 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1189 if (input_rect_data->obj)
1191 pass_event_flag = EINA_TRUE;
1197 if (cw->indicator.obj)
1199 Evas_Object *indicator;
1200 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1201 if (indicator != cw->indicator.obj)
1203 edje_object_part_unswallow(cw->shobj, indicator);
1204 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1205 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1209 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1210 evas_object_pass_events_set(cw->obj, pass_event_flag);
1215 /////////////////////////////////////////////
1218 _e_comp_object_animating_begin(E_Comp_Object *cw)
1221 if (cw->animating == 1)
1223 e_comp->animating++;
1225 e_object_ref(E_OBJECT(cw->ec));
1230 _e_comp_object_animating_end(E_Comp_Object *cw)
1239 if (cw->ec->launching)
1241 if (!cw->ec->extra_animating)
1243 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1244 cw->ec->launching = EINA_FALSE;
1245 if (cw->ec->first_mapped)
1247 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1248 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1251 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1255 e_comp->animating--;
1256 cw->showing = cw->hiding = 0;
1258 if (e_comp->animating == 0)
1259 e_comp_visibility_calculation_set(EINA_TRUE);
1260 /* remove ref from animation start, account for possibility of deletion from unref */
1261 return !!e_object_unref(E_OBJECT(cw->ec));
1267 /* handle the end of a compositor animation */
1269 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1271 E_Comp_Object *cw = data;
1273 /* visible clients which have never been sized are a bug */
1274 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1275 CRI("ACK! ec:%p", cw->ec);
1276 if (!_e_comp_object_animating_end(cw)) return;
1277 if (cw->animating) return;
1278 /* hide only after animation finishes to guarantee a full run of the animation */
1279 if (!cw->defer_hide) return;
1280 if ((!strcmp(emission, "e,action,hide,done")) ||
1281 (!strcmp(emission, "e,action,done")) ||
1282 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1284 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1285 evas_object_hide(cw->smart_obj);
1289 /* run a visibility compositor effect if available, return false if object is dead */
1291 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1297 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1298 if (!cw->effect_running)
1299 _e_comp_object_animating_begin(cw);
1300 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1301 return _e_comp_object_animating_end(cw);
1302 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1303 return _e_comp_object_animating_end(cw);
1305 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1308 zone = e_comp_zone_find_by_ec(cw->ec);
1310 zw = zone->w, zh = zone->h;
1315 zone = e_comp_object_util_zone_get(cw->smart_obj);
1316 if (!zone) zone = e_zone_current_get();
1323 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1324 cw->w, cw->h, zw, zh, x, y}, 8);
1325 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1326 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1329 /////////////////////////////////////////////
1331 /* create necessary objects for clients that e manages */
1333 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1335 if (cw->set_mouse_callbacks) return;
1336 if (!cw->smart_obj) return;
1338 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1339 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1340 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1341 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1342 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1343 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1345 cw->set_mouse_callbacks = EINA_TRUE;
1349 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1351 if (!cw->set_mouse_callbacks) return;
1352 if (!cw->smart_obj) return;
1354 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1355 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1356 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1357 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1358 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1359 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1361 cw->set_mouse_callbacks = EINA_FALSE;
1365 _e_comp_object_setup(E_Comp_Object *cw)
1367 cw->clip = evas_object_rectangle_add(e_comp->evas);
1368 evas_object_move(cw->clip, -9999, -9999);
1369 evas_object_resize(cw->clip, 999999, 999999);
1370 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1371 cw->effect_obj = edje_object_add(e_comp->evas);
1372 evas_object_move(cw->effect_obj, cw->x, cw->y);
1373 evas_object_clip_set(cw->effect_obj, cw->clip);
1374 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1375 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1376 cw->shobj = edje_object_add(e_comp->evas);
1377 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1378 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1379 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1381 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1382 if (cw->ec->override)
1384 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1385 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1386 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1388 else if (!cw->ec->input_only)
1390 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1391 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1392 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1394 cw->real_hid = !cw->ec->input_only;
1395 if (!cw->ec->input_only)
1397 e_util_size_debug_set(cw->effect_obj, 1);
1398 _e_comp_object_mouse_event_callback_set(cw);
1401 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1402 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1403 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1404 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1405 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1406 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1408 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1411 /////////////////////////////////////////////
1413 /* for fast path evas rendering; only called during render */
1415 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1417 E_Comp_Object *cw = data;
1418 E_Client *ec = cw->ec;
1420 int bx, by, bxx, byy;
1422 if (e_object_is_del(E_OBJECT(ec))) return;
1423 if (cw->external_content) return;
1424 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1425 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1428 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1429 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1431 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1433 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1434 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1438 bx = by = bxx = byy = 0;
1439 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1442 Edje_Message_Int_Set *msg;
1443 Edje_Message_Int msg2;
1444 Eina_Bool id = (bx || by || bxx || byy);
1446 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1452 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1454 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1458 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1459 e_comp_client_post_update_add(cw->ec);
1461 else if (e_comp_object_render(ec->frame))
1463 /* apply shape mask if necessary */
1464 if ((!cw->native) && (ec->shaped))
1465 e_comp_object_shape_apply(ec->frame);
1467 /* shaped clients get precise mouse events to handle transparent pixels */
1468 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1470 /* queue another render if client is still dirty; cannot refresh here. */
1471 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1472 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1474 if (cw->render_trace)
1476 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1482 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1484 E_Comp_Object *cw = data;
1485 E_Client *ec = cw->ec;
1487 if (e_object_is_del(E_OBJECT(ec))) return;
1488 if (cw->external_content) return;
1489 if (!e_comp->hwc) return;
1491 e_comp_client_render_list_add(cw->ec);
1493 if (!ec->hwc_window) return;
1495 e_hwc_windows_rendered_window_add(ec->hwc_window);
1498 /////////////////////////////////////////////
1501 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1503 E_Comp_Object *cw = data;
1506 if (cw->render_update_lock.lock)
1508 cw->render_update_lock.pending_move_x = x;
1509 cw->render_update_lock.pending_move_y = y;
1510 cw->render_update_lock.pending_move_set = EINA_TRUE;
1514 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1515 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1516 (cw->external_content))
1518 /* delay to move until the external content is unset */
1519 cw->ec->changes.pos = 1;
1524 if (cw->ec->move_after_resize)
1526 if ((x != cw->ec->x) || (y != cw->ec->y))
1528 if (!cw->ec->is_cursor)
1529 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1530 e_client_pos_set(cw->ec, x, y);
1531 cw->ec->changes.pos = 1;
1537 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1538 (cw->ec->manage_resize.resize_obj))
1540 e_client_pos_set(cw->ec, x, y);
1541 cw->ec->client.x = x + cw->client_inset.l;
1542 cw->ec->client.y = y + cw->client_inset.t;
1543 e_policy_visibility_client_defer_move(cw->ec);
1547 /* if frame_object does not exist, client_inset indicates CSD.
1548 * this means that ec->client matches cw->x/y, the opposite
1551 fx = (!cw->frame_object) * cw->client_inset.l;
1552 fy = (!cw->frame_object) * cw->client_inset.t;
1553 if ((cw->x == x + fx) && (cw->y == y + fy))
1555 if ((cw->ec->x != x) || (cw->ec->y != y))
1557 /* handle case where client tries to move to position and back very quickly */
1558 e_client_pos_set(cw->ec, x, y);
1559 cw->ec->client.x = x + cw->client_inset.l;
1560 cw->ec->client.y = y + cw->client_inset.t;
1564 if (!cw->ec->maximize_override)
1566 /* prevent moving in some directions while directionally maximized */
1567 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1569 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1572 ix = x + cw->client_inset.l;
1573 iy = y + cw->client_inset.t;
1574 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1575 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1576 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1578 /* prevent moving at all if move isn't allowed in current maximize state */
1579 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1580 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1583 zone = e_comp_zone_find_by_ec(cw->ec);
1586 cw->ec->changes.need_unmaximize = 1;
1587 cw->ec->saved.x = ix - zone->x;
1588 cw->ec->saved.y = iy - zone->y;
1589 cw->ec->saved.w = cw->ec->client.w;
1590 cw->ec->saved.h = cw->ec->client.h;
1594 /* only update during resize if triggered by resize */
1595 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1596 /* delay to move while surface waits paired commit serial*/
1597 if (e_client_pending_geometry_has(cw->ec))
1599 /* do nothing while waiting paired commit serial*/
1603 e_client_pos_set(cw->ec, x, y);
1604 if (cw->ec->new_client)
1606 /* don't actually do anything until first client idler loop */
1607 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1608 cw->ec->changes.pos = 1;
1613 /* only update xy position of client to avoid invalid
1614 * first damage region if it is not a new_client. */
1615 cw->ec->client.x = ix;
1616 cw->ec->client.y = iy;
1619 if (!cw->frame_object)
1621 evas_object_move(obj, x, y);
1626 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1628 E_Comp_Object *cw = data;
1629 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1632 if (cw->render_update_lock.lock)
1634 cw->render_update_lock.pending_resize_w = w;
1635 cw->render_update_lock.pending_resize_h = h;
1636 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1640 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1642 e_client_size_set(cw->ec, w, h);
1643 evas_object_resize(obj, w, h);
1647 /* if frame_object does not exist, client_inset indicates CSD.
1648 * this means that ec->client matches cw->w/h, the opposite
1651 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1652 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1653 if ((cw->w == w + fw) && (cw->h == h + fh))
1655 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1656 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1657 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1659 /* handle case where client tries to resize itself and back very quickly */
1660 e_client_size_set(cw->ec, w, h);
1661 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1662 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1663 evas_object_smart_callback_call(obj, "client_resize", NULL);
1667 /* guarantee that fullscreen is fullscreen */
1668 zone = e_comp_zone_find_by_ec(cw->ec);
1670 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1672 if (!e_client_transform_core_enable_get(cw->ec))
1675 /* calculate client size */
1676 iw = w - cw->client_inset.l - cw->client_inset.r;
1677 ih = h - cw->client_inset.t - cw->client_inset.b;
1678 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1680 /* prevent resizing while maximized depending on direction and config */
1681 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1683 Eina_Bool reject = EINA_FALSE;
1684 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1686 if (cw->ec->client.h != ih)
1688 cw->ec->saved.h = ih;
1689 cw->ec->saved.y = cw->ec->client.y - zone->y;
1690 reject = cw->ec->changes.need_unmaximize = 1;
1693 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1695 if (cw->ec->client.w != iw)
1697 cw->ec->saved.w = iw;
1698 cw->ec->saved.x = cw->ec->client.x - zone->x;
1699 reject = cw->ec->changes.need_unmaximize = 1;
1708 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1710 /* do nothing until client idler loops */
1711 if ((cw->ec->w != w) || (cw->ec->h != h))
1713 e_client_size_set(cw->ec, w, h);
1714 cw->ec->changes.size = 1;
1719 if (e_client_pending_geometry_has(cw->ec))
1721 /* do nothing while waiting paired commit serial*/
1725 e_client_size_set(cw->ec, w, h);
1727 cw->ec->client.w = iw;
1728 cw->ec->client.h = ih;
1729 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1731 /* The size of non-compositing window can be changed, so there is a
1732 * need to check that cw is H/W composited if cw is not redirected.
1733 * And of course we have to change size of evas object of H/W composited cw,
1734 * otherwise cw can't receive input events even if it is shown on the screen.
1736 Eina_Bool redirected = cw->redirected;
1738 redirected = e_comp_is_on_overlay(cw->ec);
1740 if ((!cw->ec->input_only) && (redirected) &&
1741 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1742 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1743 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1744 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1747 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1748 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1750 prev_w = cw->w, prev_h = cw->h;
1751 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1752 /* check shading and clamp to pixmap size for regular clients */
1753 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1754 (((w - fw != pw) || (h - fh != ph))))
1756 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1757 evas_object_smart_callback_call(obj, "client_resize", NULL);
1759 if (cw->frame_object || cw->ec->input_only)
1760 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1763 if ((cw->w == w) && (cw->h == h))
1765 /* going to be a noop resize which won't trigger smart resize */
1766 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1767 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1769 evas_object_resize(obj, w, h);
1773 evas_object_smart_callback_call(obj, "client_resize", NULL);
1776 if ((!cw->frame_object) && (!cw->ec->input_only))
1778 /* "just do it" for overrides */
1779 evas_object_resize(obj, w, h);
1781 if (!cw->ec->override)
1783 /* shape probably changed for non-overrides */
1788 /* this fixes positioning jiggles when using a resize mode
1789 * which also changes the client's position
1792 if (cw->frame_object)
1793 x = cw->x, y = cw->y;
1795 x = cw->ec->x, y = cw->ec->y;
1796 switch (cw->ec->resize_mode)
1798 case E_POINTER_RESIZE_BL:
1799 case E_POINTER_RESIZE_L:
1800 evas_object_move(obj, x + prev_w - cw->w, y);
1802 case E_POINTER_RESIZE_TL:
1803 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1805 case E_POINTER_RESIZE_T:
1806 case E_POINTER_RESIZE_TR:
1807 evas_object_move(obj, x, y + prev_h - cw->h);
1816 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1818 #ifdef REFACTOR_DESK_AREA
1819 E_Comp_Object *cw = data;
1820 E_Comp_Object_Data_Set_Layer layer_set_data;
1822 layer_set_data.cw = cw;
1823 layer_set_data.layer = layer;
1825 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1829 e_comp_render_queue();
1830 _e_comp_object_transform_obj_stack_update(obj);
1834 E_Comp_Object *cw = data;
1835 E_Comp_Wl_Client_Data *child_cdata;
1836 unsigned int l = e_comp_canvas_layer_map(layer);
1839 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1841 /* doing a compositor effect, follow directions */
1842 _e_comp_object_layer_set(obj, layer);
1843 if (layer == cw->ec->layer) //trying to put layer back
1847 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1848 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1849 if (cw->layer != l) goto layer_set;
1853 e_comp_render_queue();
1855 ec = e_client_above_get(cw->ec);
1856 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1857 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1858 ec = e_client_above_get(ec);
1859 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1861 ec = e_client_below_get(cw->ec);
1862 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1863 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1864 ec = e_client_below_get(ec);
1865 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1867 evas_object_stack_above(obj, ec->frame);
1872 if (ec && (cw->ec->parent == ec))
1874 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1875 evas_object_stack_above(obj, ec->frame);
1877 evas_object_stack_below(obj, ec->frame);
1880 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1886 if (cw->layer == l) return;
1887 if (e_comp_canvas_client_layer_map(layer) == 9999)
1888 return; //invalid layer for clients not doing comp effects
1889 if (cw->ec->fullscreen)
1891 cw->ec->saved.layer = layer;
1894 oldraise = e_config->transient.raise;
1896 /* clamp to valid client layer */
1897 layer = e_comp_canvas_client_layer_map_nearest(layer);
1898 cw->ec->layer = layer;
1899 if (e_config->transient.layer)
1902 Eina_List *list = eina_list_clone(cw->ec->transients);
1904 /* We need to set raise to one, else the child wont
1905 * follow to the new layer. It should be like this,
1906 * even if the user usually doesn't want to raise
1909 e_config->transient.raise = 1;
1910 EINA_LIST_FREE(list, child)
1912 child_cdata = e_client_cdata_get(child);
1913 if (child_cdata && !child_cdata->mapped)
1915 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1918 e_client_layer_set(child, layer);
1922 e_config->transient.raise = oldraise;
1924 _e_comp_object_layers_remove(cw);
1925 cw->layer = e_comp_canvas_layer_map(layer);
1926 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1927 //if (cw->ec->new_client)
1928 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1929 _e_comp_object_layer_set(obj, layer);
1930 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1931 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1932 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1934 /* can't stack a client above its own layer marker */
1935 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1937 if (!cw->visible) return;
1938 e_comp_render_queue();
1939 _e_comp_object_transform_obj_stack_update(obj);
1943 #ifdef REFACTOR_DESK_AREA
1945 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1949 _e_comp_object_raise(Evas_Object *obj)
1951 evas_object_raise(obj);
1953 if (evas_object_smart_smart_get(obj))
1955 E_Client *ec = e_comp_object_client_get(obj);
1957 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1961 #ifdef REFACTOR_DESK_AREA
1963 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1966 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1969 evas_object_lower(obj);
1971 if (evas_object_smart_smart_get(obj))
1973 E_Client *ec = e_comp_object_client_get(obj);
1976 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1977 #ifdef REFACTOR_DESK_AREA
1978 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1980 wl_signal_emit_mutable(&cw->events.lower, NULL);
1986 #ifdef REFACTOR_DESK_AREA
1988 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1991 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1994 evas_object_stack_above(obj, target);
1996 if (evas_object_smart_smart_get(obj))
1998 E_Client *ec = e_comp_object_client_get(obj);
2000 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2004 #ifdef REFACTOR_DESK_AREA
2006 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2009 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2012 evas_object_stack_below(obj, target);
2014 if (evas_object_smart_smart_get(obj))
2016 E_Client *ec = e_comp_object_client_get(obj);
2018 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2022 #ifdef REFACTOR_DESK_AREA
2024 e_comp_object_layer_set(Evas_Object *obj, short layer)
2027 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2030 evas_object_layer_set(obj, layer);
2032 if (evas_object_smart_smart_get(obj))
2034 E_Client *ec = e_comp_object_client_get(obj);
2036 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
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;
2052 #ifdef REFACTOR_DESK_AREA
2054 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2057 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2060 E_Comp_Object *cw2 = NULL;
2063 Evas_Object *o = stack;
2064 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2066 /* We should consider topmost's layer_pending for subsurface */
2067 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2069 if (_e_comp_object_is_pending(cw->ec))
2070 e_comp_object_layer_update(cw->smart_obj,
2071 raising? stack : NULL,
2072 raising? NULL : stack);
2074 /* obey compositor effects! */
2075 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2076 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2077 stack_cb(cw->smart_obj, stack);
2078 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2079 evas_object_data_del(cw->smart_obj, "client_restack");
2083 cw2 = evas_object_data_get(o, "comp_obj");
2085 /* assume someone knew what they were doing during client init */
2086 if (cw->ec->new_client)
2087 layer = cw->ec->layer;
2088 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2089 layer = cw2->ec->layer;
2091 layer = evas_object_layer_get(stack);
2092 ecstack = e_client_below_get(cw->ec);
2093 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2095 evas_object_layer_set(cw->smart_obj, layer);
2096 /* we got our layer wrangled, return now! */
2097 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2100 /* check if we're stacking below another client */
2103 /* check for non-client layer object */
2104 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2106 /* find an existing client to use for layering
2107 * by walking up the object stack
2109 * this is guaranteed to be pretty quick since we'll either:
2110 * - run out of client layers
2111 * - find a stacking client
2113 o = evas_object_above_get(o);
2114 if ((!o) || (o == cw->smart_obj)) break;
2115 if (evas_object_layer_get(o) != layer)
2117 /* reached the top client layer somehow
2118 * use top client object
2120 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2123 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2124 * return here since the top client layer window
2129 ec = e_client_top_get();
2134 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2137 if (cw2 && cw->layer != cw2->layer)
2140 /* remove existing layers */
2141 _e_comp_object_layers_remove(cw);
2144 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2145 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2146 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2147 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2148 else //if no stacking objects found, either raise or lower
2149 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2152 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2154 /* find new object for stacking if cw2 is on state of layer_pending */
2155 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2157 E_Client *new_stack = NULL, *current_ec = NULL;
2158 current_ec = cw2->ec;
2161 while ((new_stack = e_client_below_get(current_ec)))
2163 current_ec = new_stack;
2164 if (new_stack == cw->ec) continue;
2165 if (new_stack->layer != cw2->ec->layer) break;
2166 if (!_e_comp_object_is_pending(new_stack)) break;
2168 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2169 stack = new_stack->frame;
2172 /* stack it above layer object */
2174 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2175 stack = e_comp->layers[below_layer].obj;
2180 while ((new_stack = e_client_above_get(current_ec)))
2182 current_ec = new_stack;
2183 if (new_stack == cw->ec) continue;
2184 if (new_stack->layer != cw2->ec->layer) break;
2185 if (!_e_comp_object_is_pending(new_stack)) break;
2187 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2188 stack = new_stack->frame;
2190 stack = e_comp->layers[cw2->layer].obj;
2194 /* set restack if stacking has changed */
2195 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2196 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2197 stack_cb(cw->smart_obj, stack);
2198 if (e_comp->layers[cw->layer].obj)
2199 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2201 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2203 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2204 evas_object_data_del(cw->smart_obj, "client_restack");
2205 if (!cw->visible) return;
2206 e_comp_render_queue();
2210 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2212 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2214 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2216 #ifdef REFACTOR_DESK_AREA
2217 E_Comp_Object *cw = data;
2218 E_Comp_Object_Data_Stack_Above stack_above_data;
2220 stack_above_data.cw = cw;
2221 stack_above_data.above_obj = above;
2223 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2225 if (evas_object_below_get(obj) == above)
2227 e_comp_object_layer_update(obj, above, NULL);
2231 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2233 _e_comp_object_transform_obj_stack_update(obj);
2234 _e_comp_object_transform_obj_stack_update(above);
2241 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2243 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2245 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2247 #ifdef REFACTOR_DESK_AREA
2248 E_Comp_Object *cw = data;
2249 E_Comp_Object_Data_Stack_Below stack_below_data;
2251 stack_below_data.cw = cw;
2252 stack_below_data.below_obj = below;
2254 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2257 e_comp_render_queue();
2259 if (evas_object_above_get(obj) == below)
2261 e_comp_object_layer_update(obj, NULL, below);
2265 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2267 if (evas_object_smart_smart_get(obj))
2268 _e_comp_object_transform_obj_stack_update(obj);
2269 if (evas_object_smart_smart_get(below))
2270 _e_comp_object_transform_obj_stack_update(below);
2277 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2279 E_Comp_Object *cw = data;
2281 #ifdef REFACTOR_DESK_AREA
2286 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2288 #ifdef REFACTOR_DESK_AREA
2289 wl_signal_emit_mutable(&cw->events.lower, cw);
2290 wl_signal_emit_mutable(&cw->events.lower_done, cw);
2292 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2294 if (cw->ec->layer_pending)
2295 e_comp_object_layer_update(obj, NULL, obj);
2297 _e_comp_object_lower(cw, obj);
2300 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2301 o = evas_object_below_get(obj);
2302 _e_comp_object_layers_remove(cw);
2303 /* prepend to client list since this client should be the first item now */
2304 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2305 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2306 evas_object_data_set(obj, "client_restack", (void*)1);
2307 _e_comp_object_lower(cw, obj);
2308 evas_object_data_del(obj, "client_restack");
2309 if (!cw->visible) goto end;
2310 e_comp_render_queue();
2311 _e_comp_object_transform_obj_stack_update(obj);
2318 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2320 E_Comp_Object *cw = data;
2324 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2326 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2328 if (cw->ec->layer_pending)
2330 int obj_layer = evas_object_layer_get(obj);
2331 if (cw->ec->layer != obj_layer)
2332 e_comp_object_layer_update(obj, NULL, NULL);
2335 _e_comp_object_raise(obj);
2338 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2339 o = evas_object_above_get(obj);
2340 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2342 /* still stack below override below the layer marker */
2343 for (op = o = e_comp->layers[cw->layer].obj;
2344 o && o != e_comp->layers[cw->layer - 1].obj;
2345 op = o, o = evas_object_below_get(o))
2347 if (evas_object_smart_smart_get(o))
2351 ec = e_comp_object_client_get(o);
2352 if (ec && (!ec->override)) break;
2355 _e_comp_object_stack_below(obj, op);
2356 e_client_focus_defer_set(cw->ec);
2358 if (!cw->visible) goto end;
2359 e_comp_render_queue();
2360 _e_comp_object_transform_obj_stack_update(obj);
2368 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2370 E_Comp_Object *cw = data;
2372 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2373 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2375 ELOGF("COMP", "Hide. intercepted", cw->ec);
2380 if (cw->ec->launching == EINA_TRUE)
2382 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2383 cw->ec->launching = EINA_FALSE;
2388 /* hidden flag = just do it */
2389 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2390 evas_object_hide(obj);
2392 wl_signal_emit_mutable(&cw->events.hide, NULL);
2397 if (cw->ec->input_only)
2399 /* input_only = who cares */
2400 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2401 evas_object_hide(obj);
2403 wl_signal_emit_mutable(&cw->events.hide, NULL);
2407 /* already hidden or currently animating */
2408 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2410 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2414 /* don't try hiding during shutdown */
2415 cw->defer_hide |= stopping;
2416 if (!cw->defer_hide)
2418 if ((!cw->ec->iconic) && (!cw->ec->override))
2419 /* unset delete requested so the client doesn't break */
2420 cw->ec->delete_requested = 0;
2421 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2423 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2424 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2427 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2430 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2432 _e_comp_object_animating_begin(cw);
2433 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2435 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2436 cw->defer_hide = !!cw->animating;
2438 e_comp_object_effect_set(obj, NULL);
2441 if (cw->animating) return;
2442 /* if we have no animations running, go ahead and hide */
2444 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2445 evas_object_hide(obj);
2447 wl_signal_emit_mutable(&cw->events.hide, NULL);
2451 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2453 E_Client *ec = cw->ec;
2456 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2458 if (ec->show_pending.count > 0)
2460 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2461 ec->show_pending.running = EINA_TRUE;
2465 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2466 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2468 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2473 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,
2474 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2475 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2478 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2481 if (ec->iconic && cw->animating)
2483 /* triggered during iconify animation */
2484 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2487 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2490 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2491 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2493 evas_object_move(cw->smart_obj, ec->x, ec->y);
2494 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2495 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2497 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2498 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2501 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2502 evas_object_show(cw->smart_obj);
2505 e_client_focus_defer_set(ec);
2509 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2513 pw = ec->client.w, ph = ec->client.h;
2515 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2517 ec->changes.visible = !ec->hidden;
2520 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2524 cw->updates = eina_tiler_new(pw, ph);
2527 ec->changes.visible = !ec->hidden;
2530 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2535 eina_tiler_tile_size_set(cw->updates, 1, 1);
2538 /* ignore until client idler first run */
2539 ec->changes.visible = !ec->hidden;
2542 ELOGF("COMP", "show_helper. return. new_client", ec);
2549 evas_object_move(cw->smart_obj, ec->x, ec->y);
2550 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2551 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2552 evas_object_show(cw->smart_obj);
2555 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2557 /* start_drag not received */
2558 ec->changes.visible = 1;
2561 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2564 /* re-set geometry */
2565 evas_object_move(cw->smart_obj, ec->x, ec->y);
2566 /* force resize in case it hasn't happened yet, or just to update size */
2567 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2568 if ((cw->w < 1) || (cw->h < 1))
2570 /* if resize didn't go through, try again */
2571 ec->visible = ec->changes.visible = 1;
2573 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2576 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2577 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2578 e_pixmap_clear(ec->pixmap);
2580 if (cw->real_hid && w && h)
2583 /* force comp theming in case it didn't happen already */
2584 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2585 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2586 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2589 /* only do the show if show is allowed */
2592 if (ec->internal) //internal clients render when they feel like it
2593 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2595 if (!e_client_is_iconified_by_client(ec)||
2596 e_policy_visibility_client_is_uniconic(ec))
2598 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2599 evas_object_show(cw->smart_obj);
2601 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2602 it is rendered in idle callback without native surface and
2603 compositor shows an empty frame if other objects aren't shown
2604 because job callback of e_comp called at the next loop.
2605 it causes a visual defect when windows are switched.
2609 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2610 e_comp_object_dirty(cw->smart_obj);
2611 e_comp_object_render(cw->smart_obj);
2616 wl_signal_emit_mutable(&cw->events.show, NULL);
2620 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2622 E_Comp_Object *cw = data;
2623 E_Client *ec = cw->ec;
2625 E_Input_Rect_Data *input_rect_data;
2626 E_Input_Rect_Smart_Data *input_rect_sd;
2629 if (ec->ignored) return;
2633 //INF("SHOW2 %p", ec);
2634 _e_comp_intercept_show_helper(cw);
2637 //INF("SHOW %p", ec);
2640 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2641 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2642 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2643 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2647 if ((!cw->obj) && (cw->external_content))
2649 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2653 _e_comp_object_setup(cw);
2656 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2657 cw->obj = evas_object_image_filled_add(e_comp->evas);
2658 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2659 e_util_size_debug_set(cw->obj, 1);
2660 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2661 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2662 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2663 evas_object_name_set(cw->obj, "cw->obj");
2664 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2666 _e_comp_object_alpha_set(cw);
2669 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2672 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2673 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2676 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2679 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2681 if (input_rect_data->obj)
2683 evas_object_geometry_set(input_rect_data->obj,
2684 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2685 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2686 input_rect_data->rect.w, input_rect_data->rect.h);
2693 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2695 _e_comp_intercept_show_helper(cw);
2699 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2701 E_Comp_Object *cw = data;
2705 /* note: this is here as it seems there are enough apps that do not even
2706 * expect us to emulate a look of focus but not actually set x input
2707 * focus as we do - so simply abort any focus set on such windows */
2708 /* be strict about accepting focus hint */
2709 /* be strict about accepting focus hint */
2710 if ((!ec->icccm.accepts_focus) &&
2711 (!ec->icccm.take_focus))
2715 if (e_client_focused_get() == ec)
2716 e_client_focused_set(NULL);
2718 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2719 evas_object_focus_set(obj, focus);
2723 if (focus && ec->lock_focus_out) return;
2724 if (e_object_is_del(E_OBJECT(ec)) && focus)
2725 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2727 /* filter focus setting based on current state */
2732 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2733 evas_object_focus_set(obj, focus);
2736 if ((ec->iconic) && (!ec->deskshow))
2738 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2740 /* don't focus an iconified window. that's silly! */
2741 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2742 e_client_uniconify(ec);
2743 e_client_focus_latest_set(ec);
2757 /* not yet visible, wait till the next time... */
2758 ec->want_focus = !ec->hidden;
2763 e_client_focused_set(ec);
2767 if (e_client_focused_get() == ec)
2768 e_client_focused_set(NULL);
2772 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2774 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2776 evas_object_focus_set(obj, focus);
2780 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2782 E_Comp_Object *cw = data;
2784 if (cw->transparent.set)
2786 cw->transparent.user_r = r;
2787 cw->transparent.user_g = g;
2788 cw->transparent.user_b = b;
2789 cw->transparent.user_a = a;
2791 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2793 cw->transparent.user_r,
2794 cw->transparent.user_g,
2795 cw->transparent.user_b,
2796 cw->transparent.user_a);
2800 evas_object_color_set(obj, r, g, b, a);
2803 ////////////////////////////////////////////////////
2806 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2808 int w, h, ox, oy, ow, oh;
2810 Eina_Bool pass_event_flag = EINA_FALSE;
2811 E_Input_Rect_Data *input_rect_data;
2812 E_Input_Rect_Smart_Data *input_rect_sd;
2814 if (cw->frame_object)
2816 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2817 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2818 /* set a fixed size, force edje calc, check size difference */
2819 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2820 edje_object_message_signal_process(cw->frame_object);
2821 edje_object_calc_force(cw->frame_object);
2822 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2823 cw->client_inset.l = ox;
2824 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2825 cw->client_inset.t = oy;
2826 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2827 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2828 evas_object_resize(cw->frame_object, w, h);
2832 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2835 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2837 if (input_rect_data->obj)
2839 pass_event_flag = EINA_TRUE;
2845 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2846 evas_object_pass_events_set(cw->obj, pass_event_flag);
2850 cw->client_inset.l = 0;
2851 cw->client_inset.r = 0;
2852 cw->client_inset.t = 0;
2853 cw->client_inset.b = 0;
2855 cw->client_inset.calc = !!cw->frame_object;
2859 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2861 E_Comp_Object *cw = data;
2865 /* - get current size
2867 * - readjust for new frame size
2870 w = cw->ec->w, h = cw->ec->h;
2871 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2873 _e_comp_object_frame_recalc(cw);
2875 if (!cw->ec->fullscreen)
2876 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2878 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2879 if (cw->ec->fullscreen)
2881 zone = e_comp_zone_find_by_ec(cw->ec);
2883 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2885 else if (cw->ec->new_client)
2887 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2888 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2889 evas_object_resize(cw->ec->frame, w, h);
2891 else if ((w != cw->ec->w) || (h != cw->ec->h))
2892 evas_object_resize(cw->ec->frame, w, h);
2896 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2898 E_Comp_Object *cw = data;
2900 _e_comp_object_shadow_setup(cw);
2901 if (cw->frame_object)
2903 _e_comp_object_shadow(cw);
2904 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2905 _e_comp_object_frame_recalc(cw);
2906 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2911 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2913 E_Comp_Object *cw = data;
2915 if (_e_comp_object_shadow_setup(cw))
2916 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2917 if (cw->frame_object)
2919 _e_comp_object_shadow(cw);
2920 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2921 _e_comp_object_frame_recalc(cw);
2922 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2927 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2929 E_Comp_Object *cw = data;
2931 if (cw->frame_object)
2933 _e_comp_object_shadow(cw);
2934 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2935 _e_comp_object_frame_recalc(cw);
2936 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2941 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2943 E_Comp_Object *cw = data;
2945 if (_e_comp_object_shadow_setup(cw))
2948 cw->ec->changes.size = 1;
2950 if (cw->frame_object)
2952 _e_comp_object_shadow(cw);
2953 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2954 _e_comp_object_frame_recalc(cw);
2955 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2960 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2962 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2966 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2968 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2972 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2974 E_Comp_Object *cw = data;
2976 if (!cw->ec) return; //NYI
2977 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2981 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2983 E_Comp_Object *cw = data;
2985 if (!cw->ec) return; //NYI
2986 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2990 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2992 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2996 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2998 E_Comp_Object *cw = data;
3000 if (!e_object_is_del(E_OBJECT(cw->ec)))
3001 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3005 _e_comp_input_obj_smart_add(Evas_Object *obj)
3007 E_Input_Rect_Smart_Data *input_rect_sd;
3008 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3010 if (!input_rect_sd) return;
3011 evas_object_smart_data_set(obj, input_rect_sd);
3015 _e_comp_input_obj_smart_del(Evas_Object *obj)
3017 E_Input_Rect_Smart_Data *input_rect_sd;
3018 E_Input_Rect_Data *input_rect_data;
3020 input_rect_sd = evas_object_smart_data_get(obj);
3021 if (!input_rect_sd) return;
3023 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3025 if (input_rect_data->obj)
3027 evas_object_smart_member_del(input_rect_data->obj);
3028 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3030 E_FREE(input_rect_data);
3032 E_FREE(input_rect_sd);
3036 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3038 E_Input_Rect_Smart_Data *input_rect_sd;
3039 E_Input_Rect_Data *input_rect_data;
3043 input_rect_sd = evas_object_smart_data_get(obj);
3044 if (!input_rect_sd) return;
3046 cw = input_rect_sd->cw;
3047 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3049 if (input_rect_data->obj)
3051 evas_object_geometry_set(input_rect_data->obj,
3052 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3053 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3054 input_rect_data->rect.w, input_rect_data->rect.h);
3060 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3062 E_Input_Rect_Smart_Data *input_rect_sd;
3063 E_Input_Rect_Data *input_rect_data;
3067 input_rect_sd = evas_object_smart_data_get(obj);
3068 if (!input_rect_sd) return;
3070 cw = input_rect_sd->cw;
3071 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3073 if (input_rect_data->obj)
3075 evas_object_geometry_set(input_rect_data->obj,
3076 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3077 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3078 input_rect_data->rect.w, input_rect_data->rect.h);
3084 _e_comp_input_obj_smart_show(Evas_Object *obj)
3086 E_Input_Rect_Smart_Data *input_rect_sd;
3087 E_Input_Rect_Data *input_rect_data;
3090 input_rect_sd = evas_object_smart_data_get(obj);
3091 if (!input_rect_sd) return;
3093 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3095 if (input_rect_data->obj)
3097 evas_object_show(input_rect_data->obj);
3103 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3105 E_Input_Rect_Smart_Data *input_rect_sd;
3106 E_Input_Rect_Data *input_rect_data;
3109 input_rect_sd = evas_object_smart_data_get(obj);
3110 if (!input_rect_sd) return;
3112 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3114 if (input_rect_data->obj)
3116 evas_object_hide(input_rect_data->obj);
3122 _e_comp_input_obj_smart_init(void)
3124 if (_e_comp_input_obj_smart) return;
3126 static const Evas_Smart_Class sc =
3128 INPUT_OBJ_SMART_NAME,
3129 EVAS_SMART_CLASS_VERSION,
3130 _e_comp_input_obj_smart_add,
3131 _e_comp_input_obj_smart_del,
3132 _e_comp_input_obj_smart_move,
3133 _e_comp_input_obj_smart_resize,
3134 _e_comp_input_obj_smart_show,
3135 _e_comp_input_obj_smart_hide,
3148 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3154 _e_comp_smart_add(Evas_Object *obj)
3158 cw = E_NEW(E_Comp_Object, 1);
3159 EINA_SAFETY_ON_NULL_RETURN(cw);
3161 wl_signal_init(&cw->events.lower);
3162 #ifdef REFACTOR_DESK_AREA
3163 wl_signal_init(&cw->events.lower_done);
3164 wl_signal_init(&cw->events.raise);
3166 wl_signal_init(&cw->events.show);
3167 wl_signal_init(&cw->events.hide);
3168 #ifdef REFACTOR_DESK_AREA
3169 wl_signal_init(&cw->events.set_layer);
3170 wl_signal_init(&cw->events.stack_above);
3171 wl_signal_init(&cw->events.stack_below);
3174 cw->smart_obj = obj;
3175 cw->x = cw->y = cw->w = cw->h = -1;
3176 evas_object_smart_data_set(obj, cw);
3177 cw->opacity = 255.0;
3178 cw->external_content = 0;
3179 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3180 cw->transform_bg_color.r = 0;
3181 cw->transform_bg_color.g = 0;
3182 cw->transform_bg_color.b = 0;
3183 cw->transform_bg_color.a = 255;
3184 evas_object_data_set(obj, "comp_obj", cw);
3185 evas_object_move(obj, -1, -1);
3186 /* intercept ALL the callbacks! */
3187 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3188 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3189 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3190 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3191 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3192 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3193 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3194 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3195 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3196 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3197 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3199 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3200 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3201 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3202 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3204 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3205 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3207 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3208 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3210 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3212 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3213 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3217 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3220 evas_object_color_set(cw->clip, r, g, b, a);
3221 evas_object_smart_callback_call(obj, "color_set", NULL);
3226 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3229 evas_object_clip_set(cw->clip, clip);
3233 _e_comp_smart_clip_unset(Evas_Object *obj)
3236 evas_object_clip_unset(cw->clip);
3240 _e_comp_smart_hide(Evas_Object *obj)
3242 TRACE_DS_BEGIN(COMP:SMART HIDE);
3247 evas_object_hide(cw->clip);
3248 if (cw->input_obj) evas_object_hide(cw->input_obj);
3249 evas_object_hide(cw->effect_obj);
3250 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3251 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3252 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3259 /* unset native surface if current displaying buffer was destroied */
3260 if (!cw->buffer_destroy_listener.notify)
3262 Evas_Native_Surface *ns;
3263 ns = evas_object_image_native_surface_get(cw->obj);
3264 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3265 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3268 if (!cw->ec->input_only)
3270 edje_object_freeze(cw->effect_obj);
3271 edje_object_freeze(cw->shobj);
3272 edje_object_play_set(cw->shobj, 0);
3273 if (cw->frame_object)
3274 edje_object_play_set(cw->frame_object, 0);
3277 e_comp_render_queue(); //force nocomp recheck
3283 _e_comp_smart_show(Evas_Object *obj)
3291 if ((cw->w < 0) || (cw->h < 0))
3292 CRI("ACK! ec:%p", cw->ec);
3294 TRACE_DS_BEGIN(COMP:SMART SHOW);
3296 e_comp_object_map_update(obj);
3298 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3299 evas_object_show(tmp->frame);
3301 evas_object_show(cw->clip);
3302 if (cw->input_obj) evas_object_show(cw->input_obj);
3303 if (!cw->ec->input_only)
3305 edje_object_thaw(cw->effect_obj);
3306 edje_object_thaw(cw->shobj);
3307 edje_object_play_set(cw->shobj, 1);
3308 if (cw->frame_object)
3309 edje_object_play_set(cw->frame_object, 1);
3311 evas_object_show(cw->effect_obj);
3312 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3313 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3314 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3315 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3316 e_comp_render_queue();
3317 if (cw->ec->input_only)
3322 if (cw->ec->iconic && (!cw->ec->new_client))
3324 if (e_client_is_iconified_by_client(cw->ec))
3326 ELOGF("COMP", "Set launching flag..", cw->ec);
3327 cw->ec->launching = EINA_TRUE;
3330 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3332 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3335 ELOGF("COMP", "Set launching flag..", cw->ec);
3336 cw->ec->launching = EINA_TRUE;
3338 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3339 _e_comp_object_animating_begin(cw);
3340 if (!_e_comp_object_effect_visibility_start(cw, 1))
3346 /* ensure some random effect doesn't lock the client offscreen */
3350 e_comp_object_effect_set(obj, NULL);
3353 _e_comp_object_dim_update(cw);
3359 _e_comp_smart_del(Evas_Object *obj)
3365 if (cw->buffer_destroy_listener.notify)
3367 wl_list_remove(&cw->buffer_destroy_listener.link);
3368 cw->buffer_destroy_listener.notify = NULL;
3371 if (cw->tbm_surface)
3373 tbm_surface_internal_unref(cw->tbm_surface);
3374 cw->tbm_surface = NULL;
3377 if (cw->render_update_lock.buffer_ref.buffer)
3379 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3380 cw->ec, cw->render_update_lock.lock);
3381 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3384 e_comp_object_render_update_del(cw->smart_obj);
3385 E_FREE_FUNC(cw->updates, eina_tiler_free);
3386 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3393 EINA_LIST_FREE(cw->obj_mirror, o)
3395 evas_object_image_data_set(o, NULL);
3396 evas_object_freeze_events_set(o, 1);
3397 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3401 _e_comp_object_layers_remove(cw);
3402 l = evas_object_data_get(obj, "comp_object-to_del");
3403 E_FREE_LIST(l, evas_object_del);
3404 _e_comp_object_mouse_event_callback_unset(cw);
3405 evas_object_del(cw->clip);
3406 evas_object_del(cw->obj);
3407 evas_object_del(cw->shobj);
3408 evas_object_del(cw->effect_obj);
3409 evas_object_del(cw->frame_object);
3410 evas_object_del(cw->input_obj);
3411 evas_object_del(cw->mask.obj);
3412 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3413 evas_object_del(cw->transform_bg_obj);
3414 evas_object_del(cw->transform_tranp_obj);
3415 evas_object_del(cw->default_input_obj);
3416 eina_stringshare_del(cw->frame_theme);
3417 eina_stringshare_del(cw->frame_name);
3421 e_comp->animating--;
3423 e_object_unref(E_OBJECT(cw->ec));
3425 cw->ec->frame = NULL;
3430 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3434 cw->x = x, cw->y = y;
3435 evas_object_move(cw->effect_obj, x, y);
3436 evas_object_move(cw->default_input_obj, x, y);
3437 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3439 e_comp_object_map_update(obj);
3443 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3445 Eina_Bool first = EINA_FALSE;
3450 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3452 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3454 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3456 if (cw->w != w || cw->h != h)
3457 e_comp_object_map_update(obj);
3459 first = ((cw->w < 1) || (cw->h < 1));
3460 cw->w = w, cw->h = h;
3464 if (cw->frame_object)
3465 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3468 /* verify pixmap:object size */
3469 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3471 if ((ww != pw) || (hh != ph))
3472 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3474 evas_object_resize(cw->effect_obj, tw, th);
3475 evas_object_resize(cw->default_input_obj, w, h);
3477 evas_object_resize(cw->input_obj, w, h);
3479 evas_object_resize(cw->mask.obj, w, h);
3480 /* resize render update tiler */
3483 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3484 cw->updates_full = 0;
3485 if (cw->updates) eina_tiler_clear(cw->updates);
3489 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3490 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3498 e_comp_render_queue();
3504 _e_comp_smart_init(void)
3506 if (_e_comp_smart) return;
3508 static const Evas_Smart_Class sc =
3511 EVAS_SMART_CLASS_VERSION,
3515 _e_comp_smart_resize,
3518 _e_comp_smart_color_set,
3519 _e_comp_smart_clip_set,
3520 _e_comp_smart_clip_unset,
3530 _e_comp_smart = evas_smart_class_new(&sc);
3535 e_comp_object_init(void)
3537 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3538 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3539 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3540 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3544 e_comp_object_shutdown(void)
3550 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3552 API_ENTRY EINA_FALSE;
3553 return !!cw->force_visible;
3555 /////////////////////////////////////////////////////////
3558 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3561 Eina_Bool comp_object;
3563 comp_object = !!evas_object_data_get(obj, "comp_object");
3568 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3570 e_comp_render_queue();
3572 l = evas_object_data_get(obj, "comp_object-to_del");
3573 E_FREE_LIST(l, evas_object_del);
3577 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3579 if (e_comp_util_object_is_above_nocomp(obj) &&
3580 (!evas_object_data_get(obj, "comp_override")))
3582 evas_object_data_set(obj, "comp_override", (void*)1);
3583 e_comp_override_add();
3588 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3590 Eina_Bool ref = EINA_TRUE;
3591 if (evas_object_visible_get(obj))
3595 d = evas_object_data_del(obj, "comp_hiding");
3597 /* currently trying to hide */
3600 /* already visible */
3604 evas_object_show(obj);
3607 evas_object_ref(obj);
3608 evas_object_data_set(obj, "comp_ref", (void*)1);
3610 edje_object_signal_emit(obj, "e,state,visible", "e");
3611 evas_object_data_set(obj, "comp_showing", (void*)1);
3612 if (e_comp_util_object_is_above_nocomp(obj))
3614 evas_object_data_set(obj, "comp_override", (void*)1);
3615 e_comp_override_add();
3620 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3622 if (!evas_object_visible_get(obj)) return;
3623 /* already hiding */
3624 if (evas_object_data_get(obj, "comp_hiding")) return;
3625 if (!evas_object_data_del(obj, "comp_showing"))
3627 evas_object_ref(obj);
3628 evas_object_data_set(obj, "comp_ref", (void*)1);
3630 edje_object_signal_emit(obj, "e,state,hidden", "e");
3631 evas_object_data_set(obj, "comp_hiding", (void*)1);
3633 if (evas_object_data_del(obj, "comp_override"))
3634 e_comp_override_timed_pop();
3638 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3640 if (!e_util_strcmp(emission, "e,action,hide,done"))
3642 if (!evas_object_data_del(obj, "comp_hiding")) return;
3643 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3644 evas_object_hide(obj);
3645 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3648 evas_object_data_del(obj, "comp_showing");
3649 if (evas_object_data_del(obj, "comp_ref"))
3650 evas_object_unref(obj);
3654 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3660 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3664 E_API E_Comp_Object_Hook *
3665 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3667 E_Comp_Object_Hook *ch;
3669 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3670 ch = E_NEW(E_Comp_Object_Hook, 1);
3671 if (!ch) return NULL;
3672 ch->hookpoint = hookpoint;
3674 ch->data = (void*)data;
3675 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3680 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3683 if (_e_comp_object_hooks_walking == 0)
3685 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3689 _e_comp_object_hooks_delete++;
3692 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3693 E_API E_Comp_Object_Intercept_Hook *
3694 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3696 E_Comp_Object_Intercept_Hook *ch;
3698 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3699 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3700 if (!ch) return NULL;
3701 ch->hookpoint = hookpoint;
3703 ch->data = (void*)data;
3704 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3709 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3712 if (_e_comp_object_intercept_hooks_walking == 0)
3714 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3718 _e_comp_object_intercept_hooks_delete++;
3723 e_comp_object_util_add(Evas_Object *obj)
3727 E_Comp_Config *conf = e_comp_config_get();
3728 Eina_Bool skip = EINA_FALSE;
3734 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3736 name = evas_object_name_get(obj);
3737 vis = evas_object_visible_get(obj);
3738 o = edje_object_add(e_comp->evas);
3739 evas_object_data_set(o, "comp_object", (void*)1);
3741 skip = (!strncmp(name, "noshadow", 8));
3743 evas_object_data_set(o, "comp_object_skip", (void*)1);
3745 if (conf->shadow_style)
3747 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3748 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3751 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3752 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3753 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3755 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3757 evas_object_geometry_get(obj, &x, &y, &w, &h);
3758 evas_object_geometry_set(o, x, y, w, h);
3759 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3761 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3763 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3764 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3765 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3766 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3767 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3768 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3770 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3772 edje_object_part_swallow(o, "e.swallow.content", obj);
3774 _e_comp_object_event_add(o);
3777 evas_object_show(o);
3782 /* utility functions for deleting objects when their "owner" is deleted */
3784 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3789 EINA_SAFETY_ON_NULL_RETURN(to_del);
3790 l = evas_object_data_get(obj, "comp_object-to_del");
3791 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3792 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3793 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3797 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3802 EINA_SAFETY_ON_NULL_RETURN(to_del);
3803 l = evas_object_data_get(obj, "comp_object-to_del");
3805 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3808 /////////////////////////////////////////////////////////
3810 EINTERN Evas_Object *
3811 e_comp_object_client_add(E_Client *ec)
3816 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3817 if (ec->frame) return NULL;
3818 _e_comp_smart_init();
3819 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3820 cw = evas_object_smart_data_get(o);
3821 if (!cw) return NULL;
3822 evas_object_data_set(o, "E_Client", ec);
3825 evas_object_data_set(o, "comp_object", (void*)1);
3827 _e_comp_object_event_add(o);
3832 /* utility functions for getting client inset */
3834 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3837 if (!cw->client_inset.calc)
3843 if (ax) *ax = x - cw->client_inset.l;
3844 if (ay) *ay = y - cw->client_inset.t;
3848 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3851 if (!cw->client_inset.calc)
3857 if (ax) *ax = x + cw->client_inset.l;
3858 if (ay) *ay = y + cw->client_inset.t;
3862 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3865 if (!cw->client_inset.calc)
3871 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3872 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3876 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3879 if (!cw->client_inset.calc)
3885 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3886 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3890 e_comp_object_client_get(Evas_Object *obj)
3895 /* FIXME: remove this when eo is used */
3896 o = evas_object_data_get(obj, "comp_smart_obj");
3898 return e_comp_object_client_get(o);
3899 return cw ? cw->ec : NULL;
3903 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3906 if (cw->frame_extends)
3907 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3912 if (w) *w = cw->ec->w;
3913 if (h) *h = cw->ec->h;
3918 e_comp_object_util_zone_get(Evas_Object *obj)
3920 E_Zone *zone = NULL;
3924 zone = e_comp_zone_find_by_ec(cw->ec);
3929 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3930 zone = e_comp_zone_xy_get(x, y);
3936 e_comp_object_util_center(Evas_Object *obj)
3938 int x, y, w, h, ow, oh;
3943 zone = e_comp_object_util_zone_get(obj);
3944 EINA_SAFETY_ON_NULL_RETURN(zone);
3945 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3946 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3947 ow = cw->ec->w, oh = cw->ec->h;
3949 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3950 x = x + (w - ow) / 2;
3951 y = y + (h - oh) / 2;
3952 evas_object_move(obj, x, y);
3956 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3958 int x, y, w, h, ow, oh;
3961 EINA_SAFETY_ON_NULL_RETURN(on);
3962 evas_object_geometry_get(on, &x, &y, &w, &h);
3963 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3964 ow = cw->ec->w, oh = cw->ec->h;
3966 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3967 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3971 e_comp_object_util_fullscreen(Evas_Object *obj)
3976 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3979 evas_object_move(obj, 0, 0);
3980 evas_object_resize(obj, e_comp->w, e_comp->h);
3985 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3993 ow = cw->w, oh = cw->h;
3995 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3996 zone = e_comp_object_util_zone_get(obj);
3997 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3998 if (x) *x = zx + (zw - ow) / 2;
3999 if (y) *y = zy + (zh - oh) / 2;
4003 e_comp_object_input_objs_del(Evas_Object *obj)
4006 E_Input_Rect_Data *input_rect_data;
4007 E_Input_Rect_Smart_Data *input_rect_sd;
4012 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4013 if (!input_rect_sd) return;
4015 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4017 if (input_rect_data->obj)
4019 evas_object_smart_member_del(input_rect_data->obj);
4020 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4022 E_FREE(input_rect_data);
4027 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4030 E_Input_Rect_Data *input_rect_data = NULL;
4031 E_Input_Rect_Smart_Data *input_rect_sd;
4032 int client_w, client_h;
4034 if (cw->ec->client.w)
4035 client_w = cw->ec->client.w;
4037 client_w = cw->ec->w;
4039 if (cw->ec->client.h)
4040 client_h = cw->ec->client.h;
4042 client_h = cw->ec->h;
4044 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4048 _e_comp_input_obj_smart_init();
4049 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4050 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4051 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4054 input_rect_sd->cw = cw;
4057 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4060 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4061 if (input_rect_data)
4063 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4064 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4068 if ((input_rect_data) &&
4069 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4071 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4072 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4073 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4074 evas_object_clip_set(input_rect_data->obj, cw->clip);
4075 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4076 evas_object_geometry_set(input_rect_data->obj,
4077 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4078 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4079 evas_object_pass_events_set(cw->default_input_obj, 1);
4080 evas_object_pass_events_set(cw->obj, 1);
4083 evas_object_show(input_rect_data->obj);
4084 evas_object_show(cw->input_obj);
4089 evas_object_smart_member_del(cw->input_obj);
4090 E_FREE_FUNC(cw->input_obj, evas_object_del);
4091 evas_object_pass_events_set(cw->default_input_obj, 0);
4092 evas_object_pass_events_set(cw->obj, 0);
4097 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4100 E_Input_Rect_Smart_Data *input_rect_sd;
4101 E_Input_Rect_Data *input_rect_data;
4104 if (!cw->input_obj) return;
4106 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4109 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4111 *list = eina_list_append(*list, &input_rect_data->rect);
4117 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4120 if (l) *l = cw->client_inset.l;
4121 if (r) *r = cw->client_inset.r;
4122 if (t) *t = cw->client_inset.t;
4123 if (b) *b = cw->client_inset.b;
4126 /* set geometry for CSD */
4128 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4134 if (cw->frame_object)
4135 CRI("ACK! ec:%p", cw->ec);
4136 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4137 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4138 calc = cw->client_inset.calc;
4139 cw->client_inset.calc = l || r || t || b;
4140 eina_stringshare_replace(&cw->frame_theme, "borderless");
4141 if (cw->client_inset.calc)
4143 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4144 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4145 e_client_size_set(cw->ec, tw, th);
4147 else if (cw->ec->maximized || cw->ec->fullscreen)
4149 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4150 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4152 if (!cw->ec->new_client)
4154 if (calc && cw->client_inset.calc)
4156 tx = cw->ec->x - (l - cw->client_inset.l);
4157 ty = cw->ec->y - (t - cw->client_inset.t);
4158 e_client_pos_set(cw->ec, tx, ty);
4160 cw->ec->changes.pos = cw->ec->changes.size = 1;
4163 cw->client_inset.l = l;
4164 cw->client_inset.r = r;
4165 cw->client_inset.t = t;
4166 cw->client_inset.b = b;
4170 e_comp_object_frame_allowed(Evas_Object *obj)
4172 API_ENTRY EINA_FALSE;
4173 return (cw->frame_object || (!cw->client_inset.calc));
4177 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4179 API_ENTRY EINA_FALSE;
4180 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4181 eina_stringshare_replace(&cw->frame_name, name);
4182 if (cw->frame_object)
4183 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4188 e_comp_object_frame_exists(Evas_Object *obj)
4190 API_ENTRY EINA_FALSE;
4191 return !!cw->frame_object;
4195 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4197 Evas_Object *o, *pbg;
4200 Eina_Stringshare *theme;
4202 API_ENTRY EINA_FALSE;
4204 if (!e_util_strcmp(cw->frame_theme, name))
4205 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4206 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4207 return _e_comp_object_shadow_setup(cw);
4208 pbg = cw->frame_object;
4209 theme = eina_stringshare_add(name);
4211 if (cw->frame_object)
4215 w = cw->ec->w, h = cw->ec->h;
4216 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4217 if ((cw->ec->w != w) || (cw->ec->h != h))
4219 cw->ec->changes.size = 1;
4222 E_FREE_FUNC(cw->frame_object, evas_object_del);
4223 if (!name) goto reshadow;
4225 o = edje_object_add(e_comp->evas);
4226 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4227 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4228 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4230 cw->frame_object = NULL;
4232 eina_stringshare_del(cw->frame_theme);
4233 cw->frame_theme = theme;
4238 if (theme != e_config->theme_default_border_style)
4240 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4241 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4245 ok = e_theme_edje_object_set(o, "base/theme/border",
4246 "e/widgets/border/default/border");
4247 if (ok && (theme == e_config->theme_default_border_style))
4249 /* Reset default border style to default */
4250 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4251 e_config_save_queue();
4258 cw->frame_object = o;
4259 eina_stringshare_del(cw->frame_theme);
4260 cw->frame_theme = theme;
4261 evas_object_name_set(o, "cw->frame_object");
4264 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4268 cw->ec->changes.icon = 1;
4274 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4279 _e_comp_object_shadow_setup(cw);
4282 int old_x, old_y, new_x = 0, new_y = 0;
4284 old_x = cw->x, old_y = cw->y;
4286 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4288 new_x = cw->ec->x, new_y = cw->ec->y;
4289 else if (cw->ec->placed || (!cw->ec->new_client))
4291 /* if no previous frame:
4292 * - reapply client_inset
4297 if (cw->ec->changes.size)
4305 zone = e_comp_zone_find_by_ec(cw->ec);
4308 x = cw->ec->client.x, y = cw->ec->client.y;
4309 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4310 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4312 new_x = x, new_y = y;
4315 if (old_x != new_x || old_y != new_y)
4317 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4318 cw->y = cw->x = -99999;
4319 evas_object_move(obj, new_x, new_y);
4323 if (cw->ec->maximized)
4325 cw->ec->changes.need_maximize = 1;
4328 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4329 if (cw->frame_object)
4331 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4334 cw->frame_extends = 0;
4335 evas_object_del(pbg);
4340 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4342 E_Comp_Object_Mover *prov;
4345 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4346 edje_object_signal_emit(cw->shobj, sig, src);
4347 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4348 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4349 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4351 /* start with highest priority callback first */
4352 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4354 if (!e_util_glob_match(sig, prov->sig)) continue;
4355 if (prov->func(prov->data, obj, sig)) break;
4360 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4362 /* FIXME: at some point I guess this should use eo to inherit
4363 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4364 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4367 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4371 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4374 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4378 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4381 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4385 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4388 Eina_Rectangle rect;
4391 if (cw->ec->input_only || (!cw->updates)) return;
4392 if (cw->nocomp) return;
4393 rect.x = x, rect.y = y;
4394 rect.w = w, rect.h = h;
4395 evas_object_smart_callback_call(obj, "damage", &rect);
4397 if (e_comp_is_on_overlay(cw->ec))
4399 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4400 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4401 * E module attempts to block screen update due to the particular policy.
4403 if (e_pixmap_resource_get(cw->ec->pixmap))
4404 cw->hwc_need_update = EINA_TRUE;
4407 /* ignore overdraw */
4408 if (cw->updates_full)
4410 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4411 e_comp_object_render_update_add(obj);
4413 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4414 evas_object_show(cw->smart_obj);
4418 /* clip rect to client surface */
4419 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4420 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4421 /* if rect is the total size of the client after clip, clear the updates
4422 * since this is guaranteed to be the whole region anyway
4424 eina_tiler_area_size_get(cw->updates, &tw, &th);
4425 if ((w > tw) || (h > th))
4427 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4428 eina_tiler_clear(cw->updates);
4429 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4431 tw = cw->ec->client.w, th = cw->ec->client.h;
4433 if ((!x) && (!y) && (w == tw) && (h == th))
4435 eina_tiler_clear(cw->updates);
4436 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4437 cw->updates_full = 1;
4438 cw->update_count = 0;
4441 if (cw->update_count > UPDATE_MAX)
4443 /* this is going to get really dumb, so just update the whole thing */
4444 eina_tiler_clear(cw->updates);
4445 cw->update_count = cw->updates_full = 1;
4446 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4447 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4451 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4452 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4454 cw->updates_exist = 1;
4455 e_comp_object_render_update_add(obj);
4457 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4458 evas_object_show(cw->smart_obj);
4462 e_comp_object_damage_exists(Evas_Object *obj)
4464 API_ENTRY EINA_FALSE;
4465 return cw->updates_exist;
4469 e_comp_object_render_update_add(Evas_Object *obj)
4473 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4474 if (cw->render_update_lock.lock) return;
4475 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4479 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4481 e_comp_render_queue();
4485 e_comp_object_render_update_del(Evas_Object *obj)
4489 if (cw->ec->input_only || (!cw->updates)) return;
4490 if (!cw->update) return;
4492 /* this gets called during comp animating to clear the update flag */
4493 if (e_comp->grabbed) return;
4494 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4495 if (!e_comp->updates)
4497 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4498 if (e_comp->render_animator)
4499 ecore_animator_freeze(e_comp->render_animator);
4504 e_comp_object_shape_apply(Evas_Object *obj)
4508 unsigned int i, *pix, *p;
4512 if (!cw->ec) return; //NYI
4513 if (cw->external_content) return;
4516 if ((cw->ec->shape_rects_num >= 1) &&
4517 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4522 ERR("BUGGER: shape with native surface? cw=%p", cw);
4525 evas_object_image_size_get(cw->obj, &w, &h);
4526 if ((w < 1) || (h < 1)) return;
4529 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4530 _e_comp_object_alpha_set(cw);
4531 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4532 evas_object_image_alpha_set(o, 1);
4534 p = pix = evas_object_image_data_get(cw->obj, 1);
4537 evas_object_image_data_set(cw->obj, pix);
4542 unsigned char *spix, *sp;
4544 spix = calloc(w * h, sizeof(unsigned char));
4546 for (i = 0; i < cw->ec->shape_rects_num; i++)
4550 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4551 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4552 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4553 sp = spix + (w * ry) + rx;
4554 for (py = 0; py < rh; py++)
4556 for (px = 0; px < rw; px++)
4564 for (py = 0; py < h; py++)
4566 for (px = 0; px < w; px++)
4568 unsigned int mask, imask;
4570 mask = ((unsigned int)(*sp)) << 24;
4572 imask |= imask >> 8;
4573 imask |= imask >> 8;
4574 *p = mask | (*p & imask);
4575 //if (*sp) *p = 0xff000000 | *p;
4576 //else *p = 0x00000000;
4585 for (py = 0; py < h; py++)
4587 for (px = 0; px < w; px++)
4591 evas_object_image_data_set(cw->obj, pix);
4592 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4593 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4595 evas_object_image_data_set(o, pix);
4596 evas_object_image_data_update_add(o, 0, 0, w, h);
4598 // don't need to fix alpha chanel as blending
4599 // should be totally off here regardless of
4600 // alpha channel content
4604 _e_comp_object_clear(E_Comp_Object *cw)
4609 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4611 if (cw->render_update_lock.lock) return;
4614 e_pixmap_clear(cw->ec->pixmap);
4616 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4617 evas_object_image_size_set(cw->obj, 1, 1);
4618 evas_object_image_data_set(cw->obj, NULL);
4619 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4621 evas_object_image_size_set(o, 1, 1);
4622 evas_object_image_data_set(o, NULL);
4625 e_comp_object_render_update_del(cw->smart_obj);
4629 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4633 API_ENTRY EINA_FALSE;
4635 if (cw->transparent.set == set)
4640 evas_object_color_get(obj, &r, &g, &b, &a);
4641 evas_object_color_set(obj, 0, 0, 0, 0);
4643 cw->transparent.user_r = r;
4644 cw->transparent.user_g = g;
4645 cw->transparent.user_b = b;
4646 cw->transparent.user_a = a;
4648 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4650 cw->transparent.user_r,
4651 cw->transparent.user_g,
4652 cw->transparent.user_b,
4653 cw->transparent.user_a);
4655 cw->transparent.set = EINA_TRUE;
4659 cw->transparent.set = EINA_FALSE;
4661 evas_object_color_set(obj,
4662 cw->transparent.user_r,
4663 cw->transparent.user_g,
4664 cw->transparent.user_b,
4665 cw->transparent.user_a);
4667 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4669 cw->transparent.user_r,
4670 cw->transparent.user_g,
4671 cw->transparent.user_b,
4672 cw->transparent.user_a);
4678 /* helper function to simplify toggling of redirection for display servers which support it */
4680 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4685 if (cw->redirected == set) return;
4686 cw->redirected = set;
4687 if (cw->external_content) return;
4689 e_comp_object_map_update(obj);
4693 if (cw->updates_exist)
4694 e_comp_object_render_update_add(obj);
4696 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4698 _e_comp_object_transparent_set(obj, EINA_FALSE);
4699 evas_object_smart_callback_call(obj, "redirected", NULL);
4703 _e_comp_object_clear(cw);
4704 _e_comp_object_transparent_set(obj, EINA_TRUE);
4705 evas_object_smart_callback_call(obj, "unredirected", NULL);
4710 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4713 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4715 if (cw->buffer_destroy_listener.notify)
4717 cw->buffer_destroy_listener.notify = NULL;
4718 wl_list_remove(&cw->buffer_destroy_listener.link);
4721 if (e_object_is_del(E_OBJECT(cw->ec)))
4723 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4728 /* if it's current displaying buffer, do not remove its content */
4729 if (!evas_object_visible_get(cw->ec->frame))
4730 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4735 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4740 if (cw->buffer_destroy_listener.notify)
4742 wl_list_remove(&cw->buffer_destroy_listener.link);
4743 cw->buffer_destroy_listener.notify = NULL;
4746 if (cw->tbm_surface)
4748 tbm_surface_internal_unref(cw->tbm_surface);
4749 cw->tbm_surface = NULL;
4754 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4756 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4757 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4759 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4761 tbm_surface_internal_ref(ns->data.tbm.buffer);
4762 cw->tbm_surface = ns->data.tbm.buffer;
4766 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4767 evas_object_image_native_surface_set(cw->obj, ns);
4771 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4773 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4774 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4775 evas_object_image_native_surface_set(o, ns);
4782 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4784 Evas_Native_Surface ns;
4787 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4788 if (cw->ec->input_only) return;
4789 if (cw->external_content) return;
4790 if (cw->render_update_lock.lock) return;
4793 memset(&ns, 0, sizeof(Evas_Native_Surface));
4797 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4798 set = (!cw->ec->shaped);
4800 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4804 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4808 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4811 if (cw->ec->input_only) return;
4814 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4815 _e_comp_object_alpha_set(cw);
4817 e_comp_object_native_surface_set(obj, cw->native);
4818 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4822 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4828 if (cw->blanked == set) return;
4830 _e_comp_object_alpha_set(cw);
4833 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4834 evas_object_image_data_set(cw->obj, NULL);
4838 e_comp_object_native_surface_set(obj, 1);
4839 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4843 _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)
4848 if (!_damage_trace) return;
4852 if (!evas_object_visible_get(cw->obj)) return;
4854 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4856 o = evas_object_rectangle_add(e_comp->evas);
4857 evas_object_layer_set(o, E_LAYER_MAX);
4858 evas_object_name_set(o, "damage_trace");
4859 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4860 evas_object_resize(o, dmg_w, dmg_h);
4861 evas_object_color_set(o, 0, 128, 0, 128);
4862 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4863 evas_object_pass_events_set(o, EINA_TRUE);
4864 evas_object_show(o);
4866 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4868 dmg_w, dmg_h, dmg_x, dmg_y,
4869 origin->w, origin->h, origin->x, origin->y);
4871 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4874 /* mark an object as dirty and setup damages */
4876 e_comp_object_dirty(Evas_Object *obj)
4879 Eina_Rectangle *rect;
4883 Eina_Bool dirty, visible;
4887 if (cw->external_content) return;
4888 if (!cw->redirected) return;
4889 if (cw->render_update_lock.lock)
4891 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4894 /* only actually dirty if pixmap is available */
4895 if (!e_pixmap_resource_get(cw->ec->pixmap))
4897 // e_pixmap_size_get returns last attached buffer size
4898 // eventhough it is destroyed
4899 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4902 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4903 visible = cw->visible;
4904 if (!dirty) w = h = 1;
4905 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4907 evas_object_image_data_set(cw->obj, NULL);
4908 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4909 evas_object_image_size_set(cw->obj, tw, th);
4910 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4911 if (cw->pending_updates)
4912 eina_tiler_area_size_set(cw->pending_updates, w, h);
4913 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4915 evas_object_image_pixels_dirty_set(o, dirty);
4917 evas_object_image_data_set(o, NULL);
4918 evas_object_image_size_set(o, tw, th);
4919 visible |= evas_object_visible_get(o);
4923 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4927 e_comp_object_native_surface_set(obj, 1);
4929 m = _e_comp_object_map_damage_transform_get(cw->ec);
4930 it = eina_tiler_iterator_new(cw->updates);
4931 EINA_ITERATOR_FOREACH(it, rect)
4933 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4934 * of evas engine and doesn't convert damage according to evas_map.
4935 * so damage of evas_object_image use surface coordinate.
4939 int damage_x, damage_y, damage_w, damage_h;
4941 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4942 &damage_x, &damage_y, &damage_w, &damage_h);
4943 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4944 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4948 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4949 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4952 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4953 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4954 if (cw->pending_updates)
4955 eina_tiler_rect_add(cw->pending_updates, rect);
4957 eina_iterator_free(it);
4958 if (m) e_map_free(m);
4959 if (cw->pending_updates)
4960 eina_tiler_clear(cw->updates);
4963 cw->pending_updates = cw->updates;
4964 cw->updates = eina_tiler_new(w, h);
4965 eina_tiler_tile_size_set(cw->updates, 1, 1);
4967 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4968 evas_object_smart_callback_call(obj, "dirty", NULL);
4969 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4970 /* force render if main object is hidden but mirrors are visible */
4971 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4972 e_comp_object_render(obj);
4976 e_comp_object_render(Evas_Object *obj)
4983 API_ENTRY EINA_FALSE;
4985 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4986 if (cw->ec->input_only) return EINA_TRUE;
4987 if (cw->external_content) return EINA_TRUE;
4988 if (cw->native) return EINA_FALSE;
4989 /* if comp object is not redirected state, comp object should not be set by newly committed data
4990 because image size of comp object is 1x1 and it should not be shown on canvas */
4991 if (!cw->redirected) return EINA_TRUE;
4992 if (cw->render_update_lock.lock)
4994 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4997 e_comp_object_render_update_del(obj);
4998 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5000 if (!cw->pending_updates)
5002 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5003 evas_object_image_data_set(cw->obj, NULL);
5004 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5005 evas_object_image_data_set(o, NULL);
5009 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5011 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5013 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5016 e_pixmap_image_refresh(cw->ec->pixmap);
5017 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5020 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5021 e_pixmap_image_data_ref(cw->ec->pixmap);
5023 /* set pixel data */
5024 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5025 _e_comp_object_alpha_set(cw);
5026 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5028 evas_object_image_data_set(o, pix);
5029 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5030 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5033 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5035 e_comp_client_post_update_add(cw->ec);
5040 /* create a duplicate of an evas object */
5042 e_comp_object_util_mirror_add(Evas_Object *obj)
5046 unsigned int *pix = NULL;
5047 Eina_Bool argb = EINA_FALSE;
5052 cw = evas_object_data_get(obj, "comp_mirror");
5055 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5056 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5057 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5058 evas_object_image_alpha_set(o, 1);
5059 evas_object_image_source_set(o, obj);
5062 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5063 if (cw->external_content)
5065 ERR("%p of client %p is external content.", obj, cw->ec);
5068 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5069 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5070 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5071 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5072 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5073 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5074 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5075 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5076 evas_object_data_set(o, "comp_mirror", cw);
5078 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5079 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5081 evas_object_image_size_set(o, tw, th);
5084 pix = evas_object_image_data_get(cw->obj, 0);
5090 evas_object_image_native_surface_set(o, cw->ns);
5093 Evas_Native_Surface ns;
5094 memset(&ns, 0, sizeof(Evas_Native_Surface));
5095 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5096 evas_object_image_native_surface_set(o, &ns);
5101 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5102 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5104 (e_pixmap_image_exists(cw->ec->pixmap)))
5105 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5107 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5114 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5115 evas_object_image_pixels_dirty_set(o, dirty);
5116 evas_object_image_data_set(o, pix);
5117 evas_object_image_data_set(cw->obj, pix);
5119 evas_object_image_data_update_add(o, 0, 0, tw, th);
5124 //////////////////////////////////////////////////////
5127 e_comp_object_effect_allowed_get(Evas_Object *obj)
5129 API_ENTRY EINA_FALSE;
5131 if (!cw->shobj) return EINA_FALSE;
5132 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5133 return !e_comp_config_get()->match.disable_borders;
5136 /* setup an api effect for a client */
5138 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5141 Eina_Stringshare *grp;
5142 E_Comp_Config *config;
5143 Eina_Bool loaded = EINA_FALSE;
5145 API_ENTRY EINA_FALSE;
5146 if (!cw->shobj) return EINA_FALSE; //input window
5148 if (!effect) effect = "none";
5149 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5151 config = e_comp_config_get();
5152 if ((config) && (config->effect_file))
5154 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5156 cw->effect_set = EINA_TRUE;
5163 edje_object_file_get(cw->effect_obj, NULL, &grp);
5164 cw->effect_set = !eina_streq(effect, "none");
5165 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5166 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5168 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5169 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5170 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5172 if (cw->effect_running)
5174 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5177 cw->effect_set = EINA_FALSE;
5178 return cw->effect_set;
5182 if (cw->effect_running)
5184 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5187 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5188 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5189 if (cw->effect_clip)
5191 evas_object_clip_unset(cw->clip);
5192 cw->effect_clip = 0;
5194 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5196 _e_comp_object_dim_update(cw);
5198 return cw->effect_set;
5201 /* set params for embryo scripts in effect */
5203 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5205 Edje_Message_Int_Set *msg;
5209 EINA_SAFETY_ON_NULL_RETURN(params);
5210 EINA_SAFETY_ON_FALSE_RETURN(count);
5211 if (!cw->effect_set) return;
5213 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5214 msg->count = (int)count;
5215 for (x = 0; x < count; x++)
5216 msg->val[x] = params[x];
5217 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5218 edje_object_message_signal_process(cw->effect_obj);
5222 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5224 Edje_Signal_Cb end_cb;
5226 E_Comp_Object *cw = data;
5228 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5229 cw->effect_running = 0;
5230 if (!_e_comp_object_animating_end(cw)) return;
5232 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5234 evas_object_data_del(cw->smart_obj, "effect_running");
5235 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5236 e_comp_visibility_calculation_set(EINA_TRUE);
5239 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5240 if (!end_cb) return;
5241 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5242 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5243 end_cb(end_data, cw->smart_obj, emission, source);
5246 /* clip effect to client's zone */
5248 e_comp_object_effect_clip(Evas_Object *obj)
5252 zone = e_comp_zone_find_by_ec(cw->ec);
5254 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5255 if (!cw->effect_clip_able) return;
5256 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5257 cw->effect_clip = 1;
5260 /* unclip effect from client's zone */
5262 e_comp_object_effect_unclip(Evas_Object *obj)
5265 if (!cw->effect_clip) return;
5266 evas_object_clip_unset(cw->smart_obj);
5267 cw->effect_clip = 0;
5270 /* start effect, running end_cb after */
5272 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5274 API_ENTRY EINA_FALSE;
5275 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5276 if (!cw->effect_set) return EINA_FALSE;
5278 if (cw->effect_running)
5280 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5283 e_comp_object_effect_clip(obj);
5284 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5286 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5287 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5288 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5289 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5291 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5292 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5294 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5295 _e_comp_object_animating_begin(cw);
5296 cw->effect_running = 1;
5300 /* stop a currently-running effect immediately */
5302 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5305 Edje_Signal_Cb end_cb_before = NULL;
5306 void *end_data_before = NULL;
5307 API_ENTRY EINA_FALSE;
5309 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5310 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5312 if (end_cb_before != end_cb) return EINA_TRUE;
5313 e_comp_object_effect_unclip(obj);
5314 if (cw->effect_clip)
5316 evas_object_clip_unset(cw->effect_obj);
5317 cw->effect_clip = 0;
5319 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5320 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5322 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5324 evas_object_data_del(cw->smart_obj, "effect_running");
5325 e_comp_visibility_calculation_set(EINA_TRUE);
5328 cw->effect_running = 0;
5329 ret = _e_comp_object_animating_end(cw);
5331 if ((ret) && (end_cb_before))
5333 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5334 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5341 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5343 return a->pri - b->pri;
5346 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5347 E_API E_Comp_Object_Mover *
5348 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5350 E_Comp_Object_Mover *prov;
5352 prov = E_NEW(E_Comp_Object_Mover, 1);
5353 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5354 prov->func = provider;
5355 prov->data = (void*)data;
5358 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5359 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5364 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5366 EINA_SAFETY_ON_NULL_RETURN(prov);
5367 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5372 e_comp_object_effect_object_get(Evas_Object *obj)
5376 return cw->effect_obj;
5380 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5382 API_ENTRY EINA_FALSE;
5383 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5384 if (!cw->effect_set) return EINA_FALSE;
5391 ////////////////////////////////////
5394 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5396 if (e_comp->autoclose.obj)
5398 e_comp_ungrab_input(0, 1);
5399 if (e_comp->autoclose.del_cb)
5400 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5401 else if (!already_del)
5403 evas_object_hide(e_comp->autoclose.obj);
5404 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5406 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5408 e_comp->autoclose.obj = NULL;
5409 e_comp->autoclose.data = NULL;
5410 e_comp->autoclose.del_cb = NULL;
5411 e_comp->autoclose.key_cb = NULL;
5412 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5416 _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)
5418 _e_comp_object_autoclose_cleanup(0);
5422 _e_comp_object_autoclose_setup(Evas_Object *obj)
5424 if (!e_comp->autoclose.rect)
5426 /* create rect just below autoclose object to catch mouse events */
5427 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5428 evas_object_move(e_comp->autoclose.rect, 0, 0);
5429 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5430 evas_object_show(e_comp->autoclose.rect);
5431 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5432 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5433 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5434 e_comp_grab_input(0, 1);
5436 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5437 evas_object_focus_set(obj, 1);
5441 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5443 _e_comp_object_autoclose_setup(obj);
5444 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5448 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5450 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5451 _e_comp_object_autoclose_cleanup(1);
5452 if (e_client_focused_get()) return;
5454 E_Zone *zone = e_zone_current_get();
5457 e_zone_focus_reset(zone);
5461 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5465 if (e_comp->autoclose.obj)
5467 if (e_comp->autoclose.obj == obj) return;
5468 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5469 e_comp->autoclose.obj = obj;
5470 e_comp->autoclose.del_cb = del_cb;
5471 e_comp->autoclose.key_cb = cb;
5472 e_comp->autoclose.data = (void*)data;
5473 if (evas_object_visible_get(obj))
5474 _e_comp_object_autoclose_setup(obj);
5476 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5477 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5480 e_comp->autoclose.obj = obj;
5481 e_comp->autoclose.del_cb = del_cb;
5482 e_comp->autoclose.key_cb = cb;
5483 e_comp->autoclose.data = (void*)data;
5484 if (evas_object_visible_get(obj))
5485 _e_comp_object_autoclose_setup(obj);
5487 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5488 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5492 e_comp_object_is_animating(Evas_Object *obj)
5496 return cw->animating;
5500 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5504 if ((cw->external_content) &&
5505 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5507 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5508 "But current external content is %d object for %p.",
5509 cw->content_type, cw->ec);
5513 cw->user_alpha_set = EINA_TRUE;
5514 cw->user_alpha = alpha;
5516 if (!cw->obj) return;
5518 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5520 evas_object_image_alpha_set(cw->obj, alpha);
5522 if ((!cw->native) && (!cw->external_content))
5523 evas_object_image_data_set(cw->obj, NULL);
5527 e_comp_object_alpha_get(Evas_Object *obj)
5529 API_ENTRY EINA_FALSE;
5531 return evas_object_image_alpha_get(cw->obj);
5535 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5537 Eina_Bool mask_set = EINA_FALSE;
5541 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5542 if (cw->ec->input_only) return;
5549 o = evas_object_rectangle_add(e_comp->evas);
5550 evas_object_color_set(o, 0, 0, 0, 0);
5551 evas_object_clip_set(o, cw->clip);
5552 evas_object_smart_member_add(o, obj);
5553 evas_object_move(o, 0, 0);
5554 evas_object_resize(o, cw->w, cw->h);
5555 /* save render op value to restore when clear a mask.
5557 * NOTE: DO NOT change the render op on ec->frame while mask object
5558 * is set. it will overwrite the changed op value. */
5559 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5560 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5561 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5562 if (cw->visible) evas_object_show(o);
5565 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5566 ELOGF("COMP", " |mask_obj", cw->ec);
5567 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5574 evas_object_smart_member_del(cw->mask.obj);
5575 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5577 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5578 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5584 e_comp_object_mask_has(Evas_Object *obj)
5586 API_ENTRY EINA_FALSE;
5588 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5592 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5597 if ((cw->external_content) &&
5598 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5600 WRN("Can set up size to ONLY evas \"image\" object. "
5601 "But current external content is %d object for %p.",
5602 cw->content_type, cw->ec);
5606 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5608 evas_object_image_size_set(cw->obj, tw, th);
5612 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5614 Eina_Bool transform_set = EINA_FALSE;
5616 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5617 if (cw->ec->input_only) return;
5619 transform_set = !!set;
5623 if (!cw->transform_bg_obj)
5625 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5626 evas_object_move(o, 0, 0);
5627 evas_object_resize(o, 1, 1);
5628 if (cw->transform_bg_color.a >= 255)
5629 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5631 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5632 evas_object_color_set(o,
5633 cw->transform_bg_color.r,
5634 cw->transform_bg_color.g,
5635 cw->transform_bg_color.b,
5636 cw->transform_bg_color.a);
5637 if (cw->visible) evas_object_show(o);
5639 cw->transform_bg_obj = o;
5640 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5642 _e_comp_object_transform_obj_stack_update(obj);
5646 if (cw->transform_bg_obj)
5648 evas_object_smart_member_del(cw->transform_bg_obj);
5649 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5655 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5659 cw->transform_bg_color.r = r;
5660 cw->transform_bg_color.g = g;
5661 cw->transform_bg_color.b = b;
5662 cw->transform_bg_color.a = a;
5664 if (cw->transform_bg_obj)
5666 evas_object_color_set(cw->transform_bg_obj,
5667 cw->transform_bg_color.r,
5668 cw->transform_bg_color.g,
5669 cw->transform_bg_color.b,
5670 cw->transform_bg_color.a);
5675 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5678 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5679 if (cw->ec->input_only) return;
5680 if (!cw->transform_bg_obj) return;
5682 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5686 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5689 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5690 if (cw->ec->input_only) return;
5691 if (!cw->transform_bg_obj) return;
5693 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5697 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5699 Eina_Bool transform_set = EINA_FALSE;
5701 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5702 if (cw->ec->input_only) return;
5704 transform_set = !!set;
5708 if (!cw->transform_tranp_obj)
5710 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5711 evas_object_move(o, 0, 0);
5712 evas_object_resize(o, 1, 1);
5713 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5714 evas_object_color_set(o, 0, 0, 0, 0);
5715 if (cw->visible) evas_object_show(o);
5717 cw->transform_tranp_obj = o;
5718 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5719 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5720 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5722 _e_comp_object_transform_obj_stack_update(obj);
5726 if (cw->transform_tranp_obj)
5728 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5729 evas_object_smart_member_del(cw->transform_tranp_obj);
5730 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5736 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5739 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5740 if (cw->ec->input_only) return;
5741 if (!cw->transform_tranp_obj) return;
5743 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5747 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5750 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5751 if (cw->ec->input_only) return;
5752 if (!cw->transform_tranp_obj) return;
5754 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5758 e_comp_object_layer_update(Evas_Object *obj,
5759 Evas_Object *above, Evas_Object *below)
5761 E_Comp_Object *cw2 = NULL;
5762 Evas_Object *o = NULL;
5767 if (cw->ec->layer_block) return;
5768 if ((above) && (below))
5770 ERR("Invalid layer update request! cw=%p", cw);
5778 layer = evas_object_layer_get(o);
5779 cw2 = evas_object_data_get(o, "comp_obj");
5782 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5784 o = evas_object_above_get(o);
5785 if ((!o) || (o == cw->smart_obj)) break;
5786 if (evas_object_layer_get(o) != layer)
5788 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5793 ec = e_client_top_get();
5794 if (ec) o = ec->frame;
5797 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5801 _e_comp_object_layers_remove(cw);
5804 if (cw2->layer > cw->layer)
5805 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5806 else if (cw2->layer == cw->layer)
5809 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5811 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5813 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5816 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5819 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5823 e_comp_object_layer_get(Evas_Object *obj)
5830 e_comp_object_content_set(Evas_Object *obj,
5831 Evas_Object *content,
5832 E_Comp_Object_Content_Type type)
5834 API_ENTRY EINA_FALSE;
5836 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5837 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5838 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5842 ERR("Can't set e.swallow.content to requested content. "
5843 "Previous comp object should not be changed at all.");
5847 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5849 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5850 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5852 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5853 type, content, cw->ec, cw->ec->pixmap);
5857 cw->external_content = EINA_TRUE;
5860 cw->content_type = type;
5861 e_util_size_debug_set(cw->obj, 1);
5862 evas_object_name_set(cw->obj, "cw->obj");
5863 _e_comp_object_alpha_set(cw);
5866 _e_comp_object_shadow_setup(cw);
5872 e_comp_object_content_unset(Evas_Object *obj)
5874 API_ENTRY EINA_FALSE;
5876 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5877 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5879 if (!cw->obj && !cw->ec->visible)
5881 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5885 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5887 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5893 if (cw->frame_object)
5894 edje_object_part_unswallow(cw->frame_object, cw->obj);
5896 edje_object_part_unswallow(cw->shobj, cw->obj);
5898 evas_object_del(cw->obj);
5899 evas_object_hide(cw->obj);
5903 cw->external_content = EINA_FALSE;
5904 if (cw->ec->is_cursor)
5907 DBG("%p is cursor surface..", cw->ec);
5908 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5910 evas_object_resize(cw->ec->frame, pw, ph);
5911 evas_object_hide(cw->ec->frame);
5916 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5917 cw->obj = evas_object_image_filled_add(e_comp->evas);
5918 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5919 e_util_size_debug_set(cw->obj, 1);
5920 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5921 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5922 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5923 evas_object_name_set(cw->obj, "cw->obj");
5924 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5925 _e_comp_object_alpha_set(cw);
5928 _e_comp_object_shadow_setup(cw);
5933 _e_comp_intercept_show_helper(cw);
5937 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5938 e_comp_object_dirty(cw->smart_obj);
5939 e_comp_object_render(cw->smart_obj);
5940 e_comp_object_render_update_add(obj);
5945 EINTERN Evas_Object *
5946 e_comp_object_content_get(Evas_Object *obj)
5950 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5952 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5954 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5961 E_API E_Comp_Object_Content_Type
5962 e_comp_object_content_type_get(Evas_Object *obj)
5964 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5966 return cw->content_type;
5970 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5973 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5974 E_Comp_Config *conf = e_comp_config_get();
5975 if (cw->ec->input_only) return;
5976 if (!conf->dim_rect_enable) return;
5978 cw->dim.mask_set = mask_set;
5984 if (!cw->dim.enable) return;
5985 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5989 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5991 Eina_Bool mask_set = EINA_FALSE;
5995 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5996 E_Comp_Config *conf = e_comp_config_get();
5997 if (cw->ec->input_only) return;
5998 if (!conf->dim_rect_enable) return;
6004 if (cw->dim.mask_obj)
6006 evas_object_smart_member_del(cw->dim.mask_obj);
6007 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6010 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);
6011 o = evas_object_rectangle_add(e_comp->evas);
6012 evas_object_color_set(o, 0, 0, 0, 0);
6013 evas_object_smart_member_add(o, obj);
6014 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6015 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6017 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6018 if (cw->visible) evas_object_show(o);
6020 cw->dim.mask_obj = o;
6021 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6023 evas_object_layer_set(cw->dim.mask_obj, 9998);
6027 if (cw->dim.mask_obj)
6029 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6030 evas_object_smart_member_del(cw->dim.mask_obj);
6031 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6037 e_comp_object_dim_client_set(E_Client *ec)
6039 E_Comp_Config *conf = e_comp_config_get();
6041 if (!conf->dim_rect_enable) return ;
6042 if (dim_client == ec) return;
6044 Eina_Bool prev_dim = EINA_FALSE;
6045 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6047 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6048 prev_dim = EINA_TRUE;
6050 if (prev_dim && dim_client->visible && ec)
6052 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6053 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6057 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6058 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6064 e_comp_object_dim_client_get(void)
6066 E_Comp_Config *conf = e_comp_config_get();
6068 if (!conf->dim_rect_enable ) return NULL;
6074 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6077 char emit[32] = "\0";
6078 E_Comp_Config *conf = e_comp_config_get();
6081 if (!conf->dim_rect_enable) return;
6082 if (!cw->effect_obj) return;
6083 if (enable == cw->dim.enable) return;
6085 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6086 if (noeffect || !conf->dim_rect_effect)
6088 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6092 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6095 cw->dim.enable = enable;
6097 if (cw->dim.mask_set && !enable)
6099 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6100 edje_object_signal_emit(cw->effect_obj, emit, "e");
6102 else if (cw->dim.mask_set && enable)
6104 edje_object_signal_emit(cw->effect_obj, emit, "e");
6105 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6109 edje_object_signal_emit(cw->effect_obj, emit, "e");
6114 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6116 API_ENTRY EINA_FALSE;
6117 E_Comp_Config *conf = e_comp_config_get();
6119 if (!ec) return EINA_FALSE;
6120 if (!conf->dim_rect_enable) return EINA_FALSE;
6122 if (cw->dim.enable) return EINA_TRUE;
6128 _e_comp_object_dim_update(E_Comp_Object *cw)
6130 E_Comp_Config *conf = e_comp_config_get();
6133 if (!conf->dim_rect_enable) return;
6134 if (!cw->effect_obj) return;
6137 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6138 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6140 if (cw->dim.mask_set)
6142 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6148 e_comp_object_clear(Evas_Object *obj)
6152 _e_comp_object_clear(cw);
6156 e_comp_object_hwc_update_exists(Evas_Object *obj)
6158 API_ENTRY EINA_FALSE;
6159 return cw->hwc_need_update;
6164 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6167 cw->hwc_need_update = set;
6171 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6173 API_ENTRY EINA_FALSE;
6174 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6178 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6181 if (cw->indicator.obj != indicator)
6182 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6183 cw->indicator.obj = indicator;
6184 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6188 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6191 if (cw->indicator.obj != indicator) return;
6192 cw->indicator.obj = NULL;
6193 edje_object_part_unswallow(cw->shobj, indicator);
6197 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6200 Edje_Message_Int_Set *msg;
6202 if (!cw->indicator.obj) return;
6204 cw->indicator.w = w;
6205 cw->indicator.h = h;
6207 if (!cw->shobj) return;
6209 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6213 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6214 edje_object_message_signal_process(cw->shobj);
6217 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6219 e_comp_object_map_update(Evas_Object *obj)
6222 E_Client *ec = cw->ec;
6223 E_Comp_Wl_Client_Data *cdata;
6225 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6228 int l, remain = sizeof buffer;
6231 if (e_object_is_del(E_OBJECT(ec))) return;
6232 cdata = e_client_cdata_get(ec);
6235 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6236 * when new buffer is attached.
6238 if (!cdata->buffer_ref.buffer) return;
6240 if ((!cw->redirected) ||
6241 (e_client_video_hw_composition_check(ec)) ||
6242 (!e_comp_wl_output_buffer_transform_get(ec) &&
6243 cdata->scaler.buffer_viewport.buffer.scale == 1))
6245 if (evas_object_map_enable_get(cw->effect_obj))
6247 ELOGF("TRANSFORM", "map: disable", cw->ec);
6248 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6249 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6250 evas_object_resize(cw->effect_obj, tw, th);
6257 EINA_SAFETY_ON_NULL_RETURN(map);
6259 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6265 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6267 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6268 e_map_point_image_uv_set(map, 0, x, y);
6269 l = snprintf(p, remain, "%d,%d", x, y);
6270 p += l, remain -= l;
6272 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6273 e_map_point_image_uv_set(map, 1, x, y);
6274 l = snprintf(p, remain, " %d,%d", x, y);
6275 p += l, remain -= l;
6277 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6278 e_map_point_image_uv_set(map, 2, x, y);
6279 l = snprintf(p, remain, " %d,%d", x, y);
6280 p += l, remain -= l;
6282 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6283 e_map_point_image_uv_set(map, 3, x, y);
6284 l = snprintf(p, remain, " %d,%d", x, y);
6285 p += l, remain -= l;
6287 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6289 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6291 e_comp_object_map_set(cw->effect_obj, map);
6292 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6296 /* if there's screen rotation with comp mode, then ec->effect_obj and
6297 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6299 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6300 evas_object_resize(cw->effect_obj, tw, th);
6304 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6306 API_ENTRY EINA_FALSE;
6308 cw->render_trace = set;
6314 e_comp_object_native_usable_get(Evas_Object *obj)
6316 API_ENTRY EINA_FALSE;
6317 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6319 if (cw->ec->input_only) return EINA_FALSE;
6320 if (cw->external_content) return EINA_FALSE;
6321 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6323 /* just return true value, if it is normal case */
6324 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6327 Evas_Native_Surface *ns;
6328 ns = evas_object_image_native_surface_get(cw->obj);
6330 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6333 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6341 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6343 API_ENTRY EINA_FALSE;
6344 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6345 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6346 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6350 case E_COMP_IMAGE_FILTER_BLUR:
6351 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6353 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6354 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6356 case E_COMP_IMAGE_FILTER_INVERSE:
6357 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6359 case E_COMP_IMAGE_FILTER_NONE:
6361 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6365 cw->image_filter = filter;
6370 EINTERN E_Comp_Image_Filter
6371 e_comp_object_image_filter_get(Evas_Object *obj)
6373 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6374 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6375 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6376 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6378 return cw->image_filter;
6382 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6386 if (!_damage_trace) return;
6388 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6389 evas_object_del(obj);
6391 _damage_trace_post_objs = NULL;
6395 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6397 if (!_damage_trace) return;
6399 _damage_trace_post_objs = _damage_trace_objs;
6400 _damage_trace_objs = NULL;
6404 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6406 if (_damage_trace == onoff) return;
6410 evas_event_callback_add(e_comp->evas,
6411 EVAS_CALLBACK_RENDER_PRE,
6412 _e_comp_object_damage_trace_render_pre_cb,
6415 evas_event_callback_add(e_comp->evas,
6416 EVAS_CALLBACK_RENDER_POST,
6417 _e_comp_object_damage_trace_render_post_cb,
6424 EINA_LIST_FREE(_damage_trace_objs, obj)
6425 evas_object_del(obj);
6427 _damage_trace_objs = NULL;
6429 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6430 evas_object_del(obj);
6432 _damage_trace_post_objs = NULL;
6434 evas_event_callback_del(e_comp->evas,
6435 EVAS_CALLBACK_RENDER_PRE,
6436 _e_comp_object_damage_trace_render_pre_cb);
6438 evas_event_callback_del(e_comp->evas,
6439 EVAS_CALLBACK_RENDER_POST,
6440 _e_comp_object_damage_trace_render_post_cb);
6443 _damage_trace = onoff;
6447 e_comp_object_redirected_get(Evas_Object *obj)
6449 API_ENTRY EINA_FALSE;
6450 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6452 return cw->redirected;
6456 e_comp_object_color_visible_get(Evas_Object *obj)
6458 API_ENTRY EINA_FALSE;
6461 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6463 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6467 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6471 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6475 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6483 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6485 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6487 return e_map_set_to_comp_object(em, obj);
6491 e_comp_object_map_get(const Evas_Object *obj)
6493 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6495 return e_map_get_from_comp_object(obj);
6499 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6501 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6503 evas_object_map_enable_set(obj, enable);
6509 e_comp_object_render_update_lock(Evas_Object *obj)
6511 E_Comp_Wl_Buffer *buffer;
6512 struct wayland_tbm_client_queue *cqueue;
6514 API_ENTRY EINA_FALSE;
6516 if (cw->render_update_lock.lock == 0)
6518 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6520 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6521 if ((buffer) && (buffer->resource))
6523 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6525 wayland_tbm_server_client_queue_flush(cqueue);
6528 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6529 e_comp_object_render_update_del(obj);
6531 ELOGF("COMP", "Render update lock enabled", cw->ec);
6534 cw->render_update_lock.lock++;
6540 e_comp_object_render_update_unlock(Evas_Object *obj)
6544 if (cw->render_update_lock.lock == 0)
6547 cw->render_update_lock.lock--;
6549 if (cw->render_update_lock.lock == 0)
6552 if (cw->render_update_lock.pending_move_set)
6554 evas_object_move(obj,
6555 cw->render_update_lock.pending_move_x,
6556 cw->render_update_lock.pending_move_y);
6557 cw->render_update_lock.pending_move_x = 0;
6558 cw->render_update_lock.pending_move_y = 0;
6559 cw->render_update_lock.pending_move_set = EINA_FALSE;
6562 if (cw->render_update_lock.pending_resize_set)
6564 evas_object_resize(obj,
6565 cw->render_update_lock.pending_resize_w,
6566 cw->render_update_lock.pending_resize_h);
6567 cw->render_update_lock.pending_resize_w = 0;
6568 cw->render_update_lock.pending_resize_h = 0;
6569 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6572 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6574 if ((cw->ec->exp_iconify.buffer_flush) &&
6575 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6576 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6577 e_comp_object_clear(obj);
6579 e_comp_object_render_update_add(obj);
6581 ELOGF("COMP", "Render update lock disabled", cw->ec);
6586 e_comp_object_render_update_lock_get(Evas_Object *obj)
6588 API_ENTRY EINA_FALSE;
6590 if (cw->render_update_lock.lock > 0)
6597 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6601 if (cw->transparent.set)
6603 if (r) *r = cw->transparent.user_r;
6604 if (g) *g = cw->transparent.user_g;
6605 if (b) *b = cw->transparent.user_b;
6606 if (a) *a = cw->transparent.user_a;
6610 evas_object_color_get(obj, r, g, b, a);
6615 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6619 evas_object_render_op_set(cw->obj, op);
6622 EINTERN Evas_Render_Op
6623 e_comp_object_render_op_get(Evas_Object *obj)
6625 API_ENTRY EVAS_RENDER_BLEND;
6627 return evas_object_render_op_get(cw->obj);
6631 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6634 wl_signal_add(&cw->events.lower, listener);
6637 #ifdef REFACTOR_DESK_AREA
6639 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6642 wl_signal_add(&cw->events.lower_done, listener);
6646 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6649 wl_signal_add(&cw->events.raise, listener);
6654 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6657 wl_signal_add(&cw->events.show, listener);
6661 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6664 wl_signal_add(&cw->events.hide, listener);
6667 #ifdef REFACTOR_DESK_AREA
6669 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6672 wl_signal_add(&cw->events.set_layer, listener);
6676 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6679 wl_signal_add(&cw->events.stack_above, listener);
6683 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6686 wl_signal_add(&cw->events.stack_below, listener);