5 = keys that return objects =
6 - E_Client: the client associated with the object (E_Client*)
7 - comp_smart_obj: cw->smart_obj (Evas_Object*)
8 - comp_obj: cw (E_Comp_Object*)
10 = keys that are bool flags =
11 - client_restack: client needs a protocol-level restack
12 - comp_override: object is triggering a nocomp override to force compositing
13 - comp_ref: object has a ref from visibility animations
14 - comp_showing: object is currently running its show animation
15 - comp_hiding: object is currently running its hiding animation
16 - comp_object: object is a compositor-created object
17 - comp_object_skip: object has a name which prohibits theme shadows
18 - comp_object-to_del: list of objects which will be deleted when this object is deleted
19 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
20 - effect_running: object is animating by external module
23 #define UPDATE_MAX 512 // same as evas
24 #define FAILURE_MAX 2 // seems reasonable
25 #define SMART_NAME "e_comp_object"
26 #define INPUT_OBJ_SMART_NAME "input_object"
28 /* for non-util functions */
29 #define API_ENTRY E_Comp_Object *cw; \
30 cw = evas_object_smart_data_get(obj); \
31 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
33 /* for util functions (obj may or may not be E_Comp_Object */
34 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
37 CRI("YOU PASSED NULL! ARGH!"); \
40 cw = evas_object_smart_data_get(obj); \
41 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
43 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
45 /* enable for lots of client size info in console output */
47 # define e_util_size_debug_set(x, y)
50 /* enable along with display-specific damage INF calls to enable render tracing
54 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
56 #define RENDER_DEBUG(...)
59 typedef struct _E_Comp_Object
63 int x, y, w, h; // geometry
67 E_Comp_Object_Frame client_inset;
69 Eina_Stringshare *frame_theme;
70 Eina_Stringshare *frame_name;
71 Eina_Stringshare *visibility_effect; //effect when toggling visibility
73 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
75 Evas_Object *smart_obj; // smart object
76 Evas_Object *clip; // clipper over effect object
77 Evas_Object *input_obj; // input smart object
78 Evas_Object *obj; // composite object
79 Evas_Object *frame_object; // for client frames
80 Evas_Object *shobj; // shadow object
81 Evas_Object *effect_obj; // effects object
82 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
87 Evas_Object *transform_tranp_obj;// transform transp rect obj
88 Evas_Object *default_input_obj; // default input object
89 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
90 Eina_List *obj_mirror; // extra mirror objects
91 Eina_Tiler *updates; //render update regions
92 Eina_Tiler *pending_updates; //render update regions which are about to render
94 Evas_Native_Surface *ns; //for custom gl rendering
96 struct wl_listener buffer_destroy_listener;
98 unsigned int update_count; // how many updates have happened to this obj
100 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
102 unsigned int animating; // it's busy animating
103 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
104 unsigned int force_visible; //number of visible obj_mirror objects
105 Eina_Bool delete_pending : 1; // delete pending
106 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
107 Eina_Bool showing : 1; // object is currently in "show" animation
108 Eina_Bool hiding : 1; // object is currently in "hide" animation
109 Eina_Bool visible : 1; // is visible
111 Eina_Bool shaped : 1; // is shaped
112 Eina_Bool update : 1; // has updates to fetch
113 Eina_Bool redirected : 1; // has updates to fetch
114 Eina_Bool native : 1; // native
116 Eina_Bool nocomp : 1; // nocomp applied
117 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
118 Eina_Bool real_hid : 1; // last hide was a real window unmap
120 Eina_Bool effect_set : 1; //effect_obj has a valid group
121 Eina_Bool effect_running : 1; //effect_obj is playing an animation
122 Eina_Bool effect_clip : 1; //effect_obj is clipped
123 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
125 Eina_Bool updates_exist : 1;
126 Eina_Bool updates_full : 1; // entire object will be updated
128 Eina_Bool force_move : 1;
129 Eina_Bool frame_extends : 1; //frame may extend beyond object size
130 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
131 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
132 Eina_Bool user_alpha_set : 1;
133 Eina_Bool user_alpha : 1;
137 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
138 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
145 } indicator; //indicator object for internal client
149 Evas_Object *mask_obj;
152 int mask_x, mask_y, mask_w, mask_h;
155 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
157 tbm_surface_h tbm_surface;
158 E_Comp_Image_Filter image_filter;
159 Eina_Bool set_mouse_callbacks;
164 E_Comp_Wl_Buffer_Ref buffer_ref;
165 Eina_Bool pending_move_set;
166 int pending_move_x, pending_move_y;
167 Eina_Bool pending_resize_set;
168 int pending_resize_w, pending_resize_h;
169 } render_update_lock;
182 struct wl_signal lower;
183 //#ifdef REFACTOR_DESK_AREA
184 struct wl_signal raise;
186 struct wl_signal show;
187 struct wl_signal hide;
188 //#ifdef REFACTOR_DESK_AREA
189 struct wl_signal set_layer;
190 struct wl_signal stack_above;
191 struct wl_signal stack_below;
196 typedef struct _E_Input_Rect_Data
202 typedef struct _E_Input_Rect_Smart_Data
204 Eina_List *input_rect_data_list;
206 } E_Input_Rect_Smart_Data;
208 struct E_Comp_Object_Mover
211 E_Comp_Object_Mover_Cb func;
217 static Eina_Inlist *_e_comp_object_movers = NULL;
218 static Evas_Smart *_e_comp_smart = NULL;
219 static Evas_Smart *_e_comp_input_obj_smart = NULL;
221 static int _e_comp_object_hooks_delete = 0;
222 static int _e_comp_object_hooks_walking = 0;
224 static Eina_Inlist *_e_comp_object_hooks[] =
226 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
227 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
228 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
229 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
230 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
231 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
232 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
233 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
236 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
237 static int _e_comp_object_intercept_hooks_delete = 0;
238 static int _e_comp_object_intercept_hooks_walking = 0;
240 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
242 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
243 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
247 static Eina_Bool _damage_trace = EINA_FALSE;
248 static Eina_List *_damage_trace_objs = NULL;
249 static Eina_List *_damage_trace_post_objs = NULL;
251 /* sekrit functionzzz */
252 EINTERN void e_client_focused_set(E_Client *ec);
254 /* emitted every time a new noteworthy comp object is added */
255 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
257 /* ecore event define */
258 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
259 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
260 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
262 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
263 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
264 static void _e_comp_object_dim_update(E_Comp_Object *cw);
265 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
266 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
268 static E_Client *dim_client = NULL;
271 _e_comp_object_hooks_clean(void)
274 E_Comp_Object_Hook *ch;
277 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
278 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
280 if (!ch->delete_me) continue;
281 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
287 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
289 E_Comp_Object_Hook *ch;
290 Eina_Bool ret = EINA_TRUE;
292 if (e_object_is_del(E_OBJECT(ec)))
294 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
295 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
296 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
297 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
298 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
299 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
300 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
301 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
307 e_object_ref(E_OBJECT(ec));
308 _e_comp_object_hooks_walking++;
309 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
311 if (ch->delete_me) continue;
312 if (!(ch->func(ch->data, ec)))
318 _e_comp_object_hooks_walking--;
319 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
320 _e_comp_object_hooks_clean();
322 e_object_unref(E_OBJECT(ec));
327 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
329 _e_comp_object_intercept_hooks_clean(void)
332 E_Comp_Object_Intercept_Hook *ch;
335 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
336 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
338 if (!ch->delete_me) continue;
339 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
345 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
347 E_Comp_Object_Intercept_Hook *ch;
348 Eina_Bool ret = EINA_TRUE;
350 if (e_object_is_del(E_OBJECT(ec))) return ret;
351 e_object_ref(E_OBJECT(ec));
352 _e_comp_object_intercept_hooks_walking++;
353 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
355 if (ch->delete_me) continue;
356 if (!(ch->func(ch->data, ec)))
362 _e_comp_object_intercept_hooks_walking--;
363 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
364 _e_comp_object_intercept_hooks_clean();
366 e_object_unref(E_OBJECT(ec));
373 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
375 E_Event_Comp_Object *ev = event;
378 ec = evas_object_data_get(ev->comp_object, "E_Client");
382 e_object_unref(E_OBJECT(ec));
384 evas_object_unref(ev->comp_object);
389 _e_comp_object_event_add(Evas_Object *obj)
391 E_Event_Comp_Object *ev;
394 if (stopping) return;
395 ev = E_NEW(E_Event_Comp_Object, 1);
396 EINA_SAFETY_ON_NULL_RETURN(ev);
398 evas_object_ref(obj);
399 ev->comp_object = obj;
400 ec = evas_object_data_get(ev->comp_object, "E_Client");
404 e_object_ref(E_OBJECT(ec));
406 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
410 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
412 E_Event_Comp_Object *ev = event;
415 ec = evas_object_data_get(ev->comp_object, "E_Client");
419 e_object_unref(E_OBJECT(ec));
421 evas_object_unref(ev->comp_object);
426 _e_comp_object_event_simple(Evas_Object *obj, int type)
428 E_Event_Comp_Object *ev;
431 ev = E_NEW(E_Event_Comp_Object, 1);
434 evas_object_ref(obj);
435 ev->comp_object = obj;
436 ec = evas_object_data_get(ev->comp_object, "E_Client");
440 e_object_ref(E_OBJECT(ec));
442 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
444 /////////////////////////////////////
447 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
455 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
457 E_Comp_Object *cw = data;
459 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
460 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
463 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
464 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
468 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
470 E_Comp_Object *cw = data;
473 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
474 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
477 /////////////////////////////////////
480 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
484 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
485 if (cw->ec->input_only) return;
487 layer = evas_object_layer_get(obj);
489 if (cw->transform_bg_obj)
491 if (layer != evas_object_layer_get(cw->transform_bg_obj))
493 evas_object_layer_set(cw->transform_bg_obj, layer);
496 evas_object_stack_below(cw->transform_bg_obj, obj);
499 if (cw->transform_tranp_obj)
501 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
503 evas_object_layer_set(cw->transform_tranp_obj, layer);
506 evas_object_stack_below(cw->transform_tranp_obj, obj);
511 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
518 if (!map) return NULL;
520 e_map_util_points_populate_from_object_full(map, obj, 0);
521 e_map_util_points_color_set(map, 255, 255, 255, 255);
523 for (i = 0 ; i < 4 ; ++i)
528 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
529 e_map_point_coord_set(map, i, x, y, 1.0);
536 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
542 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
545 e_comp_object_map_set(obj, map);
546 e_comp_object_map_enable_set(obj, EINA_TRUE);
553 evas_object_map_enable_set(obj, EINA_FALSE);
558 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
564 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
567 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
569 e_comp_object_map_set(obj, map);
570 e_comp_object_map_enable_set(obj, EINA_TRUE);
577 evas_object_map_enable_set(obj, EINA_FALSE);
580 /////////////////////////////////////
582 static inline Eina_Bool
583 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
585 if (num > 1) return EINA_TRUE;
586 if ((rects[0].x == 0) && (rects[0].y == 0) &&
587 ((int)rects[0].w == w) && ((int)rects[0].h == h))
592 /////////////////////////////////////
594 /* add a client to the layer-client list */
596 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
598 g_rec_mutex_lock(&e_comp->ec_list_mutex);
601 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));
603 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));
604 if ((!above) && (!below))
607 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
608 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
609 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
611 e_comp->layers[cw->layer].clients_count++;
613 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
617 _e_comp_object_layers_remove(E_Comp_Object *cw)
619 g_rec_mutex_lock(&e_comp->ec_list_mutex);
621 if (cw->ec && e_comp->layers[cw->layer].clients)
623 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
624 e_comp->layers[cw->layer].clients_count--;
627 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
630 /////////////////////////////////////
632 _e_comp_object_alpha_set(E_Comp_Object *cw)
634 Eina_Bool alpha = cw->ec->argb;
636 if ((cw->external_content) &&
637 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
642 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
643 if (cw->user_alpha_set) alpha = cw->user_alpha;
645 evas_object_image_alpha_set(cw->obj, alpha);
649 _e_comp_object_shadow(E_Comp_Object *cw)
651 if (e_client_util_shadow_state_get(cw->ec))
652 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
654 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
655 if (cw->frame_object)
656 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
657 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
660 /* convert from the surface coordinates to the buffer coordinates */
662 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
664 E_Comp_Wl_Buffer_Viewport *vp;
665 E_Comp_Wl_Client_Data *cdata;
669 cdata = e_client_cdata_get(ec);
671 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
678 vp = &cdata->scaler.buffer_viewport;
679 transform = e_comp_wl_output_buffer_transform_get(ec);
681 e_pixmap_size_get(ec->pixmap, &bw, &bh);
683 /* for subsurface, it should be swap 90 and 270 */
684 if (e_comp_wl_subsurface_check(ec))
687 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
688 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
689 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
690 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
696 case WL_OUTPUT_TRANSFORM_NORMAL:
697 default: tx = sx, ty = sy; break;
698 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
699 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
700 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
701 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
702 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
703 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
704 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
707 tx *= vp->buffer.scale;
708 ty *= vp->buffer.scale;
715 _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)
723 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
724 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
731 if (dw) *dw = MAX(x1, x2) - mx;
732 if (dh) *dh = MAX(y1, y2) - my;
736 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
737 int *dx, int *dy, int *dw, int *dh)
739 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
740 E_Util_Transform_Rect_Vertex sv, dv;
744 e_pixmap_size_get(ec->pixmap, &bw, &bh);
746 sv = e_util_transform_rect_to_vertices(&rect);
748 for (i = 0; i < 4; i++)
750 double x = 0.0, y = 0.0;
752 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
754 /* if evas decide coordinate is outside of map, it returns (0, 0)
755 in this case, full damage is added.
757 if ((i != 0) && (x == 0.0) && (y == 0.0))
760 dv.vertices[i].vertex[0] = x;
761 dv.vertices[i].vertex[1] = y;
762 dv.vertices[i].vertex[2] = 1.0;
763 dv.vertices[i].vertex[3] = 1.0;
766 rect = e_util_transform_vertices_to_rect(&dv);
768 if (dx) *dx = rect.x;
769 if (dy) *dy = rect.y;
770 if (dw) *dw = rect.w;
771 if (dh) *dh = rect.h;
785 _e_comp_object_map_damage_transform_get(E_Client *ec)
792 if (!e_client_transform_core_enable_get(ec))
795 m = e_client_map_get(ec);
799 e_pixmap_size_get(ec->pixmap, &bw, &bh);
800 if ((bw == 0) || (bh == 0))
813 e_map_point_coord_set(m2, 0, 0, 0, 0);
814 e_map_point_coord_set(m2, 1, bw, 0, 0);
815 e_map_point_coord_set(m2, 2, bw, bh, 0);
816 e_map_point_coord_set(m2, 3, 0, bh, 0);
818 for (i = 0; i < 4; i++)
822 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
823 e_map_point_image_uv_set(m2, i, map_x, map_y);
830 /////////////////////////////////////
832 /* handle evas mouse-in events on client object */
834 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
836 Evas_Event_Mouse_In *ev = event_info;
837 E_Comp_Object *cw = data;
839 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
842 /* handle evas mouse-out events on client object */
844 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
846 Evas_Event_Mouse_Out *ev = event_info;
847 E_Comp_Object *cw = data;
849 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
852 /* handle evas mouse wheel events on client object */
854 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
856 Evas_Event_Mouse_Wheel *ev = event_info;
857 E_Comp_Object *cw = data;
858 E_Binding_Event_Wheel ev2;
861 if (e_client_action_get()) return;
862 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
863 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
866 /* handle evas mouse down events on client object */
868 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
870 Evas_Event_Mouse_Down *ev = event_info;
871 E_Comp_Object *cw = data;
872 E_Binding_Event_Mouse_Button ev2;
875 if (e_client_action_get()) return;
876 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
877 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
880 /* handle evas mouse up events on client object */
882 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
884 Evas_Event_Mouse_Up *ev = event_info;
885 E_Comp_Object *cw = data;
886 E_Binding_Event_Mouse_Button ev2;
889 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
890 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
891 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
894 /* handle evas mouse movement events on client object */
896 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
898 Evas_Event_Mouse_Move *ev = event_info;
899 E_Comp_Object *cw = data;
902 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
903 e_client_mouse_move(cw->ec, &ev->cur.output);
905 /////////////////////////////////////
907 /* helper function for checking compositor themes based on user-defined matches */
909 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
911 if (((m->title) && (!ec->netwm.name)) ||
912 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
914 #if defined(__cplusplus) || defined(c_plusplus)
915 if (((m->clas) && (!ec->icccm.cpp_class)) ||
916 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
919 if (((m->clas) && (!ec->icccm.class)) ||
920 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
924 if (((m->role) && (!ec->icccm.window_role)) ||
925 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
931 if ((int)ec->netwm.type != m->primary_type)
934 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
937 if (m->borderless != 0)
941 if (e_client_util_borderless(ec))
943 if (!(((m->borderless == -1) && (!borderless)) ||
944 ((m->borderless == 1) && (borderless))))
951 if (((ec->icccm.transient_for != 0) ||
954 if (!(((m->dialog == -1) && (!dialog)) ||
955 ((m->dialog == 1) && (dialog))))
958 if (m->accepts_focus != 0)
960 int accepts_focus = 0;
962 if (ec->icccm.accepts_focus)
964 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
965 ((m->accepts_focus == 1) && (accepts_focus))))
974 if (!(((m->vkbd == -1) && (!vkbd)) ||
975 ((m->vkbd == 1) && (vkbd))))
980 if (!(((m->argb == -1) && (!ec->argb)) ||
981 ((m->argb == 1) && (ec->argb))))
984 if (m->fullscreen != 0)
986 int fullscreen = ec->fullscreen;
988 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
989 ((m->fullscreen == 1) && (fullscreen))))
994 if (!(m->modal == -1))
1000 /* function for setting up a client's compositor frame theme (cw->shobj) */
1002 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1006 Eina_List *list = NULL, *l;
1007 E_Input_Rect_Data *input_rect_data;
1008 E_Input_Rect_Smart_Data *input_rect_sd;
1010 Eina_Stringshare *reshadow_group = NULL;
1011 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1012 Eina_Stringshare *name, *title;
1013 E_Comp_Config *conf = e_comp_config_get();
1015 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1016 /* match correct client type */
1017 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1018 name = cw->ec->icccm.name;
1019 title = cw->ec->icccm.title;
1020 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1021 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1023 /* skipping here is mostly a hack for systray because I hate it */
1026 EINA_LIST_FOREACH(list, l, m)
1028 if (((m->name) && (!name)) ||
1029 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1031 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1034 no_shadow = m->no_shadow;
1035 if (m->shadow_style)
1037 /* fast effects are just themes with "/fast" appended and shorter effect times */
1040 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1041 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1043 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1045 /* default to non-fast style if fast not available */
1048 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1049 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1051 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1053 if (ok && m->visibility_effect)
1054 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1061 if (skip || (cw->ec->e.state.video))
1063 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1065 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1068 if (conf->shadow_style)
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1079 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1080 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1082 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1089 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1091 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1095 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1097 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1102 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1107 if (cw->ec->override)
1109 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1110 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1112 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1113 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1119 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1120 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1123 _e_comp_object_shadow(cw);
1126 if (focus || cw->ec->focused || cw->ec->override)
1127 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1129 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1131 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1133 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1134 /* visibility must always be enabled for re_manage clients to prevent
1135 * pop-in animations every time the user sees a persistent client again;
1136 * applying visibility for iconic clients prevents the client from getting
1139 if (cw->visible || cw->ec->re_manage)
1140 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1142 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1144 /* breaks animation counter */
1145 if (cw->frame_object)
1147 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1148 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1149 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1150 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1156 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1160 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1163 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1165 if (input_rect_data->obj)
1167 pass_event_flag = EINA_TRUE;
1173 if (cw->indicator.obj)
1175 Evas_Object *indicator;
1176 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1177 if (indicator != cw->indicator.obj)
1179 edje_object_part_unswallow(cw->shobj, indicator);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1181 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1185 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1186 evas_object_pass_events_set(cw->obj, pass_event_flag);
1191 /////////////////////////////////////////////
1194 _e_comp_object_animating_begin(E_Comp_Object *cw)
1197 if (cw->animating == 1)
1199 e_comp->animating++;
1201 e_object_ref(E_OBJECT(cw->ec));
1206 _e_comp_object_animating_end(E_Comp_Object *cw)
1215 if (cw->ec->launching)
1217 if (!cw->ec->extra_animating)
1219 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1220 cw->ec->launching = EINA_FALSE;
1221 if (cw->ec->first_mapped)
1223 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1224 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1227 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1231 e_comp->animating--;
1232 cw->showing = cw->hiding = 0;
1234 if (e_comp->animating == 0)
1235 e_comp_visibility_calculation_set(EINA_TRUE);
1236 /* remove ref from animation start, account for possibility of deletion from unref */
1237 return !!e_object_unref(E_OBJECT(cw->ec));
1243 /* handle the end of a compositor animation */
1245 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1247 E_Comp_Object *cw = data;
1249 /* visible clients which have never been sized are a bug */
1250 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1251 CRI("ACK! ec:%p", cw->ec);
1252 if (!_e_comp_object_animating_end(cw)) return;
1253 if (cw->animating) return;
1254 /* hide only after animation finishes to guarantee a full run of the animation */
1255 if (!cw->defer_hide) return;
1256 if ((!strcmp(emission, "e,action,hide,done")) ||
1257 (!strcmp(emission, "e,action,done")) ||
1258 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1260 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1261 evas_object_hide(cw->smart_obj);
1265 /* run a visibility compositor effect if available, return false if object is dead */
1267 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1273 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1274 if (!cw->effect_running)
1275 _e_comp_object_animating_begin(cw);
1276 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1277 return _e_comp_object_animating_end(cw);
1278 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1279 return _e_comp_object_animating_end(cw);
1281 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1284 zone = e_comp_zone_find_by_ec(cw->ec);
1286 zw = zone->w, zh = zone->h;
1291 zone = e_comp_object_util_zone_get(cw->smart_obj);
1292 if (!zone) zone = e_zone_current_get();
1299 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1300 cw->w, cw->h, zw, zh, x, y}, 8);
1301 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1302 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1305 /////////////////////////////////////////////
1307 /* create necessary objects for clients that e manages */
1309 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1311 if (cw->set_mouse_callbacks) return;
1312 if (!cw->smart_obj) return;
1314 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1315 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1316 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1317 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1318 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1319 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1321 cw->set_mouse_callbacks = EINA_TRUE;
1325 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1327 if (!cw->set_mouse_callbacks) return;
1328 if (!cw->smart_obj) return;
1330 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1331 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1332 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1333 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1334 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1335 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1337 cw->set_mouse_callbacks = EINA_FALSE;
1341 _e_comp_object_setup(E_Comp_Object *cw)
1343 cw->clip = evas_object_rectangle_add(e_comp->evas);
1344 evas_object_move(cw->clip, -9999, -9999);
1345 evas_object_resize(cw->clip, 999999, 999999);
1346 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1347 cw->effect_obj = edje_object_add(e_comp->evas);
1348 evas_object_move(cw->effect_obj, cw->x, cw->y);
1349 evas_object_clip_set(cw->effect_obj, cw->clip);
1350 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1351 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1352 cw->shobj = edje_object_add(e_comp->evas);
1353 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1354 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1355 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1357 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1358 if (cw->ec->override)
1360 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1361 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1362 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1364 else if (!cw->ec->input_only)
1366 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1367 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1368 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1370 cw->real_hid = !cw->ec->input_only;
1371 if (!cw->ec->input_only)
1373 e_util_size_debug_set(cw->effect_obj, 1);
1374 _e_comp_object_mouse_event_callback_set(cw);
1377 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1378 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1379 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1380 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1381 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1382 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1384 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1387 /////////////////////////////////////////////
1389 /* for fast path evas rendering; only called during render */
1391 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1393 E_Comp_Object *cw = data;
1394 E_Client *ec = cw->ec;
1396 int bx, by, bxx, byy;
1398 if (e_object_is_del(E_OBJECT(ec))) return;
1399 if (cw->external_content) return;
1400 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1401 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1404 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1405 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1407 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1409 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1410 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1414 bx = by = bxx = byy = 0;
1415 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1418 Edje_Message_Int_Set *msg;
1419 Edje_Message_Int msg2;
1420 Eina_Bool id = (bx || by || bxx || byy);
1422 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1428 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1430 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1434 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1435 e_comp_client_post_update_add(cw->ec);
1437 else if (e_comp_object_render(ec->frame))
1439 /* apply shape mask if necessary */
1440 if ((!cw->native) && (ec->shaped))
1441 e_comp_object_shape_apply(ec->frame);
1443 /* shaped clients get precise mouse events to handle transparent pixels */
1444 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1446 /* queue another render if client is still dirty; cannot refresh here. */
1447 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1448 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1450 if (cw->render_trace)
1452 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1458 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1460 E_Comp_Object *cw = data;
1461 E_Client *ec = cw->ec;
1463 if (e_object_is_del(E_OBJECT(ec))) return;
1464 if (cw->external_content) return;
1465 if (!e_comp->hwc) return;
1467 e_comp_client_render_list_add(cw->ec);
1469 if (!ec->hwc_window) return;
1471 e_hwc_windows_rendered_window_add(ec->hwc_window);
1474 /////////////////////////////////////////////
1477 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1479 E_Comp_Object *cw = data;
1482 if (cw->render_update_lock.lock)
1484 cw->render_update_lock.pending_move_x = x;
1485 cw->render_update_lock.pending_move_y = y;
1486 cw->render_update_lock.pending_move_set = EINA_TRUE;
1490 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1491 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1492 (cw->external_content))
1494 /* delay to move until the external content is unset */
1495 cw->ec->changes.pos = 1;
1500 if (cw->ec->move_after_resize)
1502 if ((x != cw->ec->x) || (y != cw->ec->y))
1504 if (!cw->ec->is_cursor)
1505 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1506 e_client_pos_set(cw->ec, x, y);
1507 cw->ec->changes.pos = 1;
1513 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1514 (cw->ec->manage_resize.resize_obj))
1516 e_client_pos_set(cw->ec, x, y);
1517 cw->ec->client.x = x + cw->client_inset.l;
1518 cw->ec->client.y = y + cw->client_inset.t;
1519 e_policy_visibility_client_defer_move(cw->ec);
1523 /* if frame_object does not exist, client_inset indicates CSD.
1524 * this means that ec->client matches cw->x/y, the opposite
1527 fx = (!cw->frame_object) * cw->client_inset.l;
1528 fy = (!cw->frame_object) * cw->client_inset.t;
1529 if ((cw->x == x + fx) && (cw->y == y + fy))
1531 if ((cw->ec->x != x) || (cw->ec->y != y))
1533 /* handle case where client tries to move to position and back very quickly */
1534 e_client_pos_set(cw->ec, x, y);
1535 cw->ec->client.x = x + cw->client_inset.l;
1536 cw->ec->client.y = y + cw->client_inset.t;
1540 if (!cw->ec->maximize_override)
1542 /* prevent moving in some directions while directionally maximized */
1543 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1545 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1548 ix = x + cw->client_inset.l;
1549 iy = y + cw->client_inset.t;
1550 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1551 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1552 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1554 /* prevent moving at all if move isn't allowed in current maximize state */
1555 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1556 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1559 zone = e_comp_zone_find_by_ec(cw->ec);
1562 cw->ec->changes.need_unmaximize = 1;
1563 cw->ec->saved.x = ix - zone->x;
1564 cw->ec->saved.y = iy - zone->y;
1565 cw->ec->saved.w = cw->ec->client.w;
1566 cw->ec->saved.h = cw->ec->client.h;
1570 /* only update during resize if triggered by resize */
1571 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1572 /* delay to move while surface waits paired commit serial*/
1573 if (e_client_pending_geometry_has(cw->ec))
1575 /* do nothing while waiting paired commit serial*/
1579 e_client_pos_set(cw->ec, x, y);
1580 if (cw->ec->new_client)
1582 /* don't actually do anything until first client idler loop */
1583 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1584 cw->ec->changes.pos = 1;
1589 /* only update xy position of client to avoid invalid
1590 * first damage region if it is not a new_client. */
1591 cw->ec->client.x = ix;
1592 cw->ec->client.y = iy;
1595 if (!cw->frame_object)
1597 evas_object_move(obj, x, y);
1602 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1604 E_Comp_Object *cw = data;
1605 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1608 if (cw->render_update_lock.lock)
1610 cw->render_update_lock.pending_resize_w = w;
1611 cw->render_update_lock.pending_resize_h = h;
1612 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1616 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1618 e_client_size_set(cw->ec, w, h);
1619 evas_object_resize(obj, w, h);
1623 /* if frame_object does not exist, client_inset indicates CSD.
1624 * this means that ec->client matches cw->w/h, the opposite
1627 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1628 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1629 if ((cw->w == w + fw) && (cw->h == h + fh))
1631 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1632 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1633 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1635 /* handle case where client tries to resize itself and back very quickly */
1636 e_client_size_set(cw->ec, w, h);
1637 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1638 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1639 evas_object_smart_callback_call(obj, "client_resize", NULL);
1643 /* guarantee that fullscreen is fullscreen */
1644 zone = e_comp_zone_find_by_ec(cw->ec);
1646 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1648 if (!e_client_transform_core_enable_get(cw->ec))
1651 /* calculate client size */
1652 iw = w - cw->client_inset.l - cw->client_inset.r;
1653 ih = h - cw->client_inset.t - cw->client_inset.b;
1654 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1656 /* prevent resizing while maximized depending on direction and config */
1657 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1659 Eina_Bool reject = EINA_FALSE;
1660 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1662 if (cw->ec->client.h != ih)
1664 cw->ec->saved.h = ih;
1665 cw->ec->saved.y = cw->ec->client.y - zone->y;
1666 reject = cw->ec->changes.need_unmaximize = 1;
1669 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1671 if (cw->ec->client.w != iw)
1673 cw->ec->saved.w = iw;
1674 cw->ec->saved.x = cw->ec->client.x - zone->x;
1675 reject = cw->ec->changes.need_unmaximize = 1;
1684 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1686 /* do nothing until client idler loops */
1687 if ((cw->ec->w != w) || (cw->ec->h != h))
1689 e_client_size_set(cw->ec, w, h);
1690 cw->ec->changes.size = 1;
1695 if (e_client_pending_geometry_has(cw->ec))
1697 /* do nothing while waiting paired commit serial*/
1701 e_client_size_set(cw->ec, w, h);
1703 cw->ec->client.w = iw;
1704 cw->ec->client.h = ih;
1705 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1707 /* The size of non-compositing window can be changed, so there is a
1708 * need to check that cw is H/W composited if cw is not redirected.
1709 * And of course we have to change size of evas object of H/W composited cw,
1710 * otherwise cw can't receive input events even if it is shown on the screen.
1712 Eina_Bool redirected = cw->redirected;
1714 redirected = e_comp_is_on_overlay(cw->ec);
1716 if ((!cw->ec->input_only) && (redirected) &&
1717 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1718 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1719 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1720 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1723 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1724 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1726 prev_w = cw->w, prev_h = cw->h;
1727 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1728 /* check shading and clamp to pixmap size for regular clients */
1729 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1730 (((w - fw != pw) || (h - fh != ph))))
1732 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1733 evas_object_smart_callback_call(obj, "client_resize", NULL);
1735 if (cw->frame_object || cw->ec->input_only)
1736 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1739 if ((cw->w == w) && (cw->h == h))
1741 /* going to be a noop resize which won't trigger smart resize */
1742 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1743 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1745 evas_object_resize(obj, w, h);
1749 evas_object_smart_callback_call(obj, "client_resize", NULL);
1752 if ((!cw->frame_object) && (!cw->ec->input_only))
1754 /* "just do it" for overrides */
1755 evas_object_resize(obj, w, h);
1757 if (!cw->ec->override)
1759 /* shape probably changed for non-overrides */
1764 /* this fixes positioning jiggles when using a resize mode
1765 * which also changes the client's position
1768 if (cw->frame_object)
1769 x = cw->x, y = cw->y;
1771 x = cw->ec->x, y = cw->ec->y;
1772 switch (cw->ec->resize_mode)
1774 case E_POINTER_RESIZE_BL:
1775 case E_POINTER_RESIZE_L:
1776 evas_object_move(obj, x + prev_w - cw->w, y);
1778 case E_POINTER_RESIZE_TL:
1779 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1781 case E_POINTER_RESIZE_T:
1782 case E_POINTER_RESIZE_TR:
1783 evas_object_move(obj, x, y + prev_h - cw->h);
1792 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1794 E_Comp_Object *cw = data;
1795 E_Comp_Wl_Client_Data *child_cdata;
1796 unsigned int l = e_comp_canvas_layer_map(layer);
1799 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1801 /* doing a compositor effect, follow directions */
1802 _e_comp_object_layer_set(obj, layer);
1803 if (layer == cw->ec->layer) //trying to put layer back
1807 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1808 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1809 if (cw->layer != l) goto layer_set;
1813 e_comp_render_queue();
1815 ec = e_client_above_get(cw->ec);
1816 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1817 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1818 ec = e_client_above_get(ec);
1819 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1821 ec = e_client_below_get(cw->ec);
1822 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1823 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1824 ec = e_client_below_get(ec);
1825 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1827 evas_object_stack_above(obj, ec->frame);
1832 if (ec && (cw->ec->parent == ec))
1834 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1835 evas_object_stack_above(obj, ec->frame);
1837 evas_object_stack_below(obj, ec->frame);
1840 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1846 if (cw->layer == l) return;
1847 if (e_comp_canvas_client_layer_map(layer) == 9999)
1848 return; //invalid layer for clients not doing comp effects
1849 if (cw->ec->fullscreen)
1851 cw->ec->saved.layer = layer;
1854 oldraise = e_config->transient.raise;
1856 /* clamp to valid client layer */
1857 layer = e_comp_canvas_client_layer_map_nearest(layer);
1858 cw->ec->layer = layer;
1859 if (e_config->transient.layer)
1862 Eina_List *list = eina_list_clone(cw->ec->transients);
1864 /* We need to set raise to one, else the child wont
1865 * follow to the new layer. It should be like this,
1866 * even if the user usually doesn't want to raise
1869 e_config->transient.raise = 1;
1870 EINA_LIST_FREE(list, child)
1872 child_cdata = e_client_cdata_get(child);
1873 if (child_cdata && !child_cdata->mapped)
1875 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1878 e_client_layer_set(child, layer);
1882 e_config->transient.raise = oldraise;
1884 _e_comp_object_layers_remove(cw);
1885 cw->layer = e_comp_canvas_layer_map(layer);
1886 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1887 //if (cw->ec->new_client)
1888 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1889 _e_comp_object_layer_set(obj, layer);
1890 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1891 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1892 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1894 /* can't stack a client above its own layer marker */
1895 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1897 if (!cw->visible) return;
1898 e_comp_render_queue();
1899 _e_comp_object_transform_obj_stack_update(obj);
1902 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1905 _e_comp_object_raise(Evas_Object *obj)
1907 evas_object_raise(obj);
1909 if (evas_object_smart_smart_get(obj))
1911 E_Client *ec = e_comp_object_client_get(obj);
1913 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1918 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1920 evas_object_lower(obj);
1922 if (evas_object_smart_smart_get(obj))
1924 E_Client *ec = e_comp_object_client_get(obj);
1927 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1928 wl_signal_emit_mutable(&cw->events.lower, NULL);
1934 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1936 evas_object_stack_above(obj, target);
1938 if (evas_object_smart_smart_get(obj))
1940 E_Client *ec = e_comp_object_client_get(obj);
1942 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1947 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1949 evas_object_stack_below(obj, target);
1951 if (evas_object_smart_smart_get(obj))
1953 E_Client *ec = e_comp_object_client_get(obj);
1955 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1960 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1962 evas_object_layer_set(obj, layer);
1964 if (evas_object_smart_smart_get(obj))
1966 E_Client *ec = e_comp_object_client_get(obj);
1968 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1973 _e_comp_object_is_pending(E_Client *ec)
1977 if (!ec) return EINA_FALSE;
1979 topmost = e_comp_wl_topmost_parent_get(ec);
1981 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1985 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1987 E_Comp_Object *cw2 = NULL;
1990 Evas_Object *o = stack;
1991 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1993 /* We should consider topmost's layer_pending for subsurface */
1994 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1996 if (_e_comp_object_is_pending(cw->ec))
1997 e_comp_object_layer_update(cw->smart_obj,
1998 raising? stack : NULL,
1999 raising? NULL : stack);
2001 /* obey compositor effects! */
2002 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2003 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2004 stack_cb(cw->smart_obj, stack);
2005 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2006 evas_object_data_del(cw->smart_obj, "client_restack");
2010 cw2 = evas_object_data_get(o, "comp_obj");
2012 /* assume someone knew what they were doing during client init */
2013 if (cw->ec->new_client)
2014 layer = cw->ec->layer;
2015 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2016 layer = cw2->ec->layer;
2018 layer = evas_object_layer_get(stack);
2019 ecstack = e_client_below_get(cw->ec);
2020 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2022 evas_object_layer_set(cw->smart_obj, layer);
2023 /* we got our layer wrangled, return now! */
2024 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2027 /* check if we're stacking below another client */
2030 /* check for non-client layer object */
2031 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2033 /* find an existing client to use for layering
2034 * by walking up the object stack
2036 * this is guaranteed to be pretty quick since we'll either:
2037 * - run out of client layers
2038 * - find a stacking client
2040 o = evas_object_above_get(o);
2041 if ((!o) || (o == cw->smart_obj)) break;
2042 if (evas_object_layer_get(o) != layer)
2044 /* reached the top client layer somehow
2045 * use top client object
2047 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2050 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2051 * return here since the top client layer window
2056 ec = e_client_top_get();
2061 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2064 if (cw2 && cw->layer != cw2->layer)
2067 /* remove existing layers */
2068 _e_comp_object_layers_remove(cw);
2071 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2072 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2073 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2074 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2075 else //if no stacking objects found, either raise or lower
2076 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2079 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2081 /* find new object for stacking if cw2 is on state of layer_pending */
2082 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2084 E_Client *new_stack = NULL, *current_ec = NULL;
2085 current_ec = cw2->ec;
2088 while ((new_stack = e_client_below_get(current_ec)))
2090 current_ec = new_stack;
2091 if (new_stack == cw->ec) continue;
2092 if (new_stack->layer != cw2->ec->layer) break;
2093 if (!_e_comp_object_is_pending(new_stack)) break;
2095 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2096 stack = new_stack->frame;
2099 /* stack it above layer object */
2101 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2102 stack = e_comp->layers[below_layer].obj;
2107 while ((new_stack = e_client_above_get(current_ec)))
2109 current_ec = new_stack;
2110 if (new_stack == cw->ec) continue;
2111 if (new_stack->layer != cw2->ec->layer) break;
2112 if (!_e_comp_object_is_pending(new_stack)) break;
2114 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2115 stack = new_stack->frame;
2117 stack = e_comp->layers[cw2->layer].obj;
2121 /* set restack if stacking has changed */
2122 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2123 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2124 stack_cb(cw->smart_obj, stack);
2125 if (e_comp->layers[cw->layer].obj)
2126 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2128 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2130 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2131 evas_object_data_del(cw->smart_obj, "client_restack");
2132 if (!cw->visible) return;
2133 e_comp_render_queue();
2137 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2139 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2141 if (evas_object_below_get(obj) == above)
2143 e_comp_object_layer_update(obj, above, NULL);
2147 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2148 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2149 _e_comp_object_transform_obj_stack_update(obj);
2150 _e_comp_object_transform_obj_stack_update(above);
2155 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2157 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2158 if (evas_object_above_get(obj) == below)
2160 e_comp_object_layer_update(obj, NULL, below);
2164 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2165 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2166 if (evas_object_smart_smart_get(obj))
2167 _e_comp_object_transform_obj_stack_update(obj);
2168 if (evas_object_smart_smart_get(below))
2169 _e_comp_object_transform_obj_stack_update(below);
2174 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2176 E_Comp_Object *cw = data;
2179 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2181 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2183 if (cw->ec->layer_pending)
2184 e_comp_object_layer_update(obj, NULL, obj);
2186 _e_comp_object_lower(cw, obj);
2189 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2190 o = evas_object_below_get(obj);
2191 _e_comp_object_layers_remove(cw);
2192 /* prepend to client list since this client should be the first item now */
2193 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2194 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2195 evas_object_data_set(obj, "client_restack", (void*)1);
2196 _e_comp_object_lower(cw, obj);
2197 evas_object_data_del(obj, "client_restack");
2198 if (!cw->visible) goto end;
2199 e_comp_render_queue();
2200 _e_comp_object_transform_obj_stack_update(obj);
2207 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2209 E_Comp_Object *cw = data;
2213 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2215 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2217 if (cw->ec->layer_pending)
2219 int obj_layer = evas_object_layer_get(obj);
2220 if (cw->ec->layer != obj_layer)
2221 e_comp_object_layer_update(obj, NULL, NULL);
2224 _e_comp_object_raise(obj);
2227 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2228 o = evas_object_above_get(obj);
2229 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2231 /* still stack below override below the layer marker */
2232 for (op = o = e_comp->layers[cw->layer].obj;
2233 o && o != e_comp->layers[cw->layer - 1].obj;
2234 op = o, o = evas_object_below_get(o))
2236 if (evas_object_smart_smart_get(o))
2240 ec = e_comp_object_client_get(o);
2241 if (ec && (!ec->override)) break;
2244 _e_comp_object_stack_below(obj, op);
2245 e_client_focus_defer_set(cw->ec);
2247 if (!cw->visible) goto end;
2248 e_comp_render_queue();
2249 _e_comp_object_transform_obj_stack_update(obj);
2256 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2258 E_Comp_Object *cw = data;
2260 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2261 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2263 ELOGF("COMP", "Hide. intercepted", cw->ec);
2268 if (cw->ec->launching == EINA_TRUE)
2270 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2271 cw->ec->launching = EINA_FALSE;
2276 /* hidden flag = just do it */
2277 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2278 evas_object_hide(obj);
2280 wl_signal_emit_mutable(&cw->events.hide, NULL);
2285 if (cw->ec->input_only)
2287 /* input_only = who cares */
2288 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2289 evas_object_hide(obj);
2291 wl_signal_emit_mutable(&cw->events.hide, NULL);
2295 /* already hidden or currently animating */
2296 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2298 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2302 /* don't try hiding during shutdown */
2303 cw->defer_hide |= stopping;
2304 if (!cw->defer_hide)
2306 if ((!cw->ec->iconic) && (!cw->ec->override))
2307 /* unset delete requested so the client doesn't break */
2308 cw->ec->delete_requested = 0;
2309 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2311 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2312 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2315 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2318 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2320 _e_comp_object_animating_begin(cw);
2321 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2323 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2324 cw->defer_hide = !!cw->animating;
2326 e_comp_object_effect_set(obj, NULL);
2329 if (cw->animating) return;
2330 /* if we have no animations running, go ahead and hide */
2332 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2333 evas_object_hide(obj);
2335 wl_signal_emit_mutable(&cw->events.hide, NULL);
2339 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2341 E_Client *ec = cw->ec;
2344 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2346 if (ec->show_pending.count > 0)
2348 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2349 ec->show_pending.running = EINA_TRUE;
2353 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2354 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2356 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2361 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,
2362 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2363 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2366 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2369 if (ec->iconic && cw->animating)
2371 /* triggered during iconify animation */
2372 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2375 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2378 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2379 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2381 evas_object_move(cw->smart_obj, ec->x, ec->y);
2382 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2383 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2385 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2386 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2389 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2390 evas_object_show(cw->smart_obj);
2393 e_client_focus_defer_set(ec);
2397 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2401 pw = ec->client.w, ph = ec->client.h;
2403 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2405 ec->changes.visible = !ec->hidden;
2408 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2412 cw->updates = eina_tiler_new(pw, ph);
2415 ec->changes.visible = !ec->hidden;
2418 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2423 eina_tiler_tile_size_set(cw->updates, 1, 1);
2426 /* ignore until client idler first run */
2427 ec->changes.visible = !ec->hidden;
2430 ELOGF("COMP", "show_helper. return. new_client", ec);
2437 evas_object_move(cw->smart_obj, ec->x, ec->y);
2438 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2439 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2440 evas_object_show(cw->smart_obj);
2443 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2445 /* start_drag not received */
2446 ec->changes.visible = 1;
2449 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2452 /* re-set geometry */
2453 evas_object_move(cw->smart_obj, ec->x, ec->y);
2454 /* force resize in case it hasn't happened yet, or just to update size */
2455 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2456 if ((cw->w < 1) || (cw->h < 1))
2458 /* if resize didn't go through, try again */
2459 ec->visible = ec->changes.visible = 1;
2461 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2464 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2465 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2466 e_pixmap_clear(ec->pixmap);
2468 if (cw->real_hid && w && h)
2471 /* force comp theming in case it didn't happen already */
2472 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2473 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2474 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2477 /* only do the show if show is allowed */
2480 if (ec->internal) //internal clients render when they feel like it
2481 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2483 if (!e_client_is_iconified_by_client(ec)||
2484 e_policy_visibility_client_is_uniconic(ec))
2486 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2487 evas_object_show(cw->smart_obj);
2489 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2490 it is rendered in idle callback without native surface and
2491 compositor shows an empty frame if other objects aren't shown
2492 because job callback of e_comp called at the next loop.
2493 it causes a visual defect when windows are switched.
2497 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2498 e_comp_object_dirty(cw->smart_obj);
2499 e_comp_object_render(cw->smart_obj);
2504 wl_signal_emit_mutable(&cw->events.show, NULL);
2508 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2510 E_Comp_Object *cw = data;
2511 E_Client *ec = cw->ec;
2513 E_Input_Rect_Data *input_rect_data;
2514 E_Input_Rect_Smart_Data *input_rect_sd;
2517 if (ec->ignored) return;
2521 //INF("SHOW2 %p", ec);
2522 _e_comp_intercept_show_helper(cw);
2525 //INF("SHOW %p", ec);
2528 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2529 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2530 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2531 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2535 if ((!cw->obj) && (cw->external_content))
2537 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2541 _e_comp_object_setup(cw);
2544 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2545 cw->obj = evas_object_image_filled_add(e_comp->evas);
2546 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2547 e_util_size_debug_set(cw->obj, 1);
2548 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2549 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2550 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2551 evas_object_name_set(cw->obj, "cw->obj");
2552 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2554 _e_comp_object_alpha_set(cw);
2557 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2560 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2561 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2564 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2567 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2569 if (input_rect_data->obj)
2571 evas_object_geometry_set(input_rect_data->obj,
2572 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2573 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2574 input_rect_data->rect.w, input_rect_data->rect.h);
2581 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2583 _e_comp_intercept_show_helper(cw);
2587 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2589 E_Comp_Object *cw = data;
2593 /* note: this is here as it seems there are enough apps that do not even
2594 * expect us to emulate a look of focus but not actually set x input
2595 * focus as we do - so simply abort any focus set on such windows */
2596 /* be strict about accepting focus hint */
2597 /* be strict about accepting focus hint */
2598 if ((!ec->icccm.accepts_focus) &&
2599 (!ec->icccm.take_focus))
2603 if (e_client_focused_get() == ec)
2604 e_client_focused_set(NULL);
2606 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2607 evas_object_focus_set(obj, focus);
2611 if (focus && ec->lock_focus_out) return;
2612 if (e_object_is_del(E_OBJECT(ec)) && focus)
2613 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2615 /* filter focus setting based on current state */
2620 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2621 evas_object_focus_set(obj, focus);
2624 if ((ec->iconic) && (!ec->deskshow))
2626 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2628 /* don't focus an iconified window. that's silly! */
2629 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2630 e_client_uniconify(ec);
2631 e_client_focus_latest_set(ec);
2645 /* not yet visible, wait till the next time... */
2646 ec->want_focus = !ec->hidden;
2651 e_client_focused_set(ec);
2655 if (e_client_focused_get() == ec)
2656 e_client_focused_set(NULL);
2660 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2662 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2664 evas_object_focus_set(obj, focus);
2668 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2670 E_Comp_Object *cw = data;
2672 if (cw->transparent.set)
2674 cw->transparent.user_r = r;
2675 cw->transparent.user_g = g;
2676 cw->transparent.user_b = b;
2677 cw->transparent.user_a = a;
2679 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2681 cw->transparent.user_r,
2682 cw->transparent.user_g,
2683 cw->transparent.user_b,
2684 cw->transparent.user_a);
2688 evas_object_color_set(obj, r, g, b, a);
2691 ////////////////////////////////////////////////////
2694 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2696 int w, h, ox, oy, ow, oh;
2698 Eina_Bool pass_event_flag = EINA_FALSE;
2699 E_Input_Rect_Data *input_rect_data;
2700 E_Input_Rect_Smart_Data *input_rect_sd;
2702 if (cw->frame_object)
2704 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2705 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2706 /* set a fixed size, force edje calc, check size difference */
2707 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2708 edje_object_message_signal_process(cw->frame_object);
2709 edje_object_calc_force(cw->frame_object);
2710 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2711 cw->client_inset.l = ox;
2712 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2713 cw->client_inset.t = oy;
2714 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2715 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2716 evas_object_resize(cw->frame_object, w, h);
2720 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2723 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2725 if (input_rect_data->obj)
2727 pass_event_flag = EINA_TRUE;
2733 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2734 evas_object_pass_events_set(cw->obj, pass_event_flag);
2738 cw->client_inset.l = 0;
2739 cw->client_inset.r = 0;
2740 cw->client_inset.t = 0;
2741 cw->client_inset.b = 0;
2743 cw->client_inset.calc = !!cw->frame_object;
2747 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2749 E_Comp_Object *cw = data;
2753 /* - get current size
2755 * - readjust for new frame size
2758 w = cw->ec->w, h = cw->ec->h;
2759 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2761 _e_comp_object_frame_recalc(cw);
2763 if (!cw->ec->fullscreen)
2764 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2766 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2767 if (cw->ec->fullscreen)
2769 zone = e_comp_zone_find_by_ec(cw->ec);
2771 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2773 else if (cw->ec->new_client)
2775 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2776 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2777 evas_object_resize(cw->ec->frame, w, h);
2779 else if ((w != cw->ec->w) || (h != cw->ec->h))
2780 evas_object_resize(cw->ec->frame, w, h);
2784 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2786 E_Comp_Object *cw = data;
2788 _e_comp_object_shadow_setup(cw);
2789 if (cw->frame_object)
2791 _e_comp_object_shadow(cw);
2792 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2793 _e_comp_object_frame_recalc(cw);
2794 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2799 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2801 E_Comp_Object *cw = data;
2803 if (_e_comp_object_shadow_setup(cw))
2804 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2805 if (cw->frame_object)
2807 _e_comp_object_shadow(cw);
2808 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2809 _e_comp_object_frame_recalc(cw);
2810 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2815 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2817 E_Comp_Object *cw = data;
2819 if (cw->frame_object)
2821 _e_comp_object_shadow(cw);
2822 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2823 _e_comp_object_frame_recalc(cw);
2824 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2829 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2831 E_Comp_Object *cw = data;
2833 if (_e_comp_object_shadow_setup(cw))
2836 cw->ec->changes.size = 1;
2838 if (cw->frame_object)
2840 _e_comp_object_shadow(cw);
2841 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2842 _e_comp_object_frame_recalc(cw);
2843 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2848 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2850 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2854 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2856 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2860 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2862 E_Comp_Object *cw = data;
2864 if (!cw->ec) return; //NYI
2865 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2869 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2871 E_Comp_Object *cw = data;
2873 if (!cw->ec) return; //NYI
2874 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2878 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2880 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2884 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2886 E_Comp_Object *cw = data;
2888 if (!e_object_is_del(E_OBJECT(cw->ec)))
2889 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2893 _e_comp_input_obj_smart_add(Evas_Object *obj)
2895 E_Input_Rect_Smart_Data *input_rect_sd;
2896 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2898 if (!input_rect_sd) return;
2899 evas_object_smart_data_set(obj, input_rect_sd);
2903 _e_comp_input_obj_smart_del(Evas_Object *obj)
2905 E_Input_Rect_Smart_Data *input_rect_sd;
2906 E_Input_Rect_Data *input_rect_data;
2908 input_rect_sd = evas_object_smart_data_get(obj);
2909 if (!input_rect_sd) return;
2911 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2913 if (input_rect_data->obj)
2915 evas_object_smart_member_del(input_rect_data->obj);
2916 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2918 E_FREE(input_rect_data);
2920 E_FREE(input_rect_sd);
2924 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2926 E_Input_Rect_Smart_Data *input_rect_sd;
2927 E_Input_Rect_Data *input_rect_data;
2931 input_rect_sd = evas_object_smart_data_get(obj);
2932 if (!input_rect_sd) return;
2934 cw = input_rect_sd->cw;
2935 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2937 if (input_rect_data->obj)
2939 evas_object_geometry_set(input_rect_data->obj,
2940 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2941 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2942 input_rect_data->rect.w, input_rect_data->rect.h);
2948 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2950 E_Input_Rect_Smart_Data *input_rect_sd;
2951 E_Input_Rect_Data *input_rect_data;
2955 input_rect_sd = evas_object_smart_data_get(obj);
2956 if (!input_rect_sd) return;
2958 cw = input_rect_sd->cw;
2959 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2961 if (input_rect_data->obj)
2963 evas_object_geometry_set(input_rect_data->obj,
2964 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2965 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2966 input_rect_data->rect.w, input_rect_data->rect.h);
2972 _e_comp_input_obj_smart_show(Evas_Object *obj)
2974 E_Input_Rect_Smart_Data *input_rect_sd;
2975 E_Input_Rect_Data *input_rect_data;
2978 input_rect_sd = evas_object_smart_data_get(obj);
2979 if (!input_rect_sd) return;
2981 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2983 if (input_rect_data->obj)
2985 evas_object_show(input_rect_data->obj);
2991 _e_comp_input_obj_smart_hide(Evas_Object *obj)
2993 E_Input_Rect_Smart_Data *input_rect_sd;
2994 E_Input_Rect_Data *input_rect_data;
2997 input_rect_sd = evas_object_smart_data_get(obj);
2998 if (!input_rect_sd) return;
3000 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3002 if (input_rect_data->obj)
3004 evas_object_hide(input_rect_data->obj);
3010 _e_comp_input_obj_smart_init(void)
3012 if (_e_comp_input_obj_smart) return;
3014 static const Evas_Smart_Class sc =
3016 INPUT_OBJ_SMART_NAME,
3017 EVAS_SMART_CLASS_VERSION,
3018 _e_comp_input_obj_smart_add,
3019 _e_comp_input_obj_smart_del,
3020 _e_comp_input_obj_smart_move,
3021 _e_comp_input_obj_smart_resize,
3022 _e_comp_input_obj_smart_show,
3023 _e_comp_input_obj_smart_hide,
3036 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3042 _e_comp_smart_add(Evas_Object *obj)
3046 cw = E_NEW(E_Comp_Object, 1);
3047 EINA_SAFETY_ON_NULL_RETURN(cw);
3049 wl_signal_init(&cw->events.lower);
3050 #ifdef REFACTOR_DESK_AREA
3051 wl_signal_init(&cw->events.raise);
3053 wl_signal_init(&cw->events.show);
3054 wl_signal_init(&cw->events.hide);
3055 #ifdef REFACTOR_DESK_AREA
3056 wl_signal_init(&cw->events.set_layer);
3057 wl_signal_init(&cw->events.stack_above);
3058 wl_signal_init(&cw->events.stack_below);
3061 cw->smart_obj = obj;
3062 cw->x = cw->y = cw->w = cw->h = -1;
3063 evas_object_smart_data_set(obj, cw);
3064 cw->opacity = 255.0;
3065 cw->external_content = 0;
3066 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3067 cw->transform_bg_color.r = 0;
3068 cw->transform_bg_color.g = 0;
3069 cw->transform_bg_color.b = 0;
3070 cw->transform_bg_color.a = 255;
3071 evas_object_data_set(obj, "comp_obj", cw);
3072 evas_object_move(obj, -1, -1);
3073 /* intercept ALL the callbacks! */
3074 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3075 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3076 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3077 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3078 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3079 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3080 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3081 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3082 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3083 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3084 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3086 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3087 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3088 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3089 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3091 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3092 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3094 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3095 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3097 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3099 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3100 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3104 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3107 evas_object_color_set(cw->clip, r, g, b, a);
3108 evas_object_smart_callback_call(obj, "color_set", NULL);
3113 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3116 evas_object_clip_set(cw->clip, clip);
3120 _e_comp_smart_clip_unset(Evas_Object *obj)
3123 evas_object_clip_unset(cw->clip);
3127 _e_comp_smart_hide(Evas_Object *obj)
3129 TRACE_DS_BEGIN(COMP:SMART HIDE);
3134 evas_object_hide(cw->clip);
3135 if (cw->input_obj) evas_object_hide(cw->input_obj);
3136 evas_object_hide(cw->effect_obj);
3137 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3138 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3139 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3146 /* unset native surface if current displaying buffer was destroied */
3147 if (!cw->buffer_destroy_listener.notify)
3149 Evas_Native_Surface *ns;
3150 ns = evas_object_image_native_surface_get(cw->obj);
3151 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3152 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3155 if (!cw->ec->input_only)
3157 edje_object_freeze(cw->effect_obj);
3158 edje_object_freeze(cw->shobj);
3159 edje_object_play_set(cw->shobj, 0);
3160 if (cw->frame_object)
3161 edje_object_play_set(cw->frame_object, 0);
3164 e_comp_render_queue(); //force nocomp recheck
3170 _e_comp_smart_show(Evas_Object *obj)
3178 if ((cw->w < 0) || (cw->h < 0))
3179 CRI("ACK! ec:%p", cw->ec);
3181 TRACE_DS_BEGIN(COMP:SMART SHOW);
3183 e_comp_object_map_update(obj);
3185 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3186 evas_object_show(tmp->frame);
3188 evas_object_show(cw->clip);
3189 if (cw->input_obj) evas_object_show(cw->input_obj);
3190 if (!cw->ec->input_only)
3192 edje_object_thaw(cw->effect_obj);
3193 edje_object_thaw(cw->shobj);
3194 edje_object_play_set(cw->shobj, 1);
3195 if (cw->frame_object)
3196 edje_object_play_set(cw->frame_object, 1);
3198 evas_object_show(cw->effect_obj);
3199 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3200 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3201 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3202 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3203 e_comp_render_queue();
3204 if (cw->ec->input_only)
3209 if (cw->ec->iconic && (!cw->ec->new_client))
3211 if (e_client_is_iconified_by_client(cw->ec))
3213 ELOGF("COMP", "Set launching flag..", cw->ec);
3214 cw->ec->launching = EINA_TRUE;
3217 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3219 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3222 ELOGF("COMP", "Set launching flag..", cw->ec);
3223 cw->ec->launching = EINA_TRUE;
3225 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3226 _e_comp_object_animating_begin(cw);
3227 if (!_e_comp_object_effect_visibility_start(cw, 1))
3233 /* ensure some random effect doesn't lock the client offscreen */
3237 e_comp_object_effect_set(obj, NULL);
3240 _e_comp_object_dim_update(cw);
3246 _e_comp_smart_del(Evas_Object *obj)
3252 if (cw->buffer_destroy_listener.notify)
3254 wl_list_remove(&cw->buffer_destroy_listener.link);
3255 cw->buffer_destroy_listener.notify = NULL;
3258 if (cw->tbm_surface)
3260 tbm_surface_internal_unref(cw->tbm_surface);
3261 cw->tbm_surface = NULL;
3264 if (cw->render_update_lock.buffer_ref.buffer)
3266 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3267 cw->ec, cw->render_update_lock.lock);
3268 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3271 e_comp_object_render_update_del(cw->smart_obj);
3272 E_FREE_FUNC(cw->updates, eina_tiler_free);
3273 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3280 EINA_LIST_FREE(cw->obj_mirror, o)
3282 evas_object_image_data_set(o, NULL);
3283 evas_object_freeze_events_set(o, 1);
3284 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3288 _e_comp_object_layers_remove(cw);
3289 l = evas_object_data_get(obj, "comp_object-to_del");
3290 E_FREE_LIST(l, evas_object_del);
3291 _e_comp_object_mouse_event_callback_unset(cw);
3292 evas_object_del(cw->clip);
3293 evas_object_del(cw->obj);
3294 evas_object_del(cw->shobj);
3295 evas_object_del(cw->effect_obj);
3296 evas_object_del(cw->frame_object);
3297 evas_object_del(cw->input_obj);
3298 evas_object_del(cw->mask.obj);
3299 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3300 evas_object_del(cw->transform_bg_obj);
3301 evas_object_del(cw->transform_tranp_obj);
3302 evas_object_del(cw->default_input_obj);
3303 eina_stringshare_del(cw->frame_theme);
3304 eina_stringshare_del(cw->frame_name);
3308 e_comp->animating--;
3310 e_object_unref(E_OBJECT(cw->ec));
3312 cw->ec->frame = NULL;
3317 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3321 cw->x = x, cw->y = y;
3322 evas_object_move(cw->effect_obj, x, y);
3323 evas_object_move(cw->default_input_obj, x, y);
3324 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3326 e_comp_object_map_update(obj);
3330 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3332 Eina_Bool first = EINA_FALSE;
3337 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3339 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3341 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3343 if (cw->w != w || cw->h != h)
3344 e_comp_object_map_update(obj);
3346 first = ((cw->w < 1) || (cw->h < 1));
3347 cw->w = w, cw->h = h;
3351 if (cw->frame_object)
3352 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3355 /* verify pixmap:object size */
3356 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3358 if ((ww != pw) || (hh != ph))
3359 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3361 evas_object_resize(cw->effect_obj, tw, th);
3362 evas_object_resize(cw->default_input_obj, w, h);
3364 evas_object_resize(cw->input_obj, w, h);
3366 evas_object_resize(cw->mask.obj, w, h);
3367 /* resize render update tiler */
3370 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3371 cw->updates_full = 0;
3372 if (cw->updates) eina_tiler_clear(cw->updates);
3376 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3377 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3385 e_comp_render_queue();
3391 _e_comp_smart_init(void)
3393 if (_e_comp_smart) return;
3395 static const Evas_Smart_Class sc =
3398 EVAS_SMART_CLASS_VERSION,
3402 _e_comp_smart_resize,
3405 _e_comp_smart_color_set,
3406 _e_comp_smart_clip_set,
3407 _e_comp_smart_clip_unset,
3417 _e_comp_smart = evas_smart_class_new(&sc);
3422 e_comp_object_init(void)
3424 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3425 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3426 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3427 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3431 e_comp_object_shutdown(void)
3437 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3439 API_ENTRY EINA_FALSE;
3440 return !!cw->force_visible;
3442 /////////////////////////////////////////////////////////
3445 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3448 Eina_Bool comp_object;
3450 comp_object = !!evas_object_data_get(obj, "comp_object");
3455 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3457 e_comp_render_queue();
3459 l = evas_object_data_get(obj, "comp_object-to_del");
3460 E_FREE_LIST(l, evas_object_del);
3464 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3466 if (e_comp_util_object_is_above_nocomp(obj) &&
3467 (!evas_object_data_get(obj, "comp_override")))
3469 evas_object_data_set(obj, "comp_override", (void*)1);
3470 e_comp_override_add();
3475 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3477 Eina_Bool ref = EINA_TRUE;
3478 if (evas_object_visible_get(obj))
3482 d = evas_object_data_del(obj, "comp_hiding");
3484 /* currently trying to hide */
3487 /* already visible */
3491 evas_object_show(obj);
3494 evas_object_ref(obj);
3495 evas_object_data_set(obj, "comp_ref", (void*)1);
3497 edje_object_signal_emit(obj, "e,state,visible", "e");
3498 evas_object_data_set(obj, "comp_showing", (void*)1);
3499 if (e_comp_util_object_is_above_nocomp(obj))
3501 evas_object_data_set(obj, "comp_override", (void*)1);
3502 e_comp_override_add();
3507 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3509 if (!evas_object_visible_get(obj)) return;
3510 /* already hiding */
3511 if (evas_object_data_get(obj, "comp_hiding")) return;
3512 if (!evas_object_data_del(obj, "comp_showing"))
3514 evas_object_ref(obj);
3515 evas_object_data_set(obj, "comp_ref", (void*)1);
3517 edje_object_signal_emit(obj, "e,state,hidden", "e");
3518 evas_object_data_set(obj, "comp_hiding", (void*)1);
3520 if (evas_object_data_del(obj, "comp_override"))
3521 e_comp_override_timed_pop();
3525 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3527 if (!e_util_strcmp(emission, "e,action,hide,done"))
3529 if (!evas_object_data_del(obj, "comp_hiding")) return;
3530 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3531 evas_object_hide(obj);
3532 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3535 evas_object_data_del(obj, "comp_showing");
3536 if (evas_object_data_del(obj, "comp_ref"))
3537 evas_object_unref(obj);
3541 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3547 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3551 E_API E_Comp_Object_Hook *
3552 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3554 E_Comp_Object_Hook *ch;
3556 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3557 ch = E_NEW(E_Comp_Object_Hook, 1);
3558 if (!ch) return NULL;
3559 ch->hookpoint = hookpoint;
3561 ch->data = (void*)data;
3562 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3567 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3570 if (_e_comp_object_hooks_walking == 0)
3572 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3576 _e_comp_object_hooks_delete++;
3579 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3580 E_API E_Comp_Object_Intercept_Hook *
3581 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3583 E_Comp_Object_Intercept_Hook *ch;
3585 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3586 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3587 if (!ch) return NULL;
3588 ch->hookpoint = hookpoint;
3590 ch->data = (void*)data;
3591 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3596 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3599 if (_e_comp_object_intercept_hooks_walking == 0)
3601 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3605 _e_comp_object_intercept_hooks_delete++;
3610 e_comp_object_util_add(Evas_Object *obj)
3614 E_Comp_Config *conf = e_comp_config_get();
3615 Eina_Bool skip = EINA_FALSE;
3621 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3623 name = evas_object_name_get(obj);
3624 vis = evas_object_visible_get(obj);
3625 o = edje_object_add(e_comp->evas);
3626 evas_object_data_set(o, "comp_object", (void*)1);
3628 skip = (!strncmp(name, "noshadow", 8));
3630 evas_object_data_set(o, "comp_object_skip", (void*)1);
3632 if (conf->shadow_style)
3634 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3635 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3638 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3639 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3640 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3642 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3644 evas_object_geometry_get(obj, &x, &y, &w, &h);
3645 evas_object_geometry_set(o, x, y, w, h);
3646 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3648 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3650 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3651 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3652 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3653 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3654 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3655 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3657 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3659 edje_object_part_swallow(o, "e.swallow.content", obj);
3661 _e_comp_object_event_add(o);
3664 evas_object_show(o);
3669 /* utility functions for deleting objects when their "owner" is deleted */
3671 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3676 EINA_SAFETY_ON_NULL_RETURN(to_del);
3677 l = evas_object_data_get(obj, "comp_object-to_del");
3678 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3679 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3680 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3684 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3689 EINA_SAFETY_ON_NULL_RETURN(to_del);
3690 l = evas_object_data_get(obj, "comp_object-to_del");
3692 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3695 /////////////////////////////////////////////////////////
3697 EINTERN Evas_Object *
3698 e_comp_object_client_add(E_Client *ec)
3703 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3704 if (ec->frame) return NULL;
3705 _e_comp_smart_init();
3706 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3707 cw = evas_object_smart_data_get(o);
3708 if (!cw) return NULL;
3709 evas_object_data_set(o, "E_Client", ec);
3712 evas_object_data_set(o, "comp_object", (void*)1);
3714 _e_comp_object_event_add(o);
3719 /* utility functions for getting client inset */
3721 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3724 if (!cw->client_inset.calc)
3730 if (ax) *ax = x - cw->client_inset.l;
3731 if (ay) *ay = y - cw->client_inset.t;
3735 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3738 if (!cw->client_inset.calc)
3744 if (ax) *ax = x + cw->client_inset.l;
3745 if (ay) *ay = y + cw->client_inset.t;
3749 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3752 if (!cw->client_inset.calc)
3758 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3759 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3763 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3766 if (!cw->client_inset.calc)
3772 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3773 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3777 e_comp_object_client_get(Evas_Object *obj)
3782 /* FIXME: remove this when eo is used */
3783 o = evas_object_data_get(obj, "comp_smart_obj");
3785 return e_comp_object_client_get(o);
3786 return cw ? cw->ec : NULL;
3790 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3793 if (cw->frame_extends)
3794 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3799 if (w) *w = cw->ec->w;
3800 if (h) *h = cw->ec->h;
3805 e_comp_object_util_zone_get(Evas_Object *obj)
3807 E_Zone *zone = NULL;
3811 zone = e_comp_zone_find_by_ec(cw->ec);
3816 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3817 zone = e_comp_zone_xy_get(x, y);
3823 e_comp_object_util_center(Evas_Object *obj)
3825 int x, y, w, h, ow, oh;
3830 zone = e_comp_object_util_zone_get(obj);
3831 EINA_SAFETY_ON_NULL_RETURN(zone);
3832 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3833 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3834 ow = cw->ec->w, oh = cw->ec->h;
3836 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3837 x = x + (w - ow) / 2;
3838 y = y + (h - oh) / 2;
3839 evas_object_move(obj, x, y);
3843 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3845 int x, y, w, h, ow, oh;
3848 EINA_SAFETY_ON_NULL_RETURN(on);
3849 evas_object_geometry_get(on, &x, &y, &w, &h);
3850 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3851 ow = cw->ec->w, oh = cw->ec->h;
3853 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3854 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3858 e_comp_object_util_fullscreen(Evas_Object *obj)
3863 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3866 evas_object_move(obj, 0, 0);
3867 evas_object_resize(obj, e_comp->w, e_comp->h);
3872 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3880 ow = cw->w, oh = cw->h;
3882 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3883 zone = e_comp_object_util_zone_get(obj);
3884 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3885 if (x) *x = zx + (zw - ow) / 2;
3886 if (y) *y = zy + (zh - oh) / 2;
3890 e_comp_object_input_objs_del(Evas_Object *obj)
3893 E_Input_Rect_Data *input_rect_data;
3894 E_Input_Rect_Smart_Data *input_rect_sd;
3899 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3900 if (!input_rect_sd) return;
3902 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3904 if (input_rect_data->obj)
3906 evas_object_smart_member_del(input_rect_data->obj);
3907 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3909 E_FREE(input_rect_data);
3914 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3917 E_Input_Rect_Data *input_rect_data = NULL;
3918 E_Input_Rect_Smart_Data *input_rect_sd;
3919 int client_w, client_h;
3921 if (cw->ec->client.w)
3922 client_w = cw->ec->client.w;
3924 client_w = cw->ec->w;
3926 if (cw->ec->client.h)
3927 client_h = cw->ec->client.h;
3929 client_h = cw->ec->h;
3931 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3935 _e_comp_input_obj_smart_init();
3936 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3937 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3938 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3941 input_rect_sd->cw = cw;
3944 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3947 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3948 if (input_rect_data)
3950 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3951 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3955 if ((input_rect_data) &&
3956 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3958 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3959 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3960 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3961 evas_object_clip_set(input_rect_data->obj, cw->clip);
3962 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3963 evas_object_geometry_set(input_rect_data->obj,
3964 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3965 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3966 evas_object_pass_events_set(cw->default_input_obj, 1);
3967 evas_object_pass_events_set(cw->obj, 1);
3970 evas_object_show(input_rect_data->obj);
3971 evas_object_show(cw->input_obj);
3976 evas_object_smart_member_del(cw->input_obj);
3977 E_FREE_FUNC(cw->input_obj, evas_object_del);
3978 evas_object_pass_events_set(cw->default_input_obj, 0);
3979 evas_object_pass_events_set(cw->obj, 0);
3984 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
3987 E_Input_Rect_Smart_Data *input_rect_sd;
3988 E_Input_Rect_Data *input_rect_data;
3991 if (!cw->input_obj) return;
3993 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3996 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3998 *list = eina_list_append(*list, &input_rect_data->rect);
4004 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4007 if (l) *l = cw->client_inset.l;
4008 if (r) *r = cw->client_inset.r;
4009 if (t) *t = cw->client_inset.t;
4010 if (b) *b = cw->client_inset.b;
4013 /* set geometry for CSD */
4015 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4021 if (cw->frame_object)
4022 CRI("ACK! ec:%p", cw->ec);
4023 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4024 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4025 calc = cw->client_inset.calc;
4026 cw->client_inset.calc = l || r || t || b;
4027 eina_stringshare_replace(&cw->frame_theme, "borderless");
4028 if (cw->client_inset.calc)
4030 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4031 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4032 e_client_size_set(cw->ec, tw, th);
4034 else if (cw->ec->maximized || cw->ec->fullscreen)
4036 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4037 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4039 if (!cw->ec->new_client)
4041 if (calc && cw->client_inset.calc)
4043 tx = cw->ec->x - (l - cw->client_inset.l);
4044 ty = cw->ec->y - (t - cw->client_inset.t);
4045 e_client_pos_set(cw->ec, tx, ty);
4047 cw->ec->changes.pos = cw->ec->changes.size = 1;
4050 cw->client_inset.l = l;
4051 cw->client_inset.r = r;
4052 cw->client_inset.t = t;
4053 cw->client_inset.b = b;
4057 e_comp_object_frame_allowed(Evas_Object *obj)
4059 API_ENTRY EINA_FALSE;
4060 return (cw->frame_object || (!cw->client_inset.calc));
4064 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4066 API_ENTRY EINA_FALSE;
4067 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4068 eina_stringshare_replace(&cw->frame_name, name);
4069 if (cw->frame_object)
4070 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4075 e_comp_object_frame_exists(Evas_Object *obj)
4077 API_ENTRY EINA_FALSE;
4078 return !!cw->frame_object;
4082 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4084 Evas_Object *o, *pbg;
4087 Eina_Stringshare *theme;
4089 API_ENTRY EINA_FALSE;
4091 if (!e_util_strcmp(cw->frame_theme, name))
4092 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4093 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4094 return _e_comp_object_shadow_setup(cw);
4095 pbg = cw->frame_object;
4096 theme = eina_stringshare_add(name);
4098 if (cw->frame_object)
4102 w = cw->ec->w, h = cw->ec->h;
4103 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4104 if ((cw->ec->w != w) || (cw->ec->h != h))
4106 cw->ec->changes.size = 1;
4109 E_FREE_FUNC(cw->frame_object, evas_object_del);
4110 if (!name) goto reshadow;
4112 o = edje_object_add(e_comp->evas);
4113 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4114 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4115 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4117 cw->frame_object = NULL;
4119 eina_stringshare_del(cw->frame_theme);
4120 cw->frame_theme = theme;
4125 if (theme != e_config->theme_default_border_style)
4127 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4128 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4132 ok = e_theme_edje_object_set(o, "base/theme/border",
4133 "e/widgets/border/default/border");
4134 if (ok && (theme == e_config->theme_default_border_style))
4136 /* Reset default border style to default */
4137 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4138 e_config_save_queue();
4145 cw->frame_object = o;
4146 eina_stringshare_del(cw->frame_theme);
4147 cw->frame_theme = theme;
4148 evas_object_name_set(o, "cw->frame_object");
4151 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4155 cw->ec->changes.icon = 1;
4161 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4166 _e_comp_object_shadow_setup(cw);
4169 int old_x, old_y, new_x = 0, new_y = 0;
4171 old_x = cw->x, old_y = cw->y;
4173 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4175 new_x = cw->ec->x, new_y = cw->ec->y;
4176 else if (cw->ec->placed || (!cw->ec->new_client))
4178 /* if no previous frame:
4179 * - reapply client_inset
4184 if (cw->ec->changes.size)
4192 zone = e_comp_zone_find_by_ec(cw->ec);
4195 x = cw->ec->client.x, y = cw->ec->client.y;
4196 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4197 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4199 new_x = x, new_y = y;
4202 if (old_x != new_x || old_y != new_y)
4204 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4205 cw->y = cw->x = -99999;
4206 evas_object_move(obj, new_x, new_y);
4210 if (cw->ec->maximized)
4212 cw->ec->changes.need_maximize = 1;
4215 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4216 if (cw->frame_object)
4218 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4221 cw->frame_extends = 0;
4222 evas_object_del(pbg);
4227 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4229 E_Comp_Object_Mover *prov;
4232 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4233 edje_object_signal_emit(cw->shobj, sig, src);
4234 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4235 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4236 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4238 /* start with highest priority callback first */
4239 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4241 if (!e_util_glob_match(sig, prov->sig)) continue;
4242 if (prov->func(prov->data, obj, sig)) break;
4247 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4249 /* FIXME: at some point I guess this should use eo to inherit
4250 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4251 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4254 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4258 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4261 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4265 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4268 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4272 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4275 Eina_Rectangle rect;
4278 if (cw->ec->input_only || (!cw->updates)) return;
4279 if (cw->nocomp) return;
4280 rect.x = x, rect.y = y;
4281 rect.w = w, rect.h = h;
4282 evas_object_smart_callback_call(obj, "damage", &rect);
4284 if (e_comp_is_on_overlay(cw->ec))
4286 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4287 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4288 * E module attempts to block screen update due to the particular policy.
4290 if (e_pixmap_resource_get(cw->ec->pixmap))
4291 cw->hwc_need_update = EINA_TRUE;
4294 /* ignore overdraw */
4295 if (cw->updates_full)
4297 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4298 e_comp_object_render_update_add(obj);
4300 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4301 evas_object_show(cw->smart_obj);
4305 /* clip rect to client surface */
4306 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4307 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4308 /* if rect is the total size of the client after clip, clear the updates
4309 * since this is guaranteed to be the whole region anyway
4311 eina_tiler_area_size_get(cw->updates, &tw, &th);
4312 if ((w > tw) || (h > th))
4314 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4315 eina_tiler_clear(cw->updates);
4316 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4318 tw = cw->ec->client.w, th = cw->ec->client.h;
4320 if ((!x) && (!y) && (w == tw) && (h == th))
4322 eina_tiler_clear(cw->updates);
4323 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4324 cw->updates_full = 1;
4325 cw->update_count = 0;
4328 if (cw->update_count > UPDATE_MAX)
4330 /* this is going to get really dumb, so just update the whole thing */
4331 eina_tiler_clear(cw->updates);
4332 cw->update_count = cw->updates_full = 1;
4333 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4334 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4338 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4339 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4341 cw->updates_exist = 1;
4342 e_comp_object_render_update_add(obj);
4344 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4345 evas_object_show(cw->smart_obj);
4349 e_comp_object_damage_exists(Evas_Object *obj)
4351 API_ENTRY EINA_FALSE;
4352 return cw->updates_exist;
4356 e_comp_object_render_update_add(Evas_Object *obj)
4360 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4361 if (cw->render_update_lock.lock) return;
4362 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4366 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4368 e_comp_render_queue();
4372 e_comp_object_render_update_del(Evas_Object *obj)
4376 if (cw->ec->input_only || (!cw->updates)) return;
4377 if (!cw->update) return;
4379 /* this gets called during comp animating to clear the update flag */
4380 if (e_comp->grabbed) return;
4381 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4382 if (!e_comp->updates)
4384 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4385 if (e_comp->render_animator)
4386 ecore_animator_freeze(e_comp->render_animator);
4391 e_comp_object_shape_apply(Evas_Object *obj)
4395 unsigned int i, *pix, *p;
4399 if (!cw->ec) return; //NYI
4400 if (cw->external_content) return;
4403 if ((cw->ec->shape_rects_num >= 1) &&
4404 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4409 ERR("BUGGER: shape with native surface? cw=%p", cw);
4412 evas_object_image_size_get(cw->obj, &w, &h);
4413 if ((w < 1) || (h < 1)) return;
4416 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4417 _e_comp_object_alpha_set(cw);
4418 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4419 evas_object_image_alpha_set(o, 1);
4421 p = pix = evas_object_image_data_get(cw->obj, 1);
4424 evas_object_image_data_set(cw->obj, pix);
4429 unsigned char *spix, *sp;
4431 spix = calloc(w * h, sizeof(unsigned char));
4433 for (i = 0; i < cw->ec->shape_rects_num; i++)
4437 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4438 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4439 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4440 sp = spix + (w * ry) + rx;
4441 for (py = 0; py < rh; py++)
4443 for (px = 0; px < rw; px++)
4451 for (py = 0; py < h; py++)
4453 for (px = 0; px < w; px++)
4455 unsigned int mask, imask;
4457 mask = ((unsigned int)(*sp)) << 24;
4459 imask |= imask >> 8;
4460 imask |= imask >> 8;
4461 *p = mask | (*p & imask);
4462 //if (*sp) *p = 0xff000000 | *p;
4463 //else *p = 0x00000000;
4472 for (py = 0; py < h; py++)
4474 for (px = 0; px < w; px++)
4478 evas_object_image_data_set(cw->obj, pix);
4479 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4480 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4482 evas_object_image_data_set(o, pix);
4483 evas_object_image_data_update_add(o, 0, 0, w, h);
4485 // don't need to fix alpha chanel as blending
4486 // should be totally off here regardless of
4487 // alpha channel content
4491 _e_comp_object_clear(E_Comp_Object *cw)
4496 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4498 if (cw->render_update_lock.lock) return;
4501 e_pixmap_clear(cw->ec->pixmap);
4503 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4504 evas_object_image_size_set(cw->obj, 1, 1);
4505 evas_object_image_data_set(cw->obj, NULL);
4506 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4508 evas_object_image_size_set(o, 1, 1);
4509 evas_object_image_data_set(o, NULL);
4512 e_comp_object_render_update_del(cw->smart_obj);
4516 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4520 API_ENTRY EINA_FALSE;
4522 if (cw->transparent.set == set)
4527 evas_object_color_get(obj, &r, &g, &b, &a);
4528 evas_object_color_set(obj, 0, 0, 0, 0);
4530 cw->transparent.user_r = r;
4531 cw->transparent.user_g = g;
4532 cw->transparent.user_b = b;
4533 cw->transparent.user_a = a;
4535 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4537 cw->transparent.user_r,
4538 cw->transparent.user_g,
4539 cw->transparent.user_b,
4540 cw->transparent.user_a);
4542 cw->transparent.set = EINA_TRUE;
4546 cw->transparent.set = EINA_FALSE;
4548 evas_object_color_set(obj,
4549 cw->transparent.user_r,
4550 cw->transparent.user_g,
4551 cw->transparent.user_b,
4552 cw->transparent.user_a);
4554 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4556 cw->transparent.user_r,
4557 cw->transparent.user_g,
4558 cw->transparent.user_b,
4559 cw->transparent.user_a);
4565 /* helper function to simplify toggling of redirection for display servers which support it */
4567 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4572 if (cw->redirected == set) return;
4573 cw->redirected = set;
4574 if (cw->external_content) return;
4576 e_comp_object_map_update(obj);
4580 if (cw->updates_exist)
4581 e_comp_object_render_update_add(obj);
4583 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4585 _e_comp_object_transparent_set(obj, EINA_FALSE);
4586 evas_object_smart_callback_call(obj, "redirected", NULL);
4590 _e_comp_object_clear(cw);
4591 _e_comp_object_transparent_set(obj, EINA_TRUE);
4592 evas_object_smart_callback_call(obj, "unredirected", NULL);
4597 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4600 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4602 if (cw->buffer_destroy_listener.notify)
4604 cw->buffer_destroy_listener.notify = NULL;
4605 wl_list_remove(&cw->buffer_destroy_listener.link);
4608 if (e_object_is_del(E_OBJECT(cw->ec)))
4610 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4615 /* if it's current displaying buffer, do not remove its content */
4616 if (!evas_object_visible_get(cw->ec->frame))
4617 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4622 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4627 if (cw->buffer_destroy_listener.notify)
4629 wl_list_remove(&cw->buffer_destroy_listener.link);
4630 cw->buffer_destroy_listener.notify = NULL;
4633 if (cw->tbm_surface)
4635 tbm_surface_internal_unref(cw->tbm_surface);
4636 cw->tbm_surface = NULL;
4641 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4643 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4644 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4646 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4648 tbm_surface_internal_ref(ns->data.tbm.buffer);
4649 cw->tbm_surface = ns->data.tbm.buffer;
4653 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4654 evas_object_image_native_surface_set(cw->obj, ns);
4658 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4660 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4661 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4662 evas_object_image_native_surface_set(o, ns);
4669 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4671 Evas_Native_Surface ns;
4674 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4675 if (cw->ec->input_only) return;
4676 if (cw->external_content) return;
4677 if (cw->render_update_lock.lock) return;
4680 memset(&ns, 0, sizeof(Evas_Native_Surface));
4684 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4685 set = (!cw->ec->shaped);
4687 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4691 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4695 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4698 if (cw->ec->input_only) return;
4701 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4702 _e_comp_object_alpha_set(cw);
4704 e_comp_object_native_surface_set(obj, cw->native);
4705 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4709 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4715 if (cw->blanked == set) return;
4717 _e_comp_object_alpha_set(cw);
4720 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4721 evas_object_image_data_set(cw->obj, NULL);
4725 e_comp_object_native_surface_set(obj, 1);
4726 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4730 _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)
4735 if (!_damage_trace) return;
4739 if (!evas_object_visible_get(cw->obj)) return;
4741 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4743 o = evas_object_rectangle_add(e_comp->evas);
4744 evas_object_layer_set(o, E_LAYER_MAX);
4745 evas_object_name_set(o, "damage_trace");
4746 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4747 evas_object_resize(o, dmg_w, dmg_h);
4748 evas_object_color_set(o, 0, 128, 0, 128);
4749 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4750 evas_object_pass_events_set(o, EINA_TRUE);
4751 evas_object_show(o);
4753 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4755 dmg_w, dmg_h, dmg_x, dmg_y,
4756 origin->w, origin->h, origin->x, origin->y);
4758 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4761 /* mark an object as dirty and setup damages */
4763 e_comp_object_dirty(Evas_Object *obj)
4766 Eina_Rectangle *rect;
4770 Eina_Bool dirty, visible;
4774 if (cw->external_content) return;
4775 if (!cw->redirected) return;
4776 if (cw->render_update_lock.lock)
4778 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4781 /* only actually dirty if pixmap is available */
4782 if (!e_pixmap_resource_get(cw->ec->pixmap))
4784 // e_pixmap_size_get returns last attached buffer size
4785 // eventhough it is destroyed
4786 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4789 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4790 visible = cw->visible;
4791 if (!dirty) w = h = 1;
4792 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4794 evas_object_image_data_set(cw->obj, NULL);
4795 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4796 evas_object_image_size_set(cw->obj, tw, th);
4797 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4798 if (cw->pending_updates)
4799 eina_tiler_area_size_set(cw->pending_updates, w, h);
4800 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4802 evas_object_image_pixels_dirty_set(o, dirty);
4804 evas_object_image_data_set(o, NULL);
4805 evas_object_image_size_set(o, tw, th);
4806 visible |= evas_object_visible_get(o);
4810 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4814 e_comp_object_native_surface_set(obj, 1);
4816 m = _e_comp_object_map_damage_transform_get(cw->ec);
4817 it = eina_tiler_iterator_new(cw->updates);
4818 EINA_ITERATOR_FOREACH(it, rect)
4820 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4821 * of evas engine and doesn't convert damage according to evas_map.
4822 * so damage of evas_object_image use surface coordinate.
4826 int damage_x, damage_y, damage_w, damage_h;
4828 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4829 &damage_x, &damage_y, &damage_w, &damage_h);
4830 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4831 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4835 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4836 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4839 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4840 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4841 if (cw->pending_updates)
4842 eina_tiler_rect_add(cw->pending_updates, rect);
4844 eina_iterator_free(it);
4845 if (m) e_map_free(m);
4846 if (cw->pending_updates)
4847 eina_tiler_clear(cw->updates);
4850 cw->pending_updates = cw->updates;
4851 cw->updates = eina_tiler_new(w, h);
4852 eina_tiler_tile_size_set(cw->updates, 1, 1);
4854 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4855 evas_object_smart_callback_call(obj, "dirty", NULL);
4856 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4857 /* force render if main object is hidden but mirrors are visible */
4858 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4859 e_comp_object_render(obj);
4863 e_comp_object_render(Evas_Object *obj)
4870 API_ENTRY EINA_FALSE;
4872 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4873 if (cw->ec->input_only) return EINA_TRUE;
4874 if (cw->external_content) return EINA_TRUE;
4875 if (cw->native) return EINA_FALSE;
4876 /* if comp object is not redirected state, comp object should not be set by newly committed data
4877 because image size of comp object is 1x1 and it should not be shown on canvas */
4878 if (!cw->redirected) return EINA_TRUE;
4879 if (cw->render_update_lock.lock)
4881 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4884 e_comp_object_render_update_del(obj);
4885 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4887 if (!cw->pending_updates)
4889 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4890 evas_object_image_data_set(cw->obj, NULL);
4891 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4892 evas_object_image_data_set(o, NULL);
4896 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4898 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4900 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4903 e_pixmap_image_refresh(cw->ec->pixmap);
4904 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4907 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4908 e_pixmap_image_data_ref(cw->ec->pixmap);
4910 /* set pixel data */
4911 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4912 _e_comp_object_alpha_set(cw);
4913 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4915 evas_object_image_data_set(o, pix);
4916 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4917 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4920 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4922 e_comp_client_post_update_add(cw->ec);
4927 /* create a duplicate of an evas object */
4929 e_comp_object_util_mirror_add(Evas_Object *obj)
4933 unsigned int *pix = NULL;
4934 Eina_Bool argb = EINA_FALSE;
4939 cw = evas_object_data_get(obj, "comp_mirror");
4942 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4943 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4944 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4945 evas_object_image_alpha_set(o, 1);
4946 evas_object_image_source_set(o, obj);
4949 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4950 if (cw->external_content)
4952 ERR("%p of client %p is external content.", obj, cw->ec);
4955 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4956 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4957 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4958 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4959 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4960 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4961 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4962 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4963 evas_object_data_set(o, "comp_mirror", cw);
4965 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4966 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4968 evas_object_image_size_set(o, tw, th);
4971 pix = evas_object_image_data_get(cw->obj, 0);
4977 evas_object_image_native_surface_set(o, cw->ns);
4980 Evas_Native_Surface ns;
4981 memset(&ns, 0, sizeof(Evas_Native_Surface));
4982 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
4983 evas_object_image_native_surface_set(o, &ns);
4988 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
4989 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
4991 (e_pixmap_image_exists(cw->ec->pixmap)))
4992 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4994 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5001 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5002 evas_object_image_pixels_dirty_set(o, dirty);
5003 evas_object_image_data_set(o, pix);
5004 evas_object_image_data_set(cw->obj, pix);
5006 evas_object_image_data_update_add(o, 0, 0, tw, th);
5011 //////////////////////////////////////////////////////
5014 e_comp_object_effect_allowed_get(Evas_Object *obj)
5016 API_ENTRY EINA_FALSE;
5018 if (!cw->shobj) return EINA_FALSE;
5019 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5020 return !e_comp_config_get()->match.disable_borders;
5023 /* setup an api effect for a client */
5025 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5028 Eina_Stringshare *grp;
5029 E_Comp_Config *config;
5030 Eina_Bool loaded = EINA_FALSE;
5032 API_ENTRY EINA_FALSE;
5033 if (!cw->shobj) return EINA_FALSE; //input window
5035 if (!effect) effect = "none";
5036 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5038 config = e_comp_config_get();
5039 if ((config) && (config->effect_file))
5041 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5043 cw->effect_set = EINA_TRUE;
5050 edje_object_file_get(cw->effect_obj, NULL, &grp);
5051 cw->effect_set = !eina_streq(effect, "none");
5052 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5053 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5055 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5056 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5057 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5059 if (cw->effect_running)
5061 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5064 cw->effect_set = EINA_FALSE;
5065 return cw->effect_set;
5069 if (cw->effect_running)
5071 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5074 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5075 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5076 if (cw->effect_clip)
5078 evas_object_clip_unset(cw->clip);
5079 cw->effect_clip = 0;
5081 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5083 _e_comp_object_dim_update(cw);
5085 return cw->effect_set;
5088 /* set params for embryo scripts in effect */
5090 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5092 Edje_Message_Int_Set *msg;
5096 EINA_SAFETY_ON_NULL_RETURN(params);
5097 EINA_SAFETY_ON_FALSE_RETURN(count);
5098 if (!cw->effect_set) return;
5100 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5101 msg->count = (int)count;
5102 for (x = 0; x < count; x++)
5103 msg->val[x] = params[x];
5104 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5105 edje_object_message_signal_process(cw->effect_obj);
5109 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5111 Edje_Signal_Cb end_cb;
5113 E_Comp_Object *cw = data;
5115 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5116 cw->effect_running = 0;
5117 if (!_e_comp_object_animating_end(cw)) return;
5119 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5121 evas_object_data_del(cw->smart_obj, "effect_running");
5122 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5123 e_comp_visibility_calculation_set(EINA_TRUE);
5126 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5127 if (!end_cb) return;
5128 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5129 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5130 end_cb(end_data, cw->smart_obj, emission, source);
5133 /* clip effect to client's zone */
5135 e_comp_object_effect_clip(Evas_Object *obj)
5139 zone = e_comp_zone_find_by_ec(cw->ec);
5141 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5142 if (!cw->effect_clip_able) return;
5143 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5144 cw->effect_clip = 1;
5147 /* unclip effect from client's zone */
5149 e_comp_object_effect_unclip(Evas_Object *obj)
5152 if (!cw->effect_clip) return;
5153 evas_object_clip_unset(cw->smart_obj);
5154 cw->effect_clip = 0;
5157 /* start effect, running end_cb after */
5159 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5161 API_ENTRY EINA_FALSE;
5162 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5163 if (!cw->effect_set) return EINA_FALSE;
5165 if (cw->effect_running)
5167 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5170 e_comp_object_effect_clip(obj);
5171 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5173 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5174 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5175 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5176 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5178 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5179 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5181 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5182 _e_comp_object_animating_begin(cw);
5183 cw->effect_running = 1;
5187 /* stop a currently-running effect immediately */
5189 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5192 Edje_Signal_Cb end_cb_before = NULL;
5193 void *end_data_before = NULL;
5194 API_ENTRY EINA_FALSE;
5196 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5197 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5199 if (end_cb_before != end_cb) return EINA_TRUE;
5200 e_comp_object_effect_unclip(obj);
5201 if (cw->effect_clip)
5203 evas_object_clip_unset(cw->effect_obj);
5204 cw->effect_clip = 0;
5206 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5207 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5209 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5211 evas_object_data_del(cw->smart_obj, "effect_running");
5212 e_comp_visibility_calculation_set(EINA_TRUE);
5215 cw->effect_running = 0;
5216 ret = _e_comp_object_animating_end(cw);
5218 if ((ret) && (end_cb_before))
5220 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5221 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5228 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5230 return a->pri - b->pri;
5233 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5234 E_API E_Comp_Object_Mover *
5235 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5237 E_Comp_Object_Mover *prov;
5239 prov = E_NEW(E_Comp_Object_Mover, 1);
5240 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5241 prov->func = provider;
5242 prov->data = (void*)data;
5245 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5246 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5251 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5253 EINA_SAFETY_ON_NULL_RETURN(prov);
5254 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5259 e_comp_object_effect_object_get(Evas_Object *obj)
5263 return cw->effect_obj;
5267 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5269 API_ENTRY EINA_FALSE;
5270 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5271 if (!cw->effect_set) return EINA_FALSE;
5278 ////////////////////////////////////
5281 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5283 if (e_comp->autoclose.obj)
5285 e_comp_ungrab_input(0, 1);
5286 if (e_comp->autoclose.del_cb)
5287 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5288 else if (!already_del)
5290 evas_object_hide(e_comp->autoclose.obj);
5291 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5293 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5295 e_comp->autoclose.obj = NULL;
5296 e_comp->autoclose.data = NULL;
5297 e_comp->autoclose.del_cb = NULL;
5298 e_comp->autoclose.key_cb = NULL;
5299 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5303 _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)
5305 _e_comp_object_autoclose_cleanup(0);
5309 _e_comp_object_autoclose_setup(Evas_Object *obj)
5311 if (!e_comp->autoclose.rect)
5313 /* create rect just below autoclose object to catch mouse events */
5314 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5315 evas_object_move(e_comp->autoclose.rect, 0, 0);
5316 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5317 evas_object_show(e_comp->autoclose.rect);
5318 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5319 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5320 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5321 e_comp_grab_input(0, 1);
5323 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5324 evas_object_focus_set(obj, 1);
5328 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5330 _e_comp_object_autoclose_setup(obj);
5331 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5335 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5337 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5338 _e_comp_object_autoclose_cleanup(1);
5339 if (e_client_focused_get()) return;
5341 E_Zone *zone = e_zone_current_get();
5344 e_zone_focus_reset(zone);
5348 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5352 if (e_comp->autoclose.obj)
5354 if (e_comp->autoclose.obj == obj) return;
5355 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5356 e_comp->autoclose.obj = obj;
5357 e_comp->autoclose.del_cb = del_cb;
5358 e_comp->autoclose.key_cb = cb;
5359 e_comp->autoclose.data = (void*)data;
5360 if (evas_object_visible_get(obj))
5361 _e_comp_object_autoclose_setup(obj);
5363 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5364 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5367 e_comp->autoclose.obj = obj;
5368 e_comp->autoclose.del_cb = del_cb;
5369 e_comp->autoclose.key_cb = cb;
5370 e_comp->autoclose.data = (void*)data;
5371 if (evas_object_visible_get(obj))
5372 _e_comp_object_autoclose_setup(obj);
5374 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5375 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5379 e_comp_object_is_animating(Evas_Object *obj)
5383 return cw->animating;
5387 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5391 if ((cw->external_content) &&
5392 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5394 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5395 "But current external content is %d object for %p.",
5396 cw->content_type, cw->ec);
5400 cw->user_alpha_set = EINA_TRUE;
5401 cw->user_alpha = alpha;
5403 if (!cw->obj) return;
5405 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5407 evas_object_image_alpha_set(cw->obj, alpha);
5409 if ((!cw->native) && (!cw->external_content))
5410 evas_object_image_data_set(cw->obj, NULL);
5414 e_comp_object_alpha_get(Evas_Object *obj)
5416 API_ENTRY EINA_FALSE;
5418 return evas_object_image_alpha_get(cw->obj);
5422 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5424 Eina_Bool mask_set = EINA_FALSE;
5428 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5429 if (cw->ec->input_only) return;
5436 o = evas_object_rectangle_add(e_comp->evas);
5437 evas_object_color_set(o, 0, 0, 0, 0);
5438 evas_object_clip_set(o, cw->clip);
5439 evas_object_smart_member_add(o, obj);
5440 evas_object_move(o, 0, 0);
5441 evas_object_resize(o, cw->w, cw->h);
5442 /* save render op value to restore when clear a mask.
5444 * NOTE: DO NOT change the render op on ec->frame while mask object
5445 * is set. it will overwrite the changed op value. */
5446 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5447 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5448 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5449 if (cw->visible) evas_object_show(o);
5452 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5453 ELOGF("COMP", " |mask_obj", cw->ec);
5454 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5461 evas_object_smart_member_del(cw->mask.obj);
5462 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5464 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5465 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5471 e_comp_object_mask_has(Evas_Object *obj)
5473 API_ENTRY EINA_FALSE;
5475 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5479 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5484 if ((cw->external_content) &&
5485 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5487 WRN("Can set up size to ONLY evas \"image\" object. "
5488 "But current external content is %d object for %p.",
5489 cw->content_type, cw->ec);
5493 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5495 evas_object_image_size_set(cw->obj, tw, th);
5499 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5501 Eina_Bool transform_set = EINA_FALSE;
5503 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5504 if (cw->ec->input_only) return;
5506 transform_set = !!set;
5510 if (!cw->transform_bg_obj)
5512 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5513 evas_object_move(o, 0, 0);
5514 evas_object_resize(o, 1, 1);
5515 if (cw->transform_bg_color.a >= 255)
5516 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5518 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5519 evas_object_color_set(o,
5520 cw->transform_bg_color.r,
5521 cw->transform_bg_color.g,
5522 cw->transform_bg_color.b,
5523 cw->transform_bg_color.a);
5524 if (cw->visible) evas_object_show(o);
5526 cw->transform_bg_obj = o;
5527 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5529 _e_comp_object_transform_obj_stack_update(obj);
5533 if (cw->transform_bg_obj)
5535 evas_object_smart_member_del(cw->transform_bg_obj);
5536 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5542 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5546 cw->transform_bg_color.r = r;
5547 cw->transform_bg_color.g = g;
5548 cw->transform_bg_color.b = b;
5549 cw->transform_bg_color.a = a;
5551 if (cw->transform_bg_obj)
5553 evas_object_color_set(cw->transform_bg_obj,
5554 cw->transform_bg_color.r,
5555 cw->transform_bg_color.g,
5556 cw->transform_bg_color.b,
5557 cw->transform_bg_color.a);
5562 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5565 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5566 if (cw->ec->input_only) return;
5567 if (!cw->transform_bg_obj) return;
5569 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5573 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5576 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5577 if (cw->ec->input_only) return;
5578 if (!cw->transform_bg_obj) return;
5580 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5584 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5586 Eina_Bool transform_set = EINA_FALSE;
5588 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5589 if (cw->ec->input_only) return;
5591 transform_set = !!set;
5595 if (!cw->transform_tranp_obj)
5597 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5598 evas_object_move(o, 0, 0);
5599 evas_object_resize(o, 1, 1);
5600 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5601 evas_object_color_set(o, 0, 0, 0, 0);
5602 if (cw->visible) evas_object_show(o);
5604 cw->transform_tranp_obj = o;
5605 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5606 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5607 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5609 _e_comp_object_transform_obj_stack_update(obj);
5613 if (cw->transform_tranp_obj)
5615 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5616 evas_object_smart_member_del(cw->transform_tranp_obj);
5617 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5623 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5626 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5627 if (cw->ec->input_only) return;
5628 if (!cw->transform_tranp_obj) return;
5630 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5634 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5637 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5638 if (cw->ec->input_only) return;
5639 if (!cw->transform_tranp_obj) return;
5641 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5645 e_comp_object_layer_update(Evas_Object *obj,
5646 Evas_Object *above, Evas_Object *below)
5648 E_Comp_Object *cw2 = NULL;
5649 Evas_Object *o = NULL;
5654 if (cw->ec->layer_block) return;
5655 if ((above) && (below))
5657 ERR("Invalid layer update request! cw=%p", cw);
5665 layer = evas_object_layer_get(o);
5666 cw2 = evas_object_data_get(o, "comp_obj");
5669 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5671 o = evas_object_above_get(o);
5672 if ((!o) || (o == cw->smart_obj)) break;
5673 if (evas_object_layer_get(o) != layer)
5675 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5680 ec = e_client_top_get();
5681 if (ec) o = ec->frame;
5684 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5688 _e_comp_object_layers_remove(cw);
5691 if (cw2->layer > cw->layer)
5692 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5693 else if (cw2->layer == cw->layer)
5696 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5698 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5700 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5703 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5706 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5710 e_comp_object_layer_get(Evas_Object *obj)
5717 e_comp_object_content_set(Evas_Object *obj,
5718 Evas_Object *content,
5719 E_Comp_Object_Content_Type type)
5721 API_ENTRY EINA_FALSE;
5723 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5724 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5725 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5729 ERR("Can't set e.swallow.content to requested content. "
5730 "Previous comp object should not be changed at all.");
5734 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5736 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5737 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5739 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5740 type, content, cw->ec, cw->ec->pixmap);
5744 cw->external_content = EINA_TRUE;
5747 cw->content_type = type;
5748 e_util_size_debug_set(cw->obj, 1);
5749 evas_object_name_set(cw->obj, "cw->obj");
5750 _e_comp_object_alpha_set(cw);
5753 _e_comp_object_shadow_setup(cw);
5759 e_comp_object_content_unset(Evas_Object *obj)
5761 API_ENTRY EINA_FALSE;
5763 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5764 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5766 if (!cw->obj && !cw->ec->visible)
5768 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5772 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5774 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5780 if (cw->frame_object)
5781 edje_object_part_unswallow(cw->frame_object, cw->obj);
5783 edje_object_part_unswallow(cw->shobj, cw->obj);
5785 evas_object_del(cw->obj);
5786 evas_object_hide(cw->obj);
5790 cw->external_content = EINA_FALSE;
5791 if (cw->ec->is_cursor)
5794 DBG("%p is cursor surface..", cw->ec);
5795 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5797 evas_object_resize(cw->ec->frame, pw, ph);
5798 evas_object_hide(cw->ec->frame);
5803 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5804 cw->obj = evas_object_image_filled_add(e_comp->evas);
5805 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5806 e_util_size_debug_set(cw->obj, 1);
5807 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5808 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5809 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5810 evas_object_name_set(cw->obj, "cw->obj");
5811 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5812 _e_comp_object_alpha_set(cw);
5815 _e_comp_object_shadow_setup(cw);
5820 _e_comp_intercept_show_helper(cw);
5824 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5825 e_comp_object_dirty(cw->smart_obj);
5826 e_comp_object_render(cw->smart_obj);
5827 e_comp_object_render_update_add(obj);
5832 EINTERN Evas_Object *
5833 e_comp_object_content_get(Evas_Object *obj)
5837 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5839 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5841 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5848 E_API E_Comp_Object_Content_Type
5849 e_comp_object_content_type_get(Evas_Object *obj)
5851 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5853 return cw->content_type;
5857 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5860 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5861 E_Comp_Config *conf = e_comp_config_get();
5862 if (cw->ec->input_only) return;
5863 if (!conf->dim_rect_enable) return;
5865 cw->dim.mask_set = mask_set;
5871 if (!cw->dim.enable) return;
5872 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5876 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5878 Eina_Bool mask_set = EINA_FALSE;
5882 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5883 E_Comp_Config *conf = e_comp_config_get();
5884 if (cw->ec->input_only) return;
5885 if (!conf->dim_rect_enable) return;
5891 if (cw->dim.mask_obj)
5893 evas_object_smart_member_del(cw->dim.mask_obj);
5894 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5897 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);
5898 o = evas_object_rectangle_add(e_comp->evas);
5899 evas_object_color_set(o, 0, 0, 0, 0);
5900 evas_object_smart_member_add(o, obj);
5901 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5902 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5904 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5905 if (cw->visible) evas_object_show(o);
5907 cw->dim.mask_obj = o;
5908 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5910 evas_object_layer_set(cw->dim.mask_obj, 9998);
5914 if (cw->dim.mask_obj)
5916 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5917 evas_object_smart_member_del(cw->dim.mask_obj);
5918 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5924 e_comp_object_dim_client_set(E_Client *ec)
5926 E_Comp_Config *conf = e_comp_config_get();
5928 if (!conf->dim_rect_enable) return ;
5929 if (dim_client == ec) return;
5931 Eina_Bool prev_dim = EINA_FALSE;
5932 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5934 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5935 prev_dim = EINA_TRUE;
5937 if (prev_dim && dim_client->visible && ec)
5939 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5940 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5944 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5945 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5951 e_comp_object_dim_client_get(void)
5953 E_Comp_Config *conf = e_comp_config_get();
5955 if (!conf->dim_rect_enable ) return NULL;
5961 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
5964 char emit[32] = "\0";
5965 E_Comp_Config *conf = e_comp_config_get();
5968 if (!conf->dim_rect_enable) return;
5969 if (!cw->effect_obj) return;
5970 if (enable == cw->dim.enable) return;
5972 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
5973 if (noeffect || !conf->dim_rect_effect)
5975 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
5979 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
5982 cw->dim.enable = enable;
5984 if (cw->dim.mask_set && !enable)
5986 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5987 edje_object_signal_emit(cw->effect_obj, emit, "e");
5989 else if (cw->dim.mask_set && enable)
5991 edje_object_signal_emit(cw->effect_obj, emit, "e");
5992 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5996 edje_object_signal_emit(cw->effect_obj, emit, "e");
6001 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6003 API_ENTRY EINA_FALSE;
6004 E_Comp_Config *conf = e_comp_config_get();
6006 if (!ec) return EINA_FALSE;
6007 if (!conf->dim_rect_enable) return EINA_FALSE;
6009 if (cw->dim.enable) return EINA_TRUE;
6015 _e_comp_object_dim_update(E_Comp_Object *cw)
6017 E_Comp_Config *conf = e_comp_config_get();
6020 if (!conf->dim_rect_enable) return;
6021 if (!cw->effect_obj) return;
6024 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6025 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6027 if (cw->dim.mask_set)
6029 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6035 e_comp_object_clear(Evas_Object *obj)
6039 _e_comp_object_clear(cw);
6043 e_comp_object_hwc_update_exists(Evas_Object *obj)
6045 API_ENTRY EINA_FALSE;
6046 return cw->hwc_need_update;
6051 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6054 cw->hwc_need_update = set;
6058 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6060 API_ENTRY EINA_FALSE;
6061 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6065 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6068 if (cw->indicator.obj != indicator)
6069 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6070 cw->indicator.obj = indicator;
6071 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6075 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6078 if (cw->indicator.obj != indicator) return;
6079 cw->indicator.obj = NULL;
6080 edje_object_part_unswallow(cw->shobj, indicator);
6084 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6087 Edje_Message_Int_Set *msg;
6089 if (!cw->indicator.obj) return;
6091 cw->indicator.w = w;
6092 cw->indicator.h = h;
6094 if (!cw->shobj) return;
6096 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6100 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6101 edje_object_message_signal_process(cw->shobj);
6104 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6106 e_comp_object_map_update(Evas_Object *obj)
6109 E_Client *ec = cw->ec;
6110 E_Comp_Wl_Client_Data *cdata;
6112 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6115 int l, remain = sizeof buffer;
6118 if (e_object_is_del(E_OBJECT(ec))) return;
6119 cdata = e_client_cdata_get(ec);
6122 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6123 * when new buffer is attached.
6125 if (!cdata->buffer_ref.buffer) return;
6127 if ((!cw->redirected) ||
6128 (e_client_video_hw_composition_check(ec)) ||
6129 (!e_comp_wl_output_buffer_transform_get(ec) &&
6130 cdata->scaler.buffer_viewport.buffer.scale == 1))
6132 if (evas_object_map_enable_get(cw->effect_obj))
6134 ELOGF("TRANSFORM", "map: disable", cw->ec);
6135 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6136 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6137 evas_object_resize(cw->effect_obj, tw, th);
6144 EINA_SAFETY_ON_NULL_RETURN(map);
6146 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6152 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6154 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6155 e_map_point_image_uv_set(map, 0, x, y);
6156 l = snprintf(p, remain, "%d,%d", x, y);
6157 p += l, remain -= l;
6159 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6160 e_map_point_image_uv_set(map, 1, x, y);
6161 l = snprintf(p, remain, " %d,%d", x, y);
6162 p += l, remain -= l;
6164 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6165 e_map_point_image_uv_set(map, 2, x, y);
6166 l = snprintf(p, remain, " %d,%d", x, y);
6167 p += l, remain -= l;
6169 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6170 e_map_point_image_uv_set(map, 3, x, y);
6171 l = snprintf(p, remain, " %d,%d", x, y);
6172 p += l, remain -= l;
6174 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6176 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6178 e_comp_object_map_set(cw->effect_obj, map);
6179 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6183 /* if there's screen rotation with comp mode, then ec->effect_obj and
6184 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6186 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6187 evas_object_resize(cw->effect_obj, tw, th);
6191 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6193 API_ENTRY EINA_FALSE;
6195 cw->render_trace = set;
6201 e_comp_object_native_usable_get(Evas_Object *obj)
6203 API_ENTRY EINA_FALSE;
6204 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6206 if (cw->ec->input_only) return EINA_FALSE;
6207 if (cw->external_content) return EINA_FALSE;
6208 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6210 /* just return true value, if it is normal case */
6211 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6214 Evas_Native_Surface *ns;
6215 ns = evas_object_image_native_surface_get(cw->obj);
6217 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6220 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6228 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6230 API_ENTRY EINA_FALSE;
6231 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6232 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6233 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6237 case E_COMP_IMAGE_FILTER_BLUR:
6238 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6240 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6241 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6243 case E_COMP_IMAGE_FILTER_INVERSE:
6244 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6246 case E_COMP_IMAGE_FILTER_NONE:
6248 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6252 cw->image_filter = filter;
6257 EINTERN E_Comp_Image_Filter
6258 e_comp_object_image_filter_get(Evas_Object *obj)
6260 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6261 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6262 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6263 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6265 return cw->image_filter;
6269 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6273 if (!_damage_trace) return;
6275 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6276 evas_object_del(obj);
6278 _damage_trace_post_objs = NULL;
6282 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6284 if (!_damage_trace) return;
6286 _damage_trace_post_objs = _damage_trace_objs;
6287 _damage_trace_objs = NULL;
6291 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6293 if (_damage_trace == onoff) return;
6297 evas_event_callback_add(e_comp->evas,
6298 EVAS_CALLBACK_RENDER_PRE,
6299 _e_comp_object_damage_trace_render_pre_cb,
6302 evas_event_callback_add(e_comp->evas,
6303 EVAS_CALLBACK_RENDER_POST,
6304 _e_comp_object_damage_trace_render_post_cb,
6311 EINA_LIST_FREE(_damage_trace_objs, obj)
6312 evas_object_del(obj);
6314 _damage_trace_objs = NULL;
6316 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6317 evas_object_del(obj);
6319 _damage_trace_post_objs = NULL;
6321 evas_event_callback_del(e_comp->evas,
6322 EVAS_CALLBACK_RENDER_PRE,
6323 _e_comp_object_damage_trace_render_pre_cb);
6325 evas_event_callback_del(e_comp->evas,
6326 EVAS_CALLBACK_RENDER_POST,
6327 _e_comp_object_damage_trace_render_post_cb);
6330 _damage_trace = onoff;
6334 e_comp_object_redirected_get(Evas_Object *obj)
6336 API_ENTRY EINA_FALSE;
6337 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6339 return cw->redirected;
6343 e_comp_object_color_visible_get(Evas_Object *obj)
6345 API_ENTRY EINA_FALSE;
6348 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6350 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6354 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6358 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6362 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6370 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6372 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6374 return e_map_set_to_comp_object(em, obj);
6378 e_comp_object_map_get(const Evas_Object *obj)
6380 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6382 return e_map_get_from_comp_object(obj);
6386 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6388 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6390 evas_object_map_enable_set(obj, enable);
6396 e_comp_object_render_update_lock(Evas_Object *obj)
6398 E_Comp_Wl_Buffer *buffer;
6399 struct wayland_tbm_client_queue *cqueue;
6401 API_ENTRY EINA_FALSE;
6403 if (cw->render_update_lock.lock == 0)
6405 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6407 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6408 if ((buffer) && (buffer->resource))
6410 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6412 wayland_tbm_server_client_queue_flush(cqueue);
6415 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6416 e_comp_object_render_update_del(obj);
6418 ELOGF("COMP", "Render update lock enabled", cw->ec);
6421 cw->render_update_lock.lock++;
6427 e_comp_object_render_update_unlock(Evas_Object *obj)
6431 if (cw->render_update_lock.lock == 0)
6434 cw->render_update_lock.lock--;
6436 if (cw->render_update_lock.lock == 0)
6439 if (cw->render_update_lock.pending_move_set)
6441 evas_object_move(obj,
6442 cw->render_update_lock.pending_move_x,
6443 cw->render_update_lock.pending_move_y);
6444 cw->render_update_lock.pending_move_x = 0;
6445 cw->render_update_lock.pending_move_y = 0;
6446 cw->render_update_lock.pending_move_set = EINA_FALSE;
6449 if (cw->render_update_lock.pending_resize_set)
6451 evas_object_resize(obj,
6452 cw->render_update_lock.pending_resize_w,
6453 cw->render_update_lock.pending_resize_h);
6454 cw->render_update_lock.pending_resize_w = 0;
6455 cw->render_update_lock.pending_resize_h = 0;
6456 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6459 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6461 if ((cw->ec->exp_iconify.buffer_flush) &&
6462 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6463 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6464 e_comp_object_clear(obj);
6466 e_comp_object_render_update_add(obj);
6468 ELOGF("COMP", "Render update lock disabled", cw->ec);
6473 e_comp_object_render_update_lock_get(Evas_Object *obj)
6475 API_ENTRY EINA_FALSE;
6477 if (cw->render_update_lock.lock > 0)
6484 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6488 if (cw->transparent.set)
6490 if (r) *r = cw->transparent.user_r;
6491 if (g) *g = cw->transparent.user_g;
6492 if (b) *b = cw->transparent.user_b;
6493 if (a) *a = cw->transparent.user_a;
6497 evas_object_color_get(obj, r, g, b, a);
6502 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6506 evas_object_render_op_set(cw->obj, op);
6509 EINTERN Evas_Render_Op
6510 e_comp_object_render_op_get(Evas_Object *obj)
6512 API_ENTRY EVAS_RENDER_BLEND;
6514 return evas_object_render_op_get(cw->obj);
6518 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6521 wl_signal_add(&cw->events.lower, listener);
6524 #ifdef REFACTOR_DESK_AREA
6526 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6529 wl_signal_add(&cw->events.raise, listener);
6534 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6537 wl_signal_add(&cw->events.show, listener);
6541 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6544 wl_signal_add(&cw->events.hide, listener);
6547 #ifdef REFACTOR_DESK_AREA
6549 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6552 wl_signal_add(&cw->events.set_layer, listener);
6556 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6559 wl_signal_add(&cw->events.stack_above, listener);
6563 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6566 wl_signal_add(&cw->events.stack_below, listener);