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;
77 Eina_Stringshare *frame_theme;
78 Eina_Stringshare *frame_name;
79 Eina_Stringshare *visibility_effect; //effect when toggling visibility
81 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
83 Evas_Object *smart_obj; // smart object
84 Evas_Object *clip; // clipper over effect object
85 Evas_Object *input_obj; // input smart object
86 Evas_Object *obj; // composite object
87 Evas_Object *frame_object; // for client frames
88 Evas_Object *shobj; // shadow object
89 Evas_Object *effect_obj; // effects object
90 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
95 Evas_Object *transform_tranp_obj;// transform transp rect obj
96 Evas_Object *default_input_obj; // default input object
97 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
98 Eina_List *obj_mirror; // extra mirror objects
99 Eina_Tiler *updates; //render update regions
100 Eina_Tiler *pending_updates; //render update regions which are about to render
102 Evas_Native_Surface *ns; //for custom gl rendering
104 struct wl_listener buffer_destroy_listener;
106 unsigned int update_count; // how many updates have happened to this obj
108 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
110 unsigned int animating; // it's busy animating
111 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
112 unsigned int force_visible; //number of visible obj_mirror objects
113 Eina_Bool delete_pending : 1; // delete pending
114 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
115 Eina_Bool showing : 1; // object is currently in "show" animation
116 Eina_Bool hiding : 1; // object is currently in "hide" animation
117 Eina_Bool visible : 1; // is visible
119 Eina_Bool shaped : 1; // is shaped
120 Eina_Bool update : 1; // has updates to fetch
121 Eina_Bool redirected : 1; // has updates to fetch
122 Eina_Bool native : 1; // native
124 Eina_Bool nocomp : 1; // nocomp applied
125 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
126 Eina_Bool real_hid : 1; // last hide was a real window unmap
128 Eina_Bool effect_set : 1; //effect_obj has a valid group
129 Eina_Bool effect_running : 1; //effect_obj is playing an animation
130 Eina_Bool effect_clip : 1; //effect_obj is clipped
131 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
133 Eina_Bool updates_exist : 1;
134 Eina_Bool updates_full : 1; // entire object will be updated
136 Eina_Bool force_move : 1;
137 Eina_Bool frame_extends : 1; //frame may extend beyond object size
138 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
139 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
140 Eina_Bool user_alpha_set : 1;
141 Eina_Bool user_alpha : 1;
145 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
146 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
153 } indicator; //indicator object for internal client
157 Evas_Object *mask_obj;
160 int mask_x, mask_y, mask_w, mask_h;
163 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
165 tbm_surface_h tbm_surface;
166 E_Comp_Image_Filter image_filter;
167 Eina_Bool set_mouse_callbacks;
172 E_Comp_Wl_Buffer_Ref buffer_ref;
173 Eina_Bool pending_move_set;
174 int pending_move_x, pending_move_y;
175 Eina_Bool pending_resize_set;
176 int pending_resize_w, pending_resize_h;
177 } render_update_lock;
190 struct wl_signal lower;
191 struct wl_signal show;
192 struct wl_signal hide;
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))))
996 if (ec->netwm.state.modal)
998 if (!(((m->modal == -1) && (!modal)) ||
999 ((m->modal == 1) && (modal))))
1005 /* function for setting up a client's compositor frame theme (cw->shobj) */
1007 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1011 Eina_List *list = NULL, *l;
1012 E_Input_Rect_Data *input_rect_data;
1013 E_Input_Rect_Smart_Data *input_rect_sd;
1015 Eina_Stringshare *reshadow_group = NULL;
1016 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1017 Eina_Stringshare *name, *title;
1018 E_Comp_Config *conf = e_comp_config_get();
1020 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1021 /* match correct client type */
1022 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1023 name = cw->ec->icccm.name;
1024 title = cw->ec->icccm.title;
1025 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1026 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1028 /* skipping here is mostly a hack for systray because I hate it */
1031 EINA_LIST_FOREACH(list, l, m)
1033 if (((m->name) && (!name)) ||
1034 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1036 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1040 no_shadow = m->no_shadow;
1041 if (m->shadow_style)
1043 /* fast effects are just themes with "/fast" appended and shorter effect times */
1046 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1047 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1049 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1051 /* default to non-fast style if fast not available */
1054 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1055 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1057 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1059 if (ok && m->visibility_effect)
1060 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1067 if (skip || (cw->ec->e.state.video))
1069 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1071 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1074 if (conf->shadow_style)
1078 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1079 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1081 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1085 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1086 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1088 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1095 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1097 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1101 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1103 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1108 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1113 if (cw->ec->override)
1115 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1116 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1118 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1119 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1125 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1126 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1129 _e_comp_object_shadow(cw);
1132 if (focus || cw->ec->focused || cw->ec->override)
1133 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1135 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1136 if (urgent || cw->ec->urgent)
1137 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1139 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1141 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1143 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1144 /* visibility must always be enabled for re_manage clients to prevent
1145 * pop-in animations every time the user sees a persistent client again;
1146 * applying visibility for iconic clients prevents the client from getting
1149 if (cw->visible || cw->ec->re_manage)
1150 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1152 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1154 /* breaks animation counter */
1155 if (cw->frame_object)
1157 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1158 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1159 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1160 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1166 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1170 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1173 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1175 if (input_rect_data->obj)
1177 pass_event_flag = EINA_TRUE;
1183 if (cw->indicator.obj)
1185 Evas_Object *indicator;
1186 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1187 if (indicator != cw->indicator.obj)
1189 edje_object_part_unswallow(cw->shobj, indicator);
1190 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1191 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1195 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1196 evas_object_pass_events_set(cw->obj, pass_event_flag);
1201 /////////////////////////////////////////////
1204 _e_comp_object_animating_begin(E_Comp_Object *cw)
1207 if (cw->animating == 1)
1209 e_comp->animating++;
1211 e_object_ref(E_OBJECT(cw->ec));
1216 _e_comp_object_animating_end(E_Comp_Object *cw)
1225 if (cw->ec->launching)
1227 if (!cw->ec->extra_animating)
1229 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1230 cw->ec->launching = EINA_FALSE;
1231 if (cw->ec->first_mapped)
1233 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1234 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1237 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1241 e_comp->animating--;
1242 cw->showing = cw->hiding = 0;
1244 if (e_comp->animating == 0)
1245 e_comp_visibility_calculation_set(EINA_TRUE);
1246 /* remove ref from animation start, account for possibility of deletion from unref */
1247 return !!e_object_unref(E_OBJECT(cw->ec));
1253 /* handle the end of a compositor animation */
1255 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1257 E_Comp_Object *cw = data;
1259 /* visible clients which have never been sized are a bug */
1260 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1261 CRI("ACK! ec:%p", cw->ec);
1262 if (!_e_comp_object_animating_end(cw)) return;
1263 if (cw->animating) return;
1264 /* hide only after animation finishes to guarantee a full run of the animation */
1265 if (!cw->defer_hide) return;
1266 if ((!strcmp(emission, "e,action,hide,done")) ||
1267 (!strcmp(emission, "e,action,done")) ||
1268 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1270 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1271 evas_object_hide(cw->smart_obj);
1275 /* run a visibility compositor effect if available, return false if object is dead */
1277 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1283 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1284 if (!cw->effect_running)
1285 _e_comp_object_animating_begin(cw);
1286 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1287 return _e_comp_object_animating_end(cw);
1288 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1289 return _e_comp_object_animating_end(cw);
1291 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1294 zone = e_comp_zone_find_by_ec(cw->ec);
1296 zw = zone->w, zh = zone->h;
1301 zone = e_comp_object_util_zone_get(cw->smart_obj);
1302 if (!zone) zone = e_zone_current_get();
1309 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1310 cw->w, cw->h, zw, zh, x, y}, 8);
1311 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1312 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1315 /////////////////////////////////////////////
1317 /* create necessary objects for clients that e manages */
1319 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1321 if (cw->set_mouse_callbacks) return;
1322 if (!cw->smart_obj) return;
1324 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1325 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1326 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1327 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1328 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1329 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1331 cw->set_mouse_callbacks = EINA_TRUE;
1335 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1337 if (!cw->set_mouse_callbacks) return;
1338 if (!cw->smart_obj) return;
1340 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1341 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1342 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1343 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1344 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1345 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1347 cw->set_mouse_callbacks = EINA_FALSE;
1351 _e_comp_object_setup(E_Comp_Object *cw)
1353 cw->clip = evas_object_rectangle_add(e_comp->evas);
1354 evas_object_move(cw->clip, -9999, -9999);
1355 evas_object_resize(cw->clip, 999999, 999999);
1356 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1357 cw->effect_obj = edje_object_add(e_comp->evas);
1358 evas_object_move(cw->effect_obj, cw->x, cw->y);
1359 evas_object_clip_set(cw->effect_obj, cw->clip);
1360 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1361 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1362 cw->shobj = edje_object_add(e_comp->evas);
1363 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1364 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1365 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1367 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1368 if (cw->ec->override)
1370 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1371 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1372 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1374 else if (!cw->ec->input_only)
1376 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1377 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1378 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1380 cw->real_hid = !cw->ec->input_only;
1381 if (!cw->ec->input_only)
1383 e_util_size_debug_set(cw->effect_obj, 1);
1384 _e_comp_object_mouse_event_callback_set(cw);
1387 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1388 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1389 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1390 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1391 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1392 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1394 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1397 /////////////////////////////////////////////
1399 /* for fast path evas rendering; only called during render */
1401 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1403 E_Comp_Object *cw = data;
1404 E_Client *ec = cw->ec;
1406 int bx, by, bxx, byy;
1408 if (e_object_is_del(E_OBJECT(ec))) return;
1409 if (cw->external_content) return;
1410 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1411 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1414 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1415 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1417 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1419 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1420 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1424 bx = by = bxx = byy = 0;
1425 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1428 Edje_Message_Int_Set *msg;
1429 Edje_Message_Int msg2;
1430 Eina_Bool id = (bx || by || bxx || byy);
1432 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1438 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1440 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1444 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1445 e_comp_client_post_update_add(cw->ec);
1447 else if (e_comp_object_render(ec->frame))
1449 /* apply shape mask if necessary */
1450 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1451 e_comp_object_shape_apply(ec->frame);
1452 ec->shape_changed = 0;
1454 /* shaped clients get precise mouse events to handle transparent pixels */
1455 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1457 /* queue another render if client is still dirty; cannot refresh here. */
1458 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1459 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1461 if (cw->render_trace)
1463 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1469 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1471 E_Comp_Object *cw = data;
1472 E_Client *ec = cw->ec;
1474 if (e_object_is_del(E_OBJECT(ec))) return;
1475 if (cw->external_content) return;
1476 if (!e_comp->hwc) return;
1478 e_comp_client_render_list_add(cw->ec);
1480 if (!ec->hwc_window) return;
1482 e_hwc_windows_rendered_window_add(ec->hwc_window);
1485 /////////////////////////////////////////////
1488 _e_comp_object_client_pending_resize_add(E_Client *ec,
1491 unsigned int serial)
1493 E_Client_Pending_Resize *pnd;
1495 pnd = E_NEW(E_Client_Pending_Resize, 1);
1499 pnd->serial = serial;
1500 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1504 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1506 E_Comp_Object *cw = data;
1509 if (cw->render_update_lock.lock)
1511 cw->render_update_lock.pending_move_x = x;
1512 cw->render_update_lock.pending_move_y = y;
1513 cw->render_update_lock.pending_move_set = EINA_TRUE;
1517 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1518 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1519 (cw->external_content))
1521 /* delay to move until the external content is unset */
1522 cw->ec->changes.pos = 1;
1527 if (cw->ec->move_after_resize)
1529 if ((x != cw->ec->x) || (y != cw->ec->y))
1531 if (!cw->ec->is_cursor)
1532 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1533 e_client_pos_set(cw->ec, x, y);
1534 cw->ec->changes.pos = 1;
1540 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1541 (cw->ec->manage_resize.resize_obj))
1543 e_client_pos_set(cw->ec, x, y);
1544 cw->ec->client.x = x + cw->client_inset.l;
1545 cw->ec->client.y = y + cw->client_inset.t;
1546 e_policy_visibility_client_defer_move(cw->ec);
1550 /* if frame_object does not exist, client_inset indicates CSD.
1551 * this means that ec->client matches cw->x/y, the opposite
1554 fx = (!cw->frame_object) * cw->client_inset.l;
1555 fy = (!cw->frame_object) * cw->client_inset.t;
1556 if ((cw->x == x + fx) && (cw->y == y + fy))
1558 if ((cw->ec->x != x) || (cw->ec->y != y))
1560 /* handle case where client tries to move to position and back very quickly */
1561 e_client_pos_set(cw->ec, x, y);
1562 cw->ec->client.x = x + cw->client_inset.l;
1563 cw->ec->client.y = y + cw->client_inset.t;
1567 if (!cw->ec->maximize_override)
1569 /* prevent moving in some directions while directionally maximized */
1570 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1572 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1575 ix = x + cw->client_inset.l;
1576 iy = y + cw->client_inset.t;
1577 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1578 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1579 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1581 /* prevent moving at all if move isn't allowed in current maximize state */
1582 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1583 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1586 zone = e_comp_zone_find_by_ec(cw->ec);
1589 cw->ec->changes.need_unmaximize = 1;
1590 cw->ec->saved.x = ix - zone->x;
1591 cw->ec->saved.y = iy - zone->y;
1592 cw->ec->saved.w = cw->ec->client.w;
1593 cw->ec->saved.h = cw->ec->client.h;
1597 /* only update during resize if triggered by resize */
1598 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1599 /* delay to move while surface waits paired commit serial*/
1600 if (e_client_pending_geometry_has(cw->ec))
1602 /* do nothing while waiting paired commit serial*/
1606 e_client_pos_set(cw->ec, x, y);
1607 if (cw->ec->new_client)
1609 /* don't actually do anything until first client idler loop */
1610 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1611 cw->ec->changes.pos = 1;
1616 /* only update xy position of client to avoid invalid
1617 * first damage region if it is not a new_client. */
1618 cw->ec->client.x = ix;
1619 cw->ec->client.y = iy;
1622 if (!cw->frame_object)
1624 evas_object_move(obj, x, y);
1629 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1631 E_Comp_Object *cw = data;
1632 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1635 if (cw->render_update_lock.lock)
1637 cw->render_update_lock.pending_resize_w = w;
1638 cw->render_update_lock.pending_resize_h = h;
1639 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1643 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1645 e_client_size_set(cw->ec, w, h);
1646 evas_object_resize(obj, w, h);
1650 /* if frame_object does not exist, client_inset indicates CSD.
1651 * this means that ec->client matches cw->w/h, the opposite
1654 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1655 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1656 if ((cw->w == w + fw) && (cw->h == h + fh))
1658 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1659 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1660 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1662 /* handle case where client tries to resize itself and back very quickly */
1663 e_client_size_set(cw->ec, w, h);
1664 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1665 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1666 evas_object_smart_callback_call(obj, "client_resize", NULL);
1670 /* guarantee that fullscreen is fullscreen */
1671 zone = e_comp_zone_find_by_ec(cw->ec);
1673 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1675 if (!e_client_transform_core_enable_get(cw->ec))
1678 /* calculate client size */
1679 iw = w - cw->client_inset.l - cw->client_inset.r;
1680 ih = h - cw->client_inset.t - cw->client_inset.b;
1681 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1683 /* prevent resizing while maximized depending on direction and config */
1684 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1686 Eina_Bool reject = EINA_FALSE;
1687 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1689 if (cw->ec->client.h != ih)
1691 cw->ec->saved.h = ih;
1692 cw->ec->saved.y = cw->ec->client.y - zone->y;
1693 reject = cw->ec->changes.need_unmaximize = 1;
1696 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1698 if (cw->ec->client.w != iw)
1700 cw->ec->saved.w = iw;
1701 cw->ec->saved.x = cw->ec->client.x - zone->x;
1702 reject = cw->ec->changes.need_unmaximize = 1;
1711 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1713 /* do nothing until client idler loops */
1714 if ((cw->ec->w != w) || (cw->ec->h != h))
1716 e_client_size_set(cw->ec, w, h);
1717 cw->ec->changes.size = 1;
1722 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1723 ((cw->ec->w != w) || (cw->ec->h != h)))
1726 /* netwm sync resizes queue themselves and then trigger later on */
1727 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1729 if (e_client_pending_geometry_has(cw->ec))
1731 /* do nothing while waiting paired commit serial*/
1735 e_client_size_set(cw->ec, w, h);
1737 cw->ec->client.w = iw;
1738 cw->ec->client.h = ih;
1739 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1741 /* The size of non-compositing window can be changed, so there is a
1742 * need to check that cw is H/W composited if cw is not redirected.
1743 * And of course we have to change size of evas object of H/W composited cw,
1744 * otherwise cw can't receive input events even if it is shown on the screen.
1746 Eina_Bool redirected = cw->redirected;
1748 redirected = e_comp_is_on_overlay(cw->ec);
1750 if ((!cw->ec->input_only) && (redirected) &&
1751 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1752 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1753 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1754 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1757 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1758 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1760 prev_w = cw->w, prev_h = cw->h;
1761 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1762 /* check shading and clamp to pixmap size for regular clients */
1763 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1764 (((w - fw != pw) || (h - fh != ph))))
1766 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1767 evas_object_smart_callback_call(obj, "client_resize", NULL);
1769 if (cw->frame_object || cw->ec->input_only)
1770 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1773 if ((cw->w == w) && (cw->h == h))
1775 /* going to be a noop resize which won't trigger smart resize */
1776 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1777 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1779 evas_object_resize(obj, w, h);
1783 evas_object_smart_callback_call(obj, "client_resize", NULL);
1786 if ((!cw->frame_object) && (!cw->ec->input_only))
1788 /* "just do it" for overrides */
1789 evas_object_resize(obj, w, h);
1791 if (!cw->ec->override)
1793 /* shape probably changed for non-overrides */
1794 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1795 cw->ec->need_shape_export |= cw->ec->shaped;
1796 if (cw->ec->shaped || cw->ec->shaped_input)
1800 /* this fixes positioning jiggles when using a resize mode
1801 * which also changes the client's position
1804 if (cw->frame_object)
1805 x = cw->x, y = cw->y;
1807 x = cw->ec->x, y = cw->ec->y;
1808 switch (cw->ec->resize_mode)
1810 case E_POINTER_RESIZE_BL:
1811 case E_POINTER_RESIZE_L:
1812 evas_object_move(obj, x + prev_w - cw->w, y);
1814 case E_POINTER_RESIZE_TL:
1815 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1817 case E_POINTER_RESIZE_T:
1818 case E_POINTER_RESIZE_TR:
1819 evas_object_move(obj, x, y + prev_h - cw->h);
1828 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1830 E_Comp_Object *cw = data;
1831 E_Comp_Wl_Client_Data *child_cdata;
1832 unsigned int l = e_comp_canvas_layer_map(layer);
1835 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1837 /* doing a compositor effect, follow directions */
1838 _e_comp_object_layer_set(obj, layer);
1839 if (layer == cw->ec->layer) //trying to put layer back
1843 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1844 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1845 if (cw->layer != l) goto layer_set;
1849 e_comp_render_queue();
1851 ec = e_client_above_get(cw->ec);
1852 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1853 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1854 ec = e_client_above_get(ec);
1855 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1857 ec = e_client_below_get(cw->ec);
1858 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1859 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1860 ec = e_client_below_get(ec);
1861 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1863 evas_object_stack_above(obj, ec->frame);
1868 if (ec && (cw->ec->parent == ec))
1870 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1871 evas_object_stack_above(obj, ec->frame);
1873 evas_object_stack_below(obj, ec->frame);
1876 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1882 if (cw->layer == l) return;
1883 if (e_comp_canvas_client_layer_map(layer) == 9999)
1884 return; //invalid layer for clients not doing comp effects
1885 if (cw->ec->fullscreen)
1887 cw->ec->saved.layer = layer;
1890 oldraise = e_config->transient.raise;
1892 /* clamp to valid client layer */
1893 layer = e_comp_canvas_client_layer_map_nearest(layer);
1894 cw->ec->layer = layer;
1895 if (e_config->transient.layer)
1898 Eina_List *list = eina_list_clone(cw->ec->transients);
1900 /* We need to set raise to one, else the child wont
1901 * follow to the new layer. It should be like this,
1902 * even if the user usually doesn't want to raise
1905 e_config->transient.raise = 1;
1906 EINA_LIST_FREE(list, child)
1908 child_cdata = e_client_cdata_get(child);
1909 if (child_cdata && !child_cdata->mapped)
1911 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1914 e_client_layer_set(child, layer);
1918 e_config->transient.raise = oldraise;
1920 _e_comp_object_layers_remove(cw);
1921 cw->layer = e_comp_canvas_layer_map(layer);
1922 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1923 //if (cw->ec->new_client)
1924 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1925 _e_comp_object_layer_set(obj, layer);
1926 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1927 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1928 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1930 /* can't stack a client above its own layer marker */
1931 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1933 if (!cw->visible) return;
1934 e_comp_render_queue();
1935 _e_comp_object_transform_obj_stack_update(obj);
1938 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1941 _e_comp_object_raise(Evas_Object *obj)
1943 evas_object_raise(obj);
1945 if (evas_object_smart_smart_get(obj))
1947 E_Client *ec = e_comp_object_client_get(obj);
1949 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1954 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1956 evas_object_lower(obj);
1958 if (evas_object_smart_smart_get(obj))
1960 E_Client *ec = e_comp_object_client_get(obj);
1963 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1964 wl_signal_emit_mutable(&cw->events.lower, NULL);
1970 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1972 evas_object_stack_above(obj, target);
1974 if (evas_object_smart_smart_get(obj))
1976 E_Client *ec = e_comp_object_client_get(obj);
1978 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1983 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1985 evas_object_stack_below(obj, target);
1987 if (evas_object_smart_smart_get(obj))
1989 E_Client *ec = e_comp_object_client_get(obj);
1991 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1996 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1998 evas_object_layer_set(obj, layer);
2000 if (evas_object_smart_smart_get(obj))
2002 E_Client *ec = e_comp_object_client_get(obj);
2004 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2009 _e_comp_object_is_pending(E_Client *ec)
2013 if (!ec) return EINA_FALSE;
2015 topmost = e_comp_wl_topmost_parent_get(ec);
2017 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2021 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2023 E_Comp_Object *cw2 = NULL;
2026 Evas_Object *o = stack;
2027 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2029 /* We should consider topmost's layer_pending for subsurface */
2030 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2032 if (_e_comp_object_is_pending(cw->ec))
2033 e_comp_object_layer_update(cw->smart_obj,
2034 raising? stack : NULL,
2035 raising? NULL : stack);
2037 /* obey compositor effects! */
2038 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2039 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2040 stack_cb(cw->smart_obj, stack);
2041 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2042 evas_object_data_del(cw->smart_obj, "client_restack");
2046 cw2 = evas_object_data_get(o, "comp_obj");
2048 /* assume someone knew what they were doing during client init */
2049 if (cw->ec->new_client)
2050 layer = cw->ec->layer;
2051 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2052 layer = cw2->ec->layer;
2054 layer = evas_object_layer_get(stack);
2055 ecstack = e_client_below_get(cw->ec);
2056 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2058 evas_object_layer_set(cw->smart_obj, layer);
2059 /* we got our layer wrangled, return now! */
2060 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2063 /* check if we're stacking below another client */
2066 /* check for non-client layer object */
2067 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2069 /* find an existing client to use for layering
2070 * by walking up the object stack
2072 * this is guaranteed to be pretty quick since we'll either:
2073 * - run out of client layers
2074 * - find a stacking client
2076 o = evas_object_above_get(o);
2077 if ((!o) || (o == cw->smart_obj)) break;
2078 if (evas_object_layer_get(o) != layer)
2080 /* reached the top client layer somehow
2081 * use top client object
2083 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2086 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2087 * return here since the top client layer window
2092 ec = e_client_top_get();
2097 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2100 if (cw2 && cw->layer != cw2->layer)
2103 /* remove existing layers */
2104 _e_comp_object_layers_remove(cw);
2107 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2108 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2109 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2110 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2111 else //if no stacking objects found, either raise or lower
2112 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2115 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2117 /* find new object for stacking if cw2 is on state of layer_pending */
2118 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2120 E_Client *new_stack = NULL, *current_ec = NULL;
2121 current_ec = cw2->ec;
2124 while ((new_stack = e_client_below_get(current_ec)))
2126 current_ec = new_stack;
2127 if (new_stack == cw->ec) continue;
2128 if (new_stack->layer != cw2->ec->layer) break;
2129 if (!_e_comp_object_is_pending(new_stack)) break;
2131 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2132 stack = new_stack->frame;
2135 /* stack it above layer object */
2137 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2138 stack = e_comp->layers[below_layer].obj;
2143 while ((new_stack = e_client_above_get(current_ec)))
2145 current_ec = new_stack;
2146 if (new_stack == cw->ec) continue;
2147 if (new_stack->layer != cw2->ec->layer) break;
2148 if (!_e_comp_object_is_pending(new_stack)) break;
2150 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2151 stack = new_stack->frame;
2153 stack = e_comp->layers[cw2->layer].obj;
2157 /* set restack if stacking has changed */
2158 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2159 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2160 stack_cb(cw->smart_obj, stack);
2161 if (e_comp->layers[cw->layer].obj)
2162 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2164 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2166 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2167 evas_object_data_del(cw->smart_obj, "client_restack");
2168 if (!cw->visible) return;
2169 e_comp_render_queue();
2173 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2175 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2177 if (evas_object_below_get(obj) == above)
2179 e_comp_object_layer_update(obj, above, NULL);
2183 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2184 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2185 _e_comp_object_transform_obj_stack_update(obj);
2186 _e_comp_object_transform_obj_stack_update(above);
2191 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2193 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2194 if (evas_object_above_get(obj) == below)
2196 e_comp_object_layer_update(obj, NULL, below);
2200 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2201 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2202 if (evas_object_smart_smart_get(obj))
2203 _e_comp_object_transform_obj_stack_update(obj);
2204 if (evas_object_smart_smart_get(below))
2205 _e_comp_object_transform_obj_stack_update(below);
2210 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2212 E_Comp_Object *cw = data;
2215 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2217 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2219 if (cw->ec->layer_pending)
2220 e_comp_object_layer_update(obj, NULL, obj);
2222 _e_comp_object_lower(cw, obj);
2225 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2226 o = evas_object_below_get(obj);
2227 _e_comp_object_layers_remove(cw);
2228 /* prepend to client list since this client should be the first item now */
2229 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2230 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2231 evas_object_data_set(obj, "client_restack", (void*)1);
2232 _e_comp_object_lower(cw, obj);
2233 evas_object_data_del(obj, "client_restack");
2234 if (!cw->visible) goto end;
2235 e_comp_render_queue();
2236 _e_comp_object_transform_obj_stack_update(obj);
2243 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2245 E_Comp_Object *cw = data;
2249 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2251 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2253 if (cw->ec->layer_pending)
2255 int obj_layer = evas_object_layer_get(obj);
2256 if (cw->ec->layer != obj_layer)
2257 e_comp_object_layer_update(obj, NULL, NULL);
2260 _e_comp_object_raise(obj);
2263 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2264 o = evas_object_above_get(obj);
2265 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2267 /* still stack below override below the layer marker */
2268 for (op = o = e_comp->layers[cw->layer].obj;
2269 o && o != e_comp->layers[cw->layer - 1].obj;
2270 op = o, o = evas_object_below_get(o))
2272 if (evas_object_smart_smart_get(o))
2276 ec = e_comp_object_client_get(o);
2277 if (ec && (!ec->override)) break;
2280 _e_comp_object_stack_below(obj, op);
2281 e_client_focus_defer_set(cw->ec);
2283 if (!cw->visible) goto end;
2284 e_comp_render_queue();
2285 _e_comp_object_transform_obj_stack_update(obj);
2292 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2294 E_Comp_Object *cw = data;
2296 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2297 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2299 ELOGF("COMP", "Hide. intercepted", cw->ec);
2304 if (cw->ec->launching == EINA_TRUE)
2306 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2307 cw->ec->launching = EINA_FALSE;
2312 /* hidden flag = just do it */
2313 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2314 evas_object_hide(obj);
2316 wl_signal_emit_mutable(&cw->events.hide, NULL);
2321 if (cw->ec->input_only)
2323 /* input_only = who cares */
2324 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2325 evas_object_hide(obj);
2327 wl_signal_emit_mutable(&cw->events.hide, NULL);
2331 /* already hidden or currently animating */
2332 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2334 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2338 /* don't try hiding during shutdown */
2339 cw->defer_hide |= stopping;
2340 if (!cw->defer_hide)
2342 if ((!cw->ec->iconic) && (!cw->ec->override))
2343 /* unset delete requested so the client doesn't break */
2344 cw->ec->delete_requested = 0;
2345 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2347 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2348 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2351 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2354 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2356 _e_comp_object_animating_begin(cw);
2357 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2359 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2360 cw->defer_hide = !!cw->animating;
2362 e_comp_object_effect_set(obj, NULL);
2365 if (cw->animating) return;
2366 /* if we have no animations running, go ahead and hide */
2368 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2369 evas_object_hide(obj);
2371 wl_signal_emit_mutable(&cw->events.hide, NULL);
2375 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2377 E_Client *ec = cw->ec;
2380 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2382 if (ec->show_pending.count > 0)
2384 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2385 ec->show_pending.running = EINA_TRUE;
2389 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2390 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2392 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2397 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,
2398 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2399 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2402 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2405 if (ec->iconic && cw->animating)
2407 /* triggered during iconify animation */
2408 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2411 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2414 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2415 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2417 evas_object_move(cw->smart_obj, ec->x, ec->y);
2418 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2419 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2421 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2422 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2425 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2426 evas_object_show(cw->smart_obj);
2429 e_client_focus_defer_set(ec);
2433 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2437 pw = ec->client.w, ph = ec->client.h;
2439 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2441 ec->changes.visible = !ec->hidden;
2444 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2448 cw->updates = eina_tiler_new(pw, ph);
2451 ec->changes.visible = !ec->hidden;
2454 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2459 eina_tiler_tile_size_set(cw->updates, 1, 1);
2462 /* ignore until client idler first run */
2463 ec->changes.visible = !ec->hidden;
2466 ELOGF("COMP", "show_helper. return. new_client", ec);
2473 evas_object_move(cw->smart_obj, ec->x, ec->y);
2474 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2475 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2476 evas_object_show(cw->smart_obj);
2479 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2481 /* start_drag not received */
2482 ec->changes.visible = 1;
2485 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2488 /* re-set geometry */
2489 evas_object_move(cw->smart_obj, ec->x, ec->y);
2490 /* force resize in case it hasn't happened yet, or just to update size */
2491 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2492 if ((cw->w < 1) || (cw->h < 1))
2494 /* if resize didn't go through, try again */
2495 ec->visible = ec->changes.visible = 1;
2497 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2500 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2501 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2502 e_pixmap_clear(ec->pixmap);
2504 if (cw->real_hid && w && h)
2507 /* force comp theming in case it didn't happen already */
2508 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2509 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2510 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2513 /* only do the show if show is allowed */
2516 if (ec->internal) //internal clients render when they feel like it
2517 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2519 if (!e_client_is_iconified_by_client(ec)||
2520 e_policy_visibility_client_is_uniconic(ec))
2522 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2523 evas_object_show(cw->smart_obj);
2525 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2526 it is rendered in idle callback without native surface and
2527 compositor shows an empty frame if other objects aren't shown
2528 because job callback of e_comp called at the next loop.
2529 it causes a visual defect when windows are switched.
2533 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2534 e_comp_object_dirty(cw->smart_obj);
2535 e_comp_object_render(cw->smart_obj);
2540 wl_signal_emit_mutable(&cw->events.show, NULL);
2544 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2546 E_Comp_Object *cw = data;
2547 E_Client *ec = cw->ec;
2549 E_Input_Rect_Data *input_rect_data;
2550 E_Input_Rect_Smart_Data *input_rect_sd;
2553 if (ec->ignored) return;
2557 //INF("SHOW2 %p", ec);
2558 _e_comp_intercept_show_helper(cw);
2561 //INF("SHOW %p", ec);
2564 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2565 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2566 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2567 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2571 if ((!cw->obj) && (cw->external_content))
2573 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2577 _e_comp_object_setup(cw);
2580 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2581 cw->obj = evas_object_image_filled_add(e_comp->evas);
2582 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2583 e_util_size_debug_set(cw->obj, 1);
2584 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2585 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2586 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2587 evas_object_name_set(cw->obj, "cw->obj");
2588 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2590 _e_comp_object_alpha_set(cw);
2593 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2596 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2597 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2600 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2603 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2605 if (input_rect_data->obj)
2607 evas_object_geometry_set(input_rect_data->obj,
2608 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2609 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2610 input_rect_data->rect.w, input_rect_data->rect.h);
2617 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2619 _e_comp_intercept_show_helper(cw);
2623 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2625 E_Comp_Object *cw = data;
2629 /* note: this is here as it seems there are enough apps that do not even
2630 * expect us to emulate a look of focus but not actually set x input
2631 * focus as we do - so simply abort any focus set on such windows */
2632 /* be strict about accepting focus hint */
2633 /* be strict about accepting focus hint */
2634 if ((!ec->icccm.accepts_focus) &&
2635 (!ec->icccm.take_focus))
2639 if (e_client_focused_get() == ec)
2640 e_client_focused_set(NULL);
2642 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2643 evas_object_focus_set(obj, focus);
2647 if (focus && ec->lock_focus_out) return;
2648 if (e_object_is_del(E_OBJECT(ec)) && focus)
2649 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2651 /* filter focus setting based on current state */
2656 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2657 evas_object_focus_set(obj, focus);
2660 if ((ec->iconic) && (!ec->deskshow))
2662 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2664 /* don't focus an iconified window. that's silly! */
2665 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2666 e_client_uniconify(ec);
2667 e_client_focus_latest_set(ec);
2681 /* not yet visible, wait till the next time... */
2682 ec->want_focus = !ec->hidden;
2687 e_client_focused_set(ec);
2691 if (e_client_focused_get() == ec)
2692 e_client_focused_set(NULL);
2696 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2698 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2700 evas_object_focus_set(obj, focus);
2704 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2706 E_Comp_Object *cw = data;
2708 if (cw->transparent.set)
2710 cw->transparent.user_r = r;
2711 cw->transparent.user_g = g;
2712 cw->transparent.user_b = b;
2713 cw->transparent.user_a = a;
2715 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2717 cw->transparent.user_r,
2718 cw->transparent.user_g,
2719 cw->transparent.user_b,
2720 cw->transparent.user_a);
2724 evas_object_color_set(obj, r, g, b, a);
2727 ////////////////////////////////////////////////////
2730 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2732 int w, h, ox, oy, ow, oh;
2734 Eina_Bool pass_event_flag = EINA_FALSE;
2735 E_Input_Rect_Data *input_rect_data;
2736 E_Input_Rect_Smart_Data *input_rect_sd;
2738 if (cw->frame_object)
2740 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2741 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2742 /* set a fixed size, force edje calc, check size difference */
2743 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2744 edje_object_message_signal_process(cw->frame_object);
2745 edje_object_calc_force(cw->frame_object);
2746 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2747 cw->client_inset.l = ox;
2748 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2749 cw->client_inset.t = oy;
2750 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2751 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2752 evas_object_resize(cw->frame_object, w, h);
2756 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2759 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2761 if (input_rect_data->obj)
2763 pass_event_flag = EINA_TRUE;
2769 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2770 evas_object_pass_events_set(cw->obj, pass_event_flag);
2774 cw->client_inset.l = 0;
2775 cw->client_inset.r = 0;
2776 cw->client_inset.t = 0;
2777 cw->client_inset.b = 0;
2779 cw->client_inset.calc = !!cw->frame_object;
2783 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2785 E_Comp_Object *cw = data;
2789 /* - get current size
2791 * - readjust for new frame size
2794 w = cw->ec->w, h = cw->ec->h;
2795 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2797 _e_comp_object_frame_recalc(cw);
2799 if (!cw->ec->fullscreen)
2800 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2802 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2803 if (cw->ec->fullscreen)
2805 zone = e_comp_zone_find_by_ec(cw->ec);
2807 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2809 else if (cw->ec->new_client)
2811 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2812 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2813 evas_object_resize(cw->ec->frame, w, h);
2815 else if ((w != cw->ec->w) || (h != cw->ec->h))
2816 evas_object_resize(cw->ec->frame, w, h);
2820 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2822 E_Comp_Object *cw = data;
2824 if (!cw->ec) return; //NYI
2825 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2827 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2831 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2833 E_Comp_Object *cw = data;
2835 if (!cw->ec) return; //NYI
2836 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2838 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2842 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2844 E_Comp_Object *cw = data;
2846 _e_comp_object_shadow_setup(cw);
2847 if (cw->frame_object)
2849 _e_comp_object_shadow(cw);
2850 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2851 _e_comp_object_frame_recalc(cw);
2852 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2857 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2859 E_Comp_Object *cw = data;
2861 if (_e_comp_object_shadow_setup(cw))
2862 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2863 if (cw->frame_object)
2865 _e_comp_object_shadow(cw);
2866 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2867 _e_comp_object_frame_recalc(cw);
2868 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2873 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2875 E_Comp_Object *cw = data;
2877 if (cw->frame_object)
2879 _e_comp_object_shadow(cw);
2880 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2881 _e_comp_object_frame_recalc(cw);
2882 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2887 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2889 E_Comp_Object *cw = data;
2891 if (_e_comp_object_shadow_setup(cw))
2894 cw->ec->changes.size = 1;
2896 if (cw->frame_object)
2898 _e_comp_object_shadow(cw);
2899 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2900 _e_comp_object_frame_recalc(cw);
2901 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2906 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2908 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2912 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2914 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2918 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2920 E_Comp_Object *cw = data;
2922 if (!cw->ec) return; //NYI
2923 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2927 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2929 E_Comp_Object *cw = data;
2931 if (!cw->ec) return; //NYI
2932 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2936 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2938 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2942 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2944 E_Comp_Object *cw = data;
2946 if (!e_object_is_del(E_OBJECT(cw->ec)))
2947 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2951 _e_comp_input_obj_smart_add(Evas_Object *obj)
2953 E_Input_Rect_Smart_Data *input_rect_sd;
2954 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2956 if (!input_rect_sd) return;
2957 evas_object_smart_data_set(obj, input_rect_sd);
2961 _e_comp_input_obj_smart_del(Evas_Object *obj)
2963 E_Input_Rect_Smart_Data *input_rect_sd;
2964 E_Input_Rect_Data *input_rect_data;
2966 input_rect_sd = evas_object_smart_data_get(obj);
2967 if (!input_rect_sd) return;
2969 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2971 if (input_rect_data->obj)
2973 evas_object_smart_member_del(input_rect_data->obj);
2974 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2976 E_FREE(input_rect_data);
2978 E_FREE(input_rect_sd);
2982 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2984 E_Input_Rect_Smart_Data *input_rect_sd;
2985 E_Input_Rect_Data *input_rect_data;
2989 input_rect_sd = evas_object_smart_data_get(obj);
2990 if (!input_rect_sd) return;
2992 cw = input_rect_sd->cw;
2993 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2995 if (input_rect_data->obj)
2997 evas_object_geometry_set(input_rect_data->obj,
2998 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2999 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3000 input_rect_data->rect.w, input_rect_data->rect.h);
3006 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3008 E_Input_Rect_Smart_Data *input_rect_sd;
3009 E_Input_Rect_Data *input_rect_data;
3013 input_rect_sd = evas_object_smart_data_get(obj);
3014 if (!input_rect_sd) return;
3016 cw = input_rect_sd->cw;
3017 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3019 if (input_rect_data->obj)
3021 evas_object_geometry_set(input_rect_data->obj,
3022 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3023 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3024 input_rect_data->rect.w, input_rect_data->rect.h);
3030 _e_comp_input_obj_smart_show(Evas_Object *obj)
3032 E_Input_Rect_Smart_Data *input_rect_sd;
3033 E_Input_Rect_Data *input_rect_data;
3036 input_rect_sd = evas_object_smart_data_get(obj);
3037 if (!input_rect_sd) return;
3039 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3041 if (input_rect_data->obj)
3043 evas_object_show(input_rect_data->obj);
3049 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3051 E_Input_Rect_Smart_Data *input_rect_sd;
3052 E_Input_Rect_Data *input_rect_data;
3055 input_rect_sd = evas_object_smart_data_get(obj);
3056 if (!input_rect_sd) return;
3058 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3060 if (input_rect_data->obj)
3062 evas_object_hide(input_rect_data->obj);
3068 _e_comp_input_obj_smart_init(void)
3070 if (_e_comp_input_obj_smart) return;
3072 static const Evas_Smart_Class sc =
3074 INPUT_OBJ_SMART_NAME,
3075 EVAS_SMART_CLASS_VERSION,
3076 _e_comp_input_obj_smart_add,
3077 _e_comp_input_obj_smart_del,
3078 _e_comp_input_obj_smart_move,
3079 _e_comp_input_obj_smart_resize,
3080 _e_comp_input_obj_smart_show,
3081 _e_comp_input_obj_smart_hide,
3094 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3100 _e_comp_smart_add(Evas_Object *obj)
3104 cw = E_NEW(E_Comp_Object, 1);
3105 EINA_SAFETY_ON_NULL_RETURN(cw);
3107 wl_signal_init(&cw->events.lower);
3108 wl_signal_init(&cw->events.show);
3109 wl_signal_init(&cw->events.hide);
3111 cw->smart_obj = obj;
3112 cw->x = cw->y = cw->w = cw->h = -1;
3113 evas_object_smart_data_set(obj, cw);
3114 cw->opacity = 255.0;
3115 cw->external_content = 0;
3116 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3117 cw->transform_bg_color.r = 0;
3118 cw->transform_bg_color.g = 0;
3119 cw->transform_bg_color.b = 0;
3120 cw->transform_bg_color.a = 255;
3121 evas_object_data_set(obj, "comp_obj", cw);
3122 evas_object_move(obj, -1, -1);
3123 /* intercept ALL the callbacks! */
3124 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3125 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3126 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3127 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3128 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3129 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3130 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3131 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3132 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3133 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3134 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3136 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3137 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3139 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3140 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3141 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3142 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3144 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3145 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3147 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3148 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3150 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3152 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3153 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3157 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3160 evas_object_color_set(cw->clip, r, g, b, a);
3161 evas_object_smart_callback_call(obj, "color_set", NULL);
3166 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3169 evas_object_clip_set(cw->clip, clip);
3173 _e_comp_smart_clip_unset(Evas_Object *obj)
3176 evas_object_clip_unset(cw->clip);
3180 _e_comp_smart_hide(Evas_Object *obj)
3182 TRACE_DS_BEGIN(COMP:SMART HIDE);
3187 evas_object_hide(cw->clip);
3188 if (cw->input_obj) evas_object_hide(cw->input_obj);
3189 evas_object_hide(cw->effect_obj);
3190 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3191 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3192 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3199 /* unset native surface if current displaying buffer was destroied */
3200 if (!cw->buffer_destroy_listener.notify)
3202 Evas_Native_Surface *ns;
3203 ns = evas_object_image_native_surface_get(cw->obj);
3204 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3205 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3208 if (!cw->ec->input_only)
3210 edje_object_freeze(cw->effect_obj);
3211 edje_object_freeze(cw->shobj);
3212 edje_object_play_set(cw->shobj, 0);
3213 if (cw->frame_object)
3214 edje_object_play_set(cw->frame_object, 0);
3217 e_comp_render_queue(); //force nocomp recheck
3223 _e_comp_smart_show(Evas_Object *obj)
3231 if ((cw->w < 0) || (cw->h < 0))
3232 CRI("ACK! ec:%p", cw->ec);
3234 TRACE_DS_BEGIN(COMP:SMART SHOW);
3236 e_comp_object_map_update(obj);
3238 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3239 evas_object_show(tmp->frame);
3241 evas_object_show(cw->clip);
3242 if (cw->input_obj) evas_object_show(cw->input_obj);
3243 if (!cw->ec->input_only)
3245 edje_object_thaw(cw->effect_obj);
3246 edje_object_thaw(cw->shobj);
3247 edje_object_play_set(cw->shobj, 1);
3248 if (cw->frame_object)
3249 edje_object_play_set(cw->frame_object, 1);
3251 evas_object_show(cw->effect_obj);
3252 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3253 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3254 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3255 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3256 e_comp_render_queue();
3257 if (cw->ec->input_only)
3262 if (cw->ec->iconic && (!cw->ec->new_client))
3264 if (e_client_is_iconified_by_client(cw->ec))
3266 ELOGF("COMP", "Set launching flag..", cw->ec);
3267 cw->ec->launching = EINA_TRUE;
3270 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3272 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3275 ELOGF("COMP", "Set launching flag..", cw->ec);
3276 cw->ec->launching = EINA_TRUE;
3278 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3279 _e_comp_object_animating_begin(cw);
3280 if (!_e_comp_object_effect_visibility_start(cw, 1))
3286 /* ensure some random effect doesn't lock the client offscreen */
3290 e_comp_object_effect_set(obj, NULL);
3293 _e_comp_object_dim_update(cw);
3299 _e_comp_smart_del(Evas_Object *obj)
3305 if (cw->buffer_destroy_listener.notify)
3307 wl_list_remove(&cw->buffer_destroy_listener.link);
3308 cw->buffer_destroy_listener.notify = NULL;
3311 if (cw->tbm_surface)
3313 tbm_surface_internal_unref(cw->tbm_surface);
3314 cw->tbm_surface = NULL;
3317 if (cw->render_update_lock.buffer_ref.buffer)
3319 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3320 cw->ec, cw->render_update_lock.lock);
3321 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3324 e_comp_object_render_update_del(cw->smart_obj);
3325 E_FREE_FUNC(cw->updates, eina_tiler_free);
3326 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3333 EINA_LIST_FREE(cw->obj_mirror, o)
3335 evas_object_image_data_set(o, NULL);
3336 evas_object_freeze_events_set(o, 1);
3337 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3341 _e_comp_object_layers_remove(cw);
3342 l = evas_object_data_get(obj, "comp_object-to_del");
3343 E_FREE_LIST(l, evas_object_del);
3344 _e_comp_object_mouse_event_callback_unset(cw);
3345 evas_object_del(cw->clip);
3346 evas_object_del(cw->obj);
3347 evas_object_del(cw->shobj);
3348 evas_object_del(cw->effect_obj);
3349 evas_object_del(cw->frame_object);
3350 evas_object_del(cw->input_obj);
3351 evas_object_del(cw->mask.obj);
3352 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3353 evas_object_del(cw->transform_bg_obj);
3354 evas_object_del(cw->transform_tranp_obj);
3355 evas_object_del(cw->default_input_obj);
3356 eina_stringshare_del(cw->frame_theme);
3357 eina_stringshare_del(cw->frame_name);
3361 e_comp->animating--;
3363 e_object_unref(E_OBJECT(cw->ec));
3365 cw->ec->frame = NULL;
3370 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3374 cw->x = x, cw->y = y;
3375 evas_object_move(cw->effect_obj, x, y);
3376 evas_object_move(cw->default_input_obj, x, y);
3377 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3379 e_comp_object_map_update(obj);
3383 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3385 Eina_Bool first = EINA_FALSE;
3390 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3392 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3394 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3396 if (cw->w != w || cw->h != h)
3397 e_comp_object_map_update(obj);
3399 first = ((cw->w < 1) || (cw->h < 1));
3400 cw->w = w, cw->h = h;
3404 if (cw->frame_object)
3405 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3408 /* verify pixmap:object size */
3409 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3411 if ((ww != pw) || (hh != ph))
3412 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3414 evas_object_resize(cw->effect_obj, tw, th);
3415 evas_object_resize(cw->default_input_obj, w, h);
3417 evas_object_resize(cw->input_obj, w, h);
3419 evas_object_resize(cw->mask.obj, w, h);
3420 /* resize render update tiler */
3423 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3424 cw->updates_full = 0;
3425 if (cw->updates) eina_tiler_clear(cw->updates);
3429 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3430 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3438 e_comp_render_queue();
3444 _e_comp_smart_init(void)
3446 if (_e_comp_smart) return;
3448 static const Evas_Smart_Class sc =
3451 EVAS_SMART_CLASS_VERSION,
3455 _e_comp_smart_resize,
3458 _e_comp_smart_color_set,
3459 _e_comp_smart_clip_set,
3460 _e_comp_smart_clip_unset,
3470 _e_comp_smart = evas_smart_class_new(&sc);
3475 e_comp_object_init(void)
3477 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3478 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3479 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3480 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3484 e_comp_object_shutdown(void)
3490 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3492 API_ENTRY EINA_FALSE;
3493 return !!cw->force_visible;
3495 /////////////////////////////////////////////////////////
3498 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3501 Eina_Bool comp_object;
3503 comp_object = !!evas_object_data_get(obj, "comp_object");
3508 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3510 e_comp_render_queue();
3512 l = evas_object_data_get(obj, "comp_object-to_del");
3513 E_FREE_LIST(l, evas_object_del);
3517 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3519 if (e_comp_util_object_is_above_nocomp(obj) &&
3520 (!evas_object_data_get(obj, "comp_override")))
3522 evas_object_data_set(obj, "comp_override", (void*)1);
3523 e_comp_override_add();
3528 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3530 Eina_Bool ref = EINA_TRUE;
3531 if (evas_object_visible_get(obj))
3535 d = evas_object_data_del(obj, "comp_hiding");
3537 /* currently trying to hide */
3540 /* already visible */
3544 evas_object_show(obj);
3547 evas_object_ref(obj);
3548 evas_object_data_set(obj, "comp_ref", (void*)1);
3550 edje_object_signal_emit(obj, "e,state,visible", "e");
3551 evas_object_data_set(obj, "comp_showing", (void*)1);
3552 if (e_comp_util_object_is_above_nocomp(obj))
3554 evas_object_data_set(obj, "comp_override", (void*)1);
3555 e_comp_override_add();
3560 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3562 if (!evas_object_visible_get(obj)) return;
3563 /* already hiding */
3564 if (evas_object_data_get(obj, "comp_hiding")) return;
3565 if (!evas_object_data_del(obj, "comp_showing"))
3567 evas_object_ref(obj);
3568 evas_object_data_set(obj, "comp_ref", (void*)1);
3570 edje_object_signal_emit(obj, "e,state,hidden", "e");
3571 evas_object_data_set(obj, "comp_hiding", (void*)1);
3573 if (evas_object_data_del(obj, "comp_override"))
3574 e_comp_override_timed_pop();
3578 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3580 if (!e_util_strcmp(emission, "e,action,hide,done"))
3582 if (!evas_object_data_del(obj, "comp_hiding")) return;
3583 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3584 evas_object_hide(obj);
3585 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3588 evas_object_data_del(obj, "comp_showing");
3589 if (evas_object_data_del(obj, "comp_ref"))
3590 evas_object_unref(obj);
3594 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3600 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3604 E_API E_Comp_Object_Hook *
3605 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3607 E_Comp_Object_Hook *ch;
3609 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3610 ch = E_NEW(E_Comp_Object_Hook, 1);
3611 if (!ch) return NULL;
3612 ch->hookpoint = hookpoint;
3614 ch->data = (void*)data;
3615 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3620 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3623 if (_e_comp_object_hooks_walking == 0)
3625 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3629 _e_comp_object_hooks_delete++;
3632 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3633 E_API E_Comp_Object_Intercept_Hook *
3634 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3636 E_Comp_Object_Intercept_Hook *ch;
3638 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3639 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3640 if (!ch) return NULL;
3641 ch->hookpoint = hookpoint;
3643 ch->data = (void*)data;
3644 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3649 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3652 if (_e_comp_object_intercept_hooks_walking == 0)
3654 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3658 _e_comp_object_intercept_hooks_delete++;
3663 e_comp_object_util_add(Evas_Object *obj)
3667 E_Comp_Config *conf = e_comp_config_get();
3668 Eina_Bool skip = EINA_FALSE;
3674 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3676 name = evas_object_name_get(obj);
3677 vis = evas_object_visible_get(obj);
3678 o = edje_object_add(e_comp->evas);
3679 evas_object_data_set(o, "comp_object", (void*)1);
3681 skip = (!strncmp(name, "noshadow", 8));
3683 evas_object_data_set(o, "comp_object_skip", (void*)1);
3685 if (conf->shadow_style)
3687 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3688 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3691 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3692 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3693 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3695 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3697 evas_object_geometry_get(obj, &x, &y, &w, &h);
3698 evas_object_geometry_set(o, x, y, w, h);
3699 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3701 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3703 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3704 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3705 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3706 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3707 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3708 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3710 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3712 edje_object_part_swallow(o, "e.swallow.content", obj);
3714 _e_comp_object_event_add(o);
3717 evas_object_show(o);
3722 /* utility functions for deleting objects when their "owner" is deleted */
3724 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3729 EINA_SAFETY_ON_NULL_RETURN(to_del);
3730 l = evas_object_data_get(obj, "comp_object-to_del");
3731 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3732 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3733 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3737 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3742 EINA_SAFETY_ON_NULL_RETURN(to_del);
3743 l = evas_object_data_get(obj, "comp_object-to_del");
3745 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3748 /////////////////////////////////////////////////////////
3750 EINTERN Evas_Object *
3751 e_comp_object_client_add(E_Client *ec)
3756 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3757 if (ec->frame) return NULL;
3758 _e_comp_smart_init();
3759 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3760 cw = evas_object_smart_data_get(o);
3761 if (!cw) return NULL;
3762 evas_object_data_set(o, "E_Client", ec);
3765 evas_object_data_set(o, "comp_object", (void*)1);
3767 _e_comp_object_event_add(o);
3772 /* utility functions for getting client inset */
3774 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3777 if (!cw->client_inset.calc)
3783 if (ax) *ax = x - cw->client_inset.l;
3784 if (ay) *ay = y - cw->client_inset.t;
3788 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3791 if (!cw->client_inset.calc)
3797 if (ax) *ax = x + cw->client_inset.l;
3798 if (ay) *ay = y + cw->client_inset.t;
3802 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3805 if (!cw->client_inset.calc)
3811 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3812 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3816 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3819 if (!cw->client_inset.calc)
3825 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3826 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3830 e_comp_object_client_get(Evas_Object *obj)
3835 /* FIXME: remove this when eo is used */
3836 o = evas_object_data_get(obj, "comp_smart_obj");
3838 return e_comp_object_client_get(o);
3839 return cw ? cw->ec : NULL;
3843 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3846 if (cw->frame_extends)
3847 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3852 if (w) *w = cw->ec->w;
3853 if (h) *h = cw->ec->h;
3858 e_comp_object_util_zone_get(Evas_Object *obj)
3860 E_Zone *zone = NULL;
3864 zone = e_comp_zone_find_by_ec(cw->ec);
3869 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3870 zone = e_comp_zone_xy_get(x, y);
3876 e_comp_object_util_center(Evas_Object *obj)
3878 int x, y, w, h, ow, oh;
3883 zone = e_comp_object_util_zone_get(obj);
3884 EINA_SAFETY_ON_NULL_RETURN(zone);
3885 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3886 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3887 ow = cw->ec->w, oh = cw->ec->h;
3889 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3890 x = x + (w - ow) / 2;
3891 y = y + (h - oh) / 2;
3892 evas_object_move(obj, x, y);
3896 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3898 int x, y, w, h, ow, oh;
3901 EINA_SAFETY_ON_NULL_RETURN(on);
3902 evas_object_geometry_get(on, &x, &y, &w, &h);
3903 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3904 ow = cw->ec->w, oh = cw->ec->h;
3906 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3907 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3911 e_comp_object_util_fullscreen(Evas_Object *obj)
3916 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3919 evas_object_move(obj, 0, 0);
3920 evas_object_resize(obj, e_comp->w, e_comp->h);
3925 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3933 ow = cw->w, oh = cw->h;
3935 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3936 zone = e_comp_object_util_zone_get(obj);
3937 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3938 if (x) *x = zx + (zw - ow) / 2;
3939 if (y) *y = zy + (zh - oh) / 2;
3943 e_comp_object_input_objs_del(Evas_Object *obj)
3946 E_Input_Rect_Data *input_rect_data;
3947 E_Input_Rect_Smart_Data *input_rect_sd;
3952 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3953 if (!input_rect_sd) return;
3955 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3957 if (input_rect_data->obj)
3959 evas_object_smart_member_del(input_rect_data->obj);
3960 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3962 E_FREE(input_rect_data);
3967 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3970 E_Input_Rect_Data *input_rect_data = NULL;
3971 E_Input_Rect_Smart_Data *input_rect_sd;
3972 int client_w, client_h;
3974 if (cw->ec->client.w)
3975 client_w = cw->ec->client.w;
3977 client_w = cw->ec->w;
3979 if (cw->ec->client.h)
3980 client_h = cw->ec->client.h;
3982 client_h = cw->ec->h;
3984 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3988 _e_comp_input_obj_smart_init();
3989 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3990 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3991 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3994 input_rect_sd->cw = cw;
3997 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4000 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4001 if (input_rect_data)
4003 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4004 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4008 if ((input_rect_data) &&
4009 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4011 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4012 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4013 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4014 evas_object_clip_set(input_rect_data->obj, cw->clip);
4015 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4016 evas_object_geometry_set(input_rect_data->obj,
4017 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4018 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4019 evas_object_pass_events_set(cw->default_input_obj, 1);
4020 evas_object_pass_events_set(cw->obj, 1);
4023 evas_object_show(input_rect_data->obj);
4024 evas_object_show(cw->input_obj);
4029 evas_object_smart_member_del(cw->input_obj);
4030 E_FREE_FUNC(cw->input_obj, evas_object_del);
4031 evas_object_pass_events_set(cw->default_input_obj, 0);
4032 evas_object_pass_events_set(cw->obj, 0);
4037 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4040 E_Input_Rect_Smart_Data *input_rect_sd;
4041 E_Input_Rect_Data *input_rect_data;
4044 if (!cw->input_obj) return;
4046 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4049 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4051 *list = eina_list_append(*list, &input_rect_data->rect);
4057 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4060 if (l) *l = cw->client_inset.l;
4061 if (r) *r = cw->client_inset.r;
4062 if (t) *t = cw->client_inset.t;
4063 if (b) *b = cw->client_inset.b;
4066 /* set geometry for CSD */
4068 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4074 if (cw->frame_object)
4075 CRI("ACK! ec:%p", cw->ec);
4076 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4077 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4078 calc = cw->client_inset.calc;
4079 cw->client_inset.calc = l || r || t || b;
4080 eina_stringshare_replace(&cw->frame_theme, "borderless");
4081 if (cw->client_inset.calc)
4083 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4084 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4085 e_client_size_set(cw->ec, tw, th);
4087 else if (cw->ec->maximized || cw->ec->fullscreen)
4089 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4090 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4092 if (!cw->ec->new_client)
4094 if (calc && cw->client_inset.calc)
4096 tx = cw->ec->x - (l - cw->client_inset.l);
4097 ty = cw->ec->y - (t - cw->client_inset.t);
4098 e_client_pos_set(cw->ec, tx, ty);
4100 cw->ec->changes.pos = cw->ec->changes.size = 1;
4103 cw->client_inset.l = l;
4104 cw->client_inset.r = r;
4105 cw->client_inset.t = t;
4106 cw->client_inset.b = b;
4110 e_comp_object_frame_allowed(Evas_Object *obj)
4112 API_ENTRY EINA_FALSE;
4113 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4117 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4119 API_ENTRY EINA_FALSE;
4120 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4121 eina_stringshare_replace(&cw->frame_name, name);
4122 if (cw->frame_object)
4123 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4128 e_comp_object_frame_exists(Evas_Object *obj)
4130 API_ENTRY EINA_FALSE;
4131 return !!cw->frame_object;
4135 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4137 Evas_Object *o, *pbg;
4140 Eina_Stringshare *theme;
4142 API_ENTRY EINA_FALSE;
4144 if (!e_util_strcmp(cw->frame_theme, name))
4145 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4146 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4147 return _e_comp_object_shadow_setup(cw);
4148 pbg = cw->frame_object;
4149 theme = eina_stringshare_add(name);
4151 if (cw->frame_object)
4155 w = cw->ec->w, h = cw->ec->h;
4156 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4157 if ((cw->ec->w != w) || (cw->ec->h != h))
4159 cw->ec->changes.size = 1;
4162 E_FREE_FUNC(cw->frame_object, evas_object_del);
4163 if (!name) goto reshadow;
4165 o = edje_object_add(e_comp->evas);
4166 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4167 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4168 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4170 cw->frame_object = NULL;
4172 eina_stringshare_del(cw->frame_theme);
4173 cw->frame_theme = theme;
4178 if (theme != e_config->theme_default_border_style)
4180 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4181 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4185 ok = e_theme_edje_object_set(o, "base/theme/border",
4186 "e/widgets/border/default/border");
4187 if (ok && (theme == e_config->theme_default_border_style))
4189 /* Reset default border style to default */
4190 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4191 e_config_save_queue();
4198 cw->frame_object = o;
4199 eina_stringshare_del(cw->frame_theme);
4200 cw->frame_theme = theme;
4201 evas_object_name_set(o, "cw->frame_object");
4204 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4208 cw->ec->changes.icon = 1;
4214 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4219 _e_comp_object_shadow_setup(cw);
4222 int old_x, old_y, new_x = 0, new_y = 0;
4224 old_x = cw->x, old_y = cw->y;
4226 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4228 new_x = cw->ec->x, new_y = cw->ec->y;
4229 else if (cw->ec->placed || (!cw->ec->new_client))
4231 /* if no previous frame:
4232 * - reapply client_inset
4237 if (cw->ec->changes.size)
4245 zone = e_comp_zone_find_by_ec(cw->ec);
4248 x = cw->ec->client.x, y = cw->ec->client.y;
4249 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4250 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4252 new_x = x, new_y = y;
4255 if (old_x != new_x || old_y != new_y)
4257 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4258 cw->y = cw->x = -99999;
4259 evas_object_move(obj, new_x, new_y);
4263 if (cw->ec->maximized)
4265 cw->ec->changes.need_maximize = 1;
4268 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4269 if (cw->frame_object)
4271 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4274 cw->frame_extends = 0;
4275 evas_object_del(pbg);
4280 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4282 E_Comp_Object_Mover *prov;
4285 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4286 edje_object_signal_emit(cw->shobj, sig, src);
4287 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4288 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4289 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4291 /* start with highest priority callback first */
4292 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4294 if (!e_util_glob_match(sig, prov->sig)) continue;
4295 if (prov->func(prov->data, obj, sig)) break;
4300 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4302 /* FIXME: at some point I guess this should use eo to inherit
4303 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4304 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4307 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4311 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4314 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4318 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4321 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4325 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4328 Eina_Rectangle rect;
4331 if (cw->ec->input_only || (!cw->updates)) return;
4332 if (cw->nocomp) return;
4333 rect.x = x, rect.y = y;
4334 rect.w = w, rect.h = h;
4335 evas_object_smart_callback_call(obj, "damage", &rect);
4337 if (e_comp_is_on_overlay(cw->ec))
4339 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4340 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4341 * E module attempts to block screen update due to the particular policy.
4343 if (e_pixmap_resource_get(cw->ec->pixmap))
4344 cw->hwc_need_update = EINA_TRUE;
4347 /* ignore overdraw */
4348 if (cw->updates_full)
4350 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4351 e_comp_object_render_update_add(obj);
4353 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4354 evas_object_show(cw->smart_obj);
4358 /* clip rect to client surface */
4359 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4360 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4361 /* if rect is the total size of the client after clip, clear the updates
4362 * since this is guaranteed to be the whole region anyway
4364 eina_tiler_area_size_get(cw->updates, &tw, &th);
4365 if ((w > tw) || (h > th))
4367 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4368 eina_tiler_clear(cw->updates);
4369 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4371 tw = cw->ec->client.w, th = cw->ec->client.h;
4373 if ((!x) && (!y) && (w == tw) && (h == th))
4375 eina_tiler_clear(cw->updates);
4376 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4377 cw->updates_full = 1;
4378 cw->update_count = 0;
4381 if (cw->update_count > UPDATE_MAX)
4383 /* this is going to get really dumb, so just update the whole thing */
4384 eina_tiler_clear(cw->updates);
4385 cw->update_count = cw->updates_full = 1;
4386 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4387 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4391 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4392 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4394 cw->updates_exist = 1;
4395 e_comp_object_render_update_add(obj);
4397 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4398 evas_object_show(cw->smart_obj);
4402 e_comp_object_damage_exists(Evas_Object *obj)
4404 API_ENTRY EINA_FALSE;
4405 return cw->updates_exist;
4409 e_comp_object_render_update_add(Evas_Object *obj)
4413 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4414 if (cw->render_update_lock.lock) return;
4415 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4419 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4421 e_comp_render_queue();
4425 e_comp_object_render_update_del(Evas_Object *obj)
4429 if (cw->ec->input_only || (!cw->updates)) return;
4430 if (!cw->update) return;
4432 /* this gets called during comp animating to clear the update flag */
4433 if (e_comp->grabbed) return;
4434 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4435 if (!e_comp->updates)
4437 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4438 if (e_comp->render_animator)
4439 ecore_animator_freeze(e_comp->render_animator);
4444 e_comp_object_shape_apply(Evas_Object *obj)
4448 unsigned int i, *pix, *p;
4452 if (!cw->ec) return; //NYI
4453 if (cw->external_content) return;
4456 if ((cw->ec->shape_rects_num >= 1) &&
4457 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4462 ERR("BUGGER: shape with native surface? cw=%p", cw);
4465 evas_object_image_size_get(cw->obj, &w, &h);
4466 if ((w < 1) || (h < 1)) return;
4469 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4470 _e_comp_object_alpha_set(cw);
4471 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4472 evas_object_image_alpha_set(o, 1);
4474 p = pix = evas_object_image_data_get(cw->obj, 1);
4477 evas_object_image_data_set(cw->obj, pix);
4482 unsigned char *spix, *sp;
4484 spix = calloc(w * h, sizeof(unsigned char));
4486 for (i = 0; i < cw->ec->shape_rects_num; i++)
4490 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4491 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4492 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4493 sp = spix + (w * ry) + rx;
4494 for (py = 0; py < rh; py++)
4496 for (px = 0; px < rw; px++)
4504 for (py = 0; py < h; py++)
4506 for (px = 0; px < w; px++)
4508 unsigned int mask, imask;
4510 mask = ((unsigned int)(*sp)) << 24;
4512 imask |= imask >> 8;
4513 imask |= imask >> 8;
4514 *p = mask | (*p & imask);
4515 //if (*sp) *p = 0xff000000 | *p;
4516 //else *p = 0x00000000;
4525 for (py = 0; py < h; py++)
4527 for (px = 0; px < w; px++)
4531 evas_object_image_data_set(cw->obj, pix);
4532 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4533 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4535 evas_object_image_data_set(o, pix);
4536 evas_object_image_data_update_add(o, 0, 0, w, h);
4538 // don't need to fix alpha chanel as blending
4539 // should be totally off here regardless of
4540 // alpha channel content
4544 _e_comp_object_clear(E_Comp_Object *cw)
4549 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4551 if (cw->render_update_lock.lock) return;
4554 e_pixmap_clear(cw->ec->pixmap);
4556 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4557 evas_object_image_size_set(cw->obj, 1, 1);
4558 evas_object_image_data_set(cw->obj, NULL);
4559 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4561 evas_object_image_size_set(o, 1, 1);
4562 evas_object_image_data_set(o, NULL);
4565 e_comp_object_render_update_del(cw->smart_obj);
4569 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4573 API_ENTRY EINA_FALSE;
4575 if (cw->transparent.set == set)
4580 evas_object_color_get(obj, &r, &g, &b, &a);
4581 evas_object_color_set(obj, 0, 0, 0, 0);
4583 cw->transparent.user_r = r;
4584 cw->transparent.user_g = g;
4585 cw->transparent.user_b = b;
4586 cw->transparent.user_a = a;
4588 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4590 cw->transparent.user_r,
4591 cw->transparent.user_g,
4592 cw->transparent.user_b,
4593 cw->transparent.user_a);
4595 cw->transparent.set = EINA_TRUE;
4599 cw->transparent.set = EINA_FALSE;
4601 evas_object_color_set(obj,
4602 cw->transparent.user_r,
4603 cw->transparent.user_g,
4604 cw->transparent.user_b,
4605 cw->transparent.user_a);
4607 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4609 cw->transparent.user_r,
4610 cw->transparent.user_g,
4611 cw->transparent.user_b,
4612 cw->transparent.user_a);
4618 /* helper function to simplify toggling of redirection for display servers which support it */
4620 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4625 if (cw->redirected == set) return;
4626 cw->redirected = set;
4627 if (cw->external_content) return;
4629 e_comp_object_map_update(obj);
4633 if (cw->updates_exist)
4634 e_comp_object_render_update_add(obj);
4636 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4638 _e_comp_object_transparent_set(obj, EINA_FALSE);
4639 evas_object_smart_callback_call(obj, "redirected", NULL);
4643 _e_comp_object_clear(cw);
4644 _e_comp_object_transparent_set(obj, EINA_TRUE);
4645 evas_object_smart_callback_call(obj, "unredirected", NULL);
4650 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4653 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4655 if (cw->buffer_destroy_listener.notify)
4657 cw->buffer_destroy_listener.notify = NULL;
4658 wl_list_remove(&cw->buffer_destroy_listener.link);
4661 if (e_object_is_del(E_OBJECT(cw->ec)))
4663 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4668 /* if it's current displaying buffer, do not remove its content */
4669 if (!evas_object_visible_get(cw->ec->frame))
4670 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4675 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4680 if (cw->buffer_destroy_listener.notify)
4682 wl_list_remove(&cw->buffer_destroy_listener.link);
4683 cw->buffer_destroy_listener.notify = NULL;
4686 if (cw->tbm_surface)
4688 tbm_surface_internal_unref(cw->tbm_surface);
4689 cw->tbm_surface = NULL;
4694 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4696 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4697 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4699 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4701 tbm_surface_internal_ref(ns->data.tbm.buffer);
4702 cw->tbm_surface = ns->data.tbm.buffer;
4706 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4707 evas_object_image_native_surface_set(cw->obj, ns);
4711 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4713 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4714 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4715 evas_object_image_native_surface_set(o, ns);
4722 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4724 Evas_Native_Surface ns;
4727 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4728 if (cw->ec->input_only) return;
4729 if (cw->external_content) return;
4730 if (cw->render_update_lock.lock) return;
4733 memset(&ns, 0, sizeof(Evas_Native_Surface));
4737 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4738 set = (!cw->ec->shaped);
4740 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4744 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4748 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4751 if (cw->ec->input_only) return;
4754 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4755 _e_comp_object_alpha_set(cw);
4757 e_comp_object_native_surface_set(obj, cw->native);
4758 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4762 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4768 if (cw->blanked == set) return;
4770 _e_comp_object_alpha_set(cw);
4773 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4774 evas_object_image_data_set(cw->obj, NULL);
4778 e_comp_object_native_surface_set(obj, 1);
4779 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4783 _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)
4788 if (!_damage_trace) return;
4792 if (!evas_object_visible_get(cw->obj)) return;
4794 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4796 o = evas_object_rectangle_add(e_comp->evas);
4797 evas_object_layer_set(o, E_LAYER_MAX);
4798 evas_object_name_set(o, "damage_trace");
4799 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4800 evas_object_resize(o, dmg_w, dmg_h);
4801 evas_object_color_set(o, 0, 128, 0, 128);
4802 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4803 evas_object_pass_events_set(o, EINA_TRUE);
4804 evas_object_show(o);
4806 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4808 dmg_w, dmg_h, dmg_x, dmg_y,
4809 origin->w, origin->h, origin->x, origin->y);
4811 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4814 /* mark an object as dirty and setup damages */
4816 e_comp_object_dirty(Evas_Object *obj)
4819 Eina_Rectangle *rect;
4823 Eina_Bool dirty, visible;
4827 if (cw->external_content) return;
4828 if (!cw->redirected) return;
4829 if (cw->render_update_lock.lock)
4831 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4834 /* only actually dirty if pixmap is available */
4835 if (!e_pixmap_resource_get(cw->ec->pixmap))
4837 // e_pixmap_size_get returns last attached buffer size
4838 // eventhough it is destroyed
4839 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4842 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4843 visible = cw->visible;
4844 if (!dirty) w = h = 1;
4845 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4847 evas_object_image_data_set(cw->obj, NULL);
4848 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4849 evas_object_image_size_set(cw->obj, tw, th);
4850 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4851 if (cw->pending_updates)
4852 eina_tiler_area_size_set(cw->pending_updates, w, h);
4853 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4855 evas_object_image_pixels_dirty_set(o, dirty);
4857 evas_object_image_data_set(o, NULL);
4858 evas_object_image_size_set(o, tw, th);
4859 visible |= evas_object_visible_get(o);
4863 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4867 e_comp_object_native_surface_set(obj, 1);
4869 m = _e_comp_object_map_damage_transform_get(cw->ec);
4870 it = eina_tiler_iterator_new(cw->updates);
4871 EINA_ITERATOR_FOREACH(it, rect)
4873 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4874 * of evas engine and doesn't convert damage according to evas_map.
4875 * so damage of evas_object_image use surface coordinate.
4879 int damage_x, damage_y, damage_w, damage_h;
4881 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4882 &damage_x, &damage_y, &damage_w, &damage_h);
4883 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4884 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4888 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4889 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4892 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4893 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4894 if (cw->pending_updates)
4895 eina_tiler_rect_add(cw->pending_updates, rect);
4897 eina_iterator_free(it);
4898 if (m) e_map_free(m);
4899 if (cw->pending_updates)
4900 eina_tiler_clear(cw->updates);
4903 cw->pending_updates = cw->updates;
4904 cw->updates = eina_tiler_new(w, h);
4905 eina_tiler_tile_size_set(cw->updates, 1, 1);
4907 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4908 evas_object_smart_callback_call(obj, "dirty", NULL);
4909 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4910 /* force render if main object is hidden but mirrors are visible */
4911 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4912 e_comp_object_render(obj);
4916 e_comp_object_render(Evas_Object *obj)
4923 API_ENTRY EINA_FALSE;
4925 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4926 if (cw->ec->input_only) return EINA_TRUE;
4927 if (cw->external_content) return EINA_TRUE;
4928 if (cw->native) return EINA_FALSE;
4929 /* if comp object is not redirected state, comp object should not be set by newly committed data
4930 because image size of comp object is 1x1 and it should not be shown on canvas */
4931 if (!cw->redirected) return EINA_TRUE;
4932 if (cw->render_update_lock.lock)
4934 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4937 e_comp_object_render_update_del(obj);
4938 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4940 if (!cw->pending_updates)
4942 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4943 evas_object_image_data_set(cw->obj, NULL);
4944 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4945 evas_object_image_data_set(o, NULL);
4949 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4951 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4953 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4956 e_pixmap_image_refresh(cw->ec->pixmap);
4957 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4960 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4961 e_pixmap_image_data_ref(cw->ec->pixmap);
4963 /* set pixel data */
4964 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4965 _e_comp_object_alpha_set(cw);
4966 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4968 evas_object_image_data_set(o, pix);
4969 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4970 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4973 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4975 e_comp_client_post_update_add(cw->ec);
4980 /* create a duplicate of an evas object */
4982 e_comp_object_util_mirror_add(Evas_Object *obj)
4986 unsigned int *pix = NULL;
4987 Eina_Bool argb = EINA_FALSE;
4992 cw = evas_object_data_get(obj, "comp_mirror");
4995 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4996 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4997 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4998 evas_object_image_alpha_set(o, 1);
4999 evas_object_image_source_set(o, obj);
5002 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5003 if (cw->external_content)
5005 ERR("%p of client %p is external content.", obj, cw->ec);
5008 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5009 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5010 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5011 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5012 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5013 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5014 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5015 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5016 evas_object_data_set(o, "comp_mirror", cw);
5018 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5019 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5021 evas_object_image_size_set(o, tw, th);
5024 pix = evas_object_image_data_get(cw->obj, 0);
5030 evas_object_image_native_surface_set(o, cw->ns);
5033 Evas_Native_Surface ns;
5034 memset(&ns, 0, sizeof(Evas_Native_Surface));
5035 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5036 evas_object_image_native_surface_set(o, &ns);
5041 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5042 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5044 (e_pixmap_image_exists(cw->ec->pixmap)))
5045 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5047 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5054 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5055 evas_object_image_pixels_dirty_set(o, dirty);
5056 evas_object_image_data_set(o, pix);
5057 evas_object_image_data_set(cw->obj, pix);
5059 evas_object_image_data_update_add(o, 0, 0, tw, th);
5064 //////////////////////////////////////////////////////
5067 e_comp_object_effect_allowed_get(Evas_Object *obj)
5069 API_ENTRY EINA_FALSE;
5071 if (!cw->shobj) return EINA_FALSE;
5072 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5073 return !e_comp_config_get()->match.disable_borders;
5076 /* setup an api effect for a client */
5078 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5081 Eina_Stringshare *grp;
5082 E_Comp_Config *config;
5083 Eina_Bool loaded = EINA_FALSE;
5085 API_ENTRY EINA_FALSE;
5086 if (!cw->shobj) return EINA_FALSE; //input window
5088 if (!effect) effect = "none";
5089 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5091 config = e_comp_config_get();
5092 if ((config) && (config->effect_file))
5094 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5096 cw->effect_set = EINA_TRUE;
5103 edje_object_file_get(cw->effect_obj, NULL, &grp);
5104 cw->effect_set = !eina_streq(effect, "none");
5105 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5106 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5108 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5109 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5110 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5112 if (cw->effect_running)
5114 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5117 cw->effect_set = EINA_FALSE;
5118 return cw->effect_set;
5122 if (cw->effect_running)
5124 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5127 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5128 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5129 if (cw->effect_clip)
5131 evas_object_clip_unset(cw->clip);
5132 cw->effect_clip = 0;
5134 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5136 _e_comp_object_dim_update(cw);
5138 return cw->effect_set;
5141 /* set params for embryo scripts in effect */
5143 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5145 Edje_Message_Int_Set *msg;
5149 EINA_SAFETY_ON_NULL_RETURN(params);
5150 EINA_SAFETY_ON_FALSE_RETURN(count);
5151 if (!cw->effect_set) return;
5153 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5154 msg->count = (int)count;
5155 for (x = 0; x < count; x++)
5156 msg->val[x] = params[x];
5157 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5158 edje_object_message_signal_process(cw->effect_obj);
5162 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5164 Edje_Signal_Cb end_cb;
5166 E_Comp_Object *cw = data;
5168 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5169 cw->effect_running = 0;
5170 if (!_e_comp_object_animating_end(cw)) return;
5172 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5174 evas_object_data_del(cw->smart_obj, "effect_running");
5175 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5176 e_comp_visibility_calculation_set(EINA_TRUE);
5179 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5180 if (!end_cb) return;
5181 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5182 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5183 end_cb(end_data, cw->smart_obj, emission, source);
5186 /* clip effect to client's zone */
5188 e_comp_object_effect_clip(Evas_Object *obj)
5192 zone = e_comp_zone_find_by_ec(cw->ec);
5194 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5195 if (!cw->effect_clip_able) return;
5196 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5197 cw->effect_clip = 1;
5200 /* unclip effect from client's zone */
5202 e_comp_object_effect_unclip(Evas_Object *obj)
5205 if (!cw->effect_clip) return;
5206 evas_object_clip_unset(cw->smart_obj);
5207 cw->effect_clip = 0;
5210 /* start effect, running end_cb after */
5212 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5214 API_ENTRY EINA_FALSE;
5215 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5216 if (!cw->effect_set) return EINA_FALSE;
5218 if (cw->effect_running)
5220 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5223 e_comp_object_effect_clip(obj);
5224 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5226 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5227 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5228 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5229 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5231 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5232 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5234 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5235 _e_comp_object_animating_begin(cw);
5236 cw->effect_running = 1;
5240 /* stop a currently-running effect immediately */
5242 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5245 Edje_Signal_Cb end_cb_before = NULL;
5246 void *end_data_before = NULL;
5247 API_ENTRY EINA_FALSE;
5249 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5250 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5252 if (end_cb_before != end_cb) return EINA_TRUE;
5253 e_comp_object_effect_unclip(obj);
5254 if (cw->effect_clip)
5256 evas_object_clip_unset(cw->effect_obj);
5257 cw->effect_clip = 0;
5259 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5260 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5262 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5264 evas_object_data_del(cw->smart_obj, "effect_running");
5265 e_comp_visibility_calculation_set(EINA_TRUE);
5268 cw->effect_running = 0;
5269 ret = _e_comp_object_animating_end(cw);
5271 if ((ret) && (end_cb_before))
5273 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5274 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5281 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5283 return a->pri - b->pri;
5286 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5287 E_API E_Comp_Object_Mover *
5288 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5290 E_Comp_Object_Mover *prov;
5292 prov = E_NEW(E_Comp_Object_Mover, 1);
5293 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5294 prov->func = provider;
5295 prov->data = (void*)data;
5298 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5299 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5304 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5306 EINA_SAFETY_ON_NULL_RETURN(prov);
5307 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5312 e_comp_object_effect_object_get(Evas_Object *obj)
5316 return cw->effect_obj;
5320 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5322 API_ENTRY EINA_FALSE;
5323 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5324 if (!cw->effect_set) return EINA_FALSE;
5331 ////////////////////////////////////
5334 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5336 if (e_comp->autoclose.obj)
5338 e_comp_ungrab_input(0, 1);
5339 if (e_comp->autoclose.del_cb)
5340 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5341 else if (!already_del)
5343 evas_object_hide(e_comp->autoclose.obj);
5344 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5346 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5348 e_comp->autoclose.obj = NULL;
5349 e_comp->autoclose.data = NULL;
5350 e_comp->autoclose.del_cb = NULL;
5351 e_comp->autoclose.key_cb = NULL;
5352 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5356 _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)
5358 _e_comp_object_autoclose_cleanup(0);
5362 _e_comp_object_autoclose_setup(Evas_Object *obj)
5364 if (!e_comp->autoclose.rect)
5366 /* create rect just below autoclose object to catch mouse events */
5367 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5368 evas_object_move(e_comp->autoclose.rect, 0, 0);
5369 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5370 evas_object_show(e_comp->autoclose.rect);
5371 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5372 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5373 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5374 e_comp_grab_input(0, 1);
5376 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5377 evas_object_focus_set(obj, 1);
5381 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5383 _e_comp_object_autoclose_setup(obj);
5384 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5388 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5390 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5391 _e_comp_object_autoclose_cleanup(1);
5392 if (e_client_focused_get()) return;
5394 E_Zone *zone = e_zone_current_get();
5397 e_zone_focus_reset(zone);
5401 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5405 if (e_comp->autoclose.obj)
5407 if (e_comp->autoclose.obj == obj) return;
5408 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5409 e_comp->autoclose.obj = obj;
5410 e_comp->autoclose.del_cb = del_cb;
5411 e_comp->autoclose.key_cb = cb;
5412 e_comp->autoclose.data = (void*)data;
5413 if (evas_object_visible_get(obj))
5414 _e_comp_object_autoclose_setup(obj);
5416 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5417 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5420 e_comp->autoclose.obj = obj;
5421 e_comp->autoclose.del_cb = del_cb;
5422 e_comp->autoclose.key_cb = cb;
5423 e_comp->autoclose.data = (void*)data;
5424 if (evas_object_visible_get(obj))
5425 _e_comp_object_autoclose_setup(obj);
5427 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5428 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5432 e_comp_object_is_animating(Evas_Object *obj)
5436 return cw->animating;
5440 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5444 if ((cw->external_content) &&
5445 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5447 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5448 "But current external content is %d object for %p.",
5449 cw->content_type, cw->ec);
5453 cw->user_alpha_set = EINA_TRUE;
5454 cw->user_alpha = alpha;
5456 if (!cw->obj) return;
5458 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5460 evas_object_image_alpha_set(cw->obj, alpha);
5462 if ((!cw->native) && (!cw->external_content))
5463 evas_object_image_data_set(cw->obj, NULL);
5467 e_comp_object_alpha_get(Evas_Object *obj)
5469 API_ENTRY EINA_FALSE;
5471 return evas_object_image_alpha_get(cw->obj);
5475 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5477 Eina_Bool mask_set = EINA_FALSE;
5481 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5482 if (cw->ec->input_only) return;
5489 o = evas_object_rectangle_add(e_comp->evas);
5490 evas_object_color_set(o, 0, 0, 0, 0);
5491 evas_object_clip_set(o, cw->clip);
5492 evas_object_smart_member_add(o, obj);
5493 evas_object_move(o, 0, 0);
5494 evas_object_resize(o, cw->w, cw->h);
5495 /* save render op value to restore when clear a mask.
5497 * NOTE: DO NOT change the render op on ec->frame while mask object
5498 * is set. it will overwrite the changed op value. */
5499 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5500 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5501 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5502 if (cw->visible) evas_object_show(o);
5505 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5506 ELOGF("COMP", " |mask_obj", cw->ec);
5507 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5514 evas_object_smart_member_del(cw->mask.obj);
5515 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5517 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5518 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5524 e_comp_object_mask_has(Evas_Object *obj)
5526 API_ENTRY EINA_FALSE;
5528 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5532 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5537 if ((cw->external_content) &&
5538 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5540 WRN("Can set up size to ONLY evas \"image\" object. "
5541 "But current external content is %d object for %p.",
5542 cw->content_type, cw->ec);
5546 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5548 evas_object_image_size_set(cw->obj, tw, th);
5552 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5554 Eina_Bool transform_set = EINA_FALSE;
5556 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5557 if (cw->ec->input_only) return;
5559 transform_set = !!set;
5563 if (!cw->transform_bg_obj)
5565 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5566 evas_object_move(o, 0, 0);
5567 evas_object_resize(o, 1, 1);
5568 if (cw->transform_bg_color.a >= 255)
5569 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5571 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5572 evas_object_color_set(o,
5573 cw->transform_bg_color.r,
5574 cw->transform_bg_color.g,
5575 cw->transform_bg_color.b,
5576 cw->transform_bg_color.a);
5577 if (cw->visible) evas_object_show(o);
5579 cw->transform_bg_obj = o;
5580 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5582 _e_comp_object_transform_obj_stack_update(obj);
5586 if (cw->transform_bg_obj)
5588 evas_object_smart_member_del(cw->transform_bg_obj);
5589 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5595 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5599 cw->transform_bg_color.r = r;
5600 cw->transform_bg_color.g = g;
5601 cw->transform_bg_color.b = b;
5602 cw->transform_bg_color.a = a;
5604 if (cw->transform_bg_obj)
5606 evas_object_color_set(cw->transform_bg_obj,
5607 cw->transform_bg_color.r,
5608 cw->transform_bg_color.g,
5609 cw->transform_bg_color.b,
5610 cw->transform_bg_color.a);
5615 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5618 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5619 if (cw->ec->input_only) return;
5620 if (!cw->transform_bg_obj) return;
5622 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5626 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5629 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5630 if (cw->ec->input_only) return;
5631 if (!cw->transform_bg_obj) return;
5633 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5637 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5639 Eina_Bool transform_set = EINA_FALSE;
5641 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5642 if (cw->ec->input_only) return;
5644 transform_set = !!set;
5648 if (!cw->transform_tranp_obj)
5650 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5651 evas_object_move(o, 0, 0);
5652 evas_object_resize(o, 1, 1);
5653 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5654 evas_object_color_set(o, 0, 0, 0, 0);
5655 if (cw->visible) evas_object_show(o);
5657 cw->transform_tranp_obj = o;
5658 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5659 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5660 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5662 _e_comp_object_transform_obj_stack_update(obj);
5666 if (cw->transform_tranp_obj)
5668 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5669 evas_object_smart_member_del(cw->transform_tranp_obj);
5670 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5676 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5679 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5680 if (cw->ec->input_only) return;
5681 if (!cw->transform_tranp_obj) return;
5683 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5687 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5690 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5691 if (cw->ec->input_only) return;
5692 if (!cw->transform_tranp_obj) return;
5694 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5698 e_comp_object_layer_update(Evas_Object *obj,
5699 Evas_Object *above, Evas_Object *below)
5701 E_Comp_Object *cw2 = NULL;
5702 Evas_Object *o = NULL;
5707 if (cw->ec->layer_block) return;
5708 if ((above) && (below))
5710 ERR("Invalid layer update request! cw=%p", cw);
5718 layer = evas_object_layer_get(o);
5719 cw2 = evas_object_data_get(o, "comp_obj");
5722 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5724 o = evas_object_above_get(o);
5725 if ((!o) || (o == cw->smart_obj)) break;
5726 if (evas_object_layer_get(o) != layer)
5728 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5733 ec = e_client_top_get();
5734 if (ec) o = ec->frame;
5737 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5741 _e_comp_object_layers_remove(cw);
5744 if (cw2->layer > cw->layer)
5745 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5746 else if (cw2->layer == cw->layer)
5749 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5751 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5753 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5756 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5759 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5763 e_comp_object_layer_get(Evas_Object *obj)
5770 e_comp_object_content_set(Evas_Object *obj,
5771 Evas_Object *content,
5772 E_Comp_Object_Content_Type type)
5774 API_ENTRY EINA_FALSE;
5776 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5777 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5778 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5782 ERR("Can't set e.swallow.content to requested content. "
5783 "Previous comp object should not be changed at all.");
5787 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5789 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5790 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5792 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5793 type, content, cw->ec, cw->ec->pixmap);
5797 cw->external_content = EINA_TRUE;
5800 cw->content_type = type;
5801 e_util_size_debug_set(cw->obj, 1);
5802 evas_object_name_set(cw->obj, "cw->obj");
5803 _e_comp_object_alpha_set(cw);
5806 _e_comp_object_shadow_setup(cw);
5812 e_comp_object_content_unset(Evas_Object *obj)
5814 API_ENTRY EINA_FALSE;
5816 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5817 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5819 if (!cw->obj && !cw->ec->visible)
5821 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5825 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5827 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5833 if (cw->frame_object)
5834 edje_object_part_unswallow(cw->frame_object, cw->obj);
5836 edje_object_part_unswallow(cw->shobj, cw->obj);
5838 evas_object_del(cw->obj);
5839 evas_object_hide(cw->obj);
5843 cw->external_content = EINA_FALSE;
5844 if (cw->ec->is_cursor)
5847 DBG("%p is cursor surface..", cw->ec);
5848 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5850 evas_object_resize(cw->ec->frame, pw, ph);
5851 evas_object_hide(cw->ec->frame);
5856 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5857 cw->obj = evas_object_image_filled_add(e_comp->evas);
5858 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5859 e_util_size_debug_set(cw->obj, 1);
5860 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5861 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5862 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5863 evas_object_name_set(cw->obj, "cw->obj");
5864 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5865 _e_comp_object_alpha_set(cw);
5868 _e_comp_object_shadow_setup(cw);
5873 _e_comp_intercept_show_helper(cw);
5877 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5878 e_comp_object_dirty(cw->smart_obj);
5879 e_comp_object_render(cw->smart_obj);
5880 e_comp_object_render_update_add(obj);
5885 EINTERN Evas_Object *
5886 e_comp_object_content_get(Evas_Object *obj)
5890 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5892 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5894 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5901 E_API E_Comp_Object_Content_Type
5902 e_comp_object_content_type_get(Evas_Object *obj)
5904 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5906 return cw->content_type;
5910 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5913 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5914 E_Comp_Config *conf = e_comp_config_get();
5915 if (cw->ec->input_only) return;
5916 if (!conf->dim_rect_enable) return;
5918 cw->dim.mask_set = mask_set;
5924 if (!cw->dim.enable) return;
5925 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5929 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5931 Eina_Bool mask_set = EINA_FALSE;
5935 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5936 E_Comp_Config *conf = e_comp_config_get();
5937 if (cw->ec->input_only) return;
5938 if (!conf->dim_rect_enable) return;
5944 if (cw->dim.mask_obj)
5946 evas_object_smart_member_del(cw->dim.mask_obj);
5947 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5950 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);
5951 o = evas_object_rectangle_add(e_comp->evas);
5952 evas_object_color_set(o, 0, 0, 0, 0);
5953 evas_object_smart_member_add(o, obj);
5954 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5955 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5957 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5958 if (cw->visible) evas_object_show(o);
5960 cw->dim.mask_obj = o;
5961 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5963 evas_object_layer_set(cw->dim.mask_obj, 9998);
5967 if (cw->dim.mask_obj)
5969 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5970 evas_object_smart_member_del(cw->dim.mask_obj);
5971 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5977 e_comp_object_dim_client_set(E_Client *ec)
5979 E_Comp_Config *conf = e_comp_config_get();
5981 if (!conf->dim_rect_enable) return ;
5982 if (dim_client == ec) return;
5984 Eina_Bool prev_dim = EINA_FALSE;
5985 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5987 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5988 prev_dim = EINA_TRUE;
5990 if (prev_dim && dim_client->visible && ec)
5992 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5993 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5997 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5998 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6004 e_comp_object_dim_client_get(void)
6006 E_Comp_Config *conf = e_comp_config_get();
6008 if (!conf->dim_rect_enable ) return NULL;
6014 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6017 char emit[32] = "\0";
6018 E_Comp_Config *conf = e_comp_config_get();
6021 if (!conf->dim_rect_enable) return;
6022 if (!cw->effect_obj) return;
6023 if (enable == cw->dim.enable) return;
6025 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6026 if (noeffect || !conf->dim_rect_effect)
6028 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6032 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6035 cw->dim.enable = enable;
6037 if (cw->dim.mask_set && !enable)
6039 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6040 edje_object_signal_emit(cw->effect_obj, emit, "e");
6042 else if (cw->dim.mask_set && enable)
6044 edje_object_signal_emit(cw->effect_obj, emit, "e");
6045 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6049 edje_object_signal_emit(cw->effect_obj, emit, "e");
6054 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6056 API_ENTRY EINA_FALSE;
6057 E_Comp_Config *conf = e_comp_config_get();
6059 if (!ec) return EINA_FALSE;
6060 if (!conf->dim_rect_enable) return EINA_FALSE;
6062 if (cw->dim.enable) return EINA_TRUE;
6068 _e_comp_object_dim_update(E_Comp_Object *cw)
6070 E_Comp_Config *conf = e_comp_config_get();
6073 if (!conf->dim_rect_enable) return;
6074 if (!cw->effect_obj) return;
6077 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6078 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6080 if (cw->dim.mask_set)
6082 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6088 e_comp_object_clear(Evas_Object *obj)
6092 _e_comp_object_clear(cw);
6096 e_comp_object_hwc_update_exists(Evas_Object *obj)
6098 API_ENTRY EINA_FALSE;
6099 return cw->hwc_need_update;
6104 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6107 cw->hwc_need_update = set;
6111 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6113 API_ENTRY EINA_FALSE;
6114 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6118 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6121 if (cw->indicator.obj != indicator)
6122 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6123 cw->indicator.obj = indicator;
6124 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6128 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6131 if (cw->indicator.obj != indicator) return;
6132 cw->indicator.obj = NULL;
6133 edje_object_part_unswallow(cw->shobj, indicator);
6137 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6140 Edje_Message_Int_Set *msg;
6142 if (!cw->indicator.obj) return;
6144 cw->indicator.w = w;
6145 cw->indicator.h = h;
6147 if (!cw->shobj) return;
6149 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6153 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6154 edje_object_message_signal_process(cw->shobj);
6157 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6159 e_comp_object_map_update(Evas_Object *obj)
6162 E_Client *ec = cw->ec;
6163 E_Comp_Wl_Client_Data *cdata;
6165 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6168 int l, remain = sizeof buffer;
6171 if (e_object_is_del(E_OBJECT(ec))) return;
6172 cdata = e_client_cdata_get(ec);
6175 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6176 * when new buffer is attached.
6178 if (!cdata->buffer_ref.buffer) return;
6180 if ((!cw->redirected) ||
6181 (e_client_video_hw_composition_check(ec)) ||
6182 (!e_comp_wl_output_buffer_transform_get(ec) &&
6183 cdata->scaler.buffer_viewport.buffer.scale == 1))
6185 if (evas_object_map_enable_get(cw->effect_obj))
6187 ELOGF("TRANSFORM", "map: disable", cw->ec);
6188 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6189 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6190 evas_object_resize(cw->effect_obj, tw, th);
6197 EINA_SAFETY_ON_NULL_RETURN(map);
6199 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6205 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6207 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6208 e_map_point_image_uv_set(map, 0, x, y);
6209 l = snprintf(p, remain, "%d,%d", x, y);
6210 p += l, remain -= l;
6212 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6213 e_map_point_image_uv_set(map, 1, x, y);
6214 l = snprintf(p, remain, " %d,%d", x, y);
6215 p += l, remain -= l;
6217 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6218 e_map_point_image_uv_set(map, 2, x, y);
6219 l = snprintf(p, remain, " %d,%d", x, y);
6220 p += l, remain -= l;
6222 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6223 e_map_point_image_uv_set(map, 3, x, y);
6224 l = snprintf(p, remain, " %d,%d", x, y);
6225 p += l, remain -= l;
6227 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6229 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6231 e_comp_object_map_set(cw->effect_obj, map);
6232 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6236 /* if there's screen rotation with comp mode, then ec->effect_obj and
6237 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6239 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6240 evas_object_resize(cw->effect_obj, tw, th);
6244 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6246 API_ENTRY EINA_FALSE;
6248 cw->render_trace = set;
6254 e_comp_object_native_usable_get(Evas_Object *obj)
6256 API_ENTRY EINA_FALSE;
6257 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6259 if (cw->ec->input_only) return EINA_FALSE;
6260 if (cw->external_content) return EINA_FALSE;
6261 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6263 /* just return true value, if it is normal case */
6264 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6267 Evas_Native_Surface *ns;
6268 ns = evas_object_image_native_surface_get(cw->obj);
6270 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6273 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6281 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6283 API_ENTRY EINA_FALSE;
6284 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6285 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6286 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6290 case E_COMP_IMAGE_FILTER_BLUR:
6291 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6293 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6294 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6296 case E_COMP_IMAGE_FILTER_INVERSE:
6297 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6299 case E_COMP_IMAGE_FILTER_NONE:
6301 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6305 cw->image_filter = filter;
6310 EINTERN E_Comp_Image_Filter
6311 e_comp_object_image_filter_get(Evas_Object *obj)
6313 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6314 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6315 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6316 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6318 return cw->image_filter;
6322 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6326 if (!_damage_trace) return;
6328 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6329 evas_object_del(obj);
6331 _damage_trace_post_objs = NULL;
6335 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6337 if (!_damage_trace) return;
6339 _damage_trace_post_objs = _damage_trace_objs;
6340 _damage_trace_objs = NULL;
6344 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6346 if (_damage_trace == onoff) return;
6350 evas_event_callback_add(e_comp->evas,
6351 EVAS_CALLBACK_RENDER_PRE,
6352 _e_comp_object_damage_trace_render_pre_cb,
6355 evas_event_callback_add(e_comp->evas,
6356 EVAS_CALLBACK_RENDER_POST,
6357 _e_comp_object_damage_trace_render_post_cb,
6364 EINA_LIST_FREE(_damage_trace_objs, obj)
6365 evas_object_del(obj);
6367 _damage_trace_objs = NULL;
6369 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6370 evas_object_del(obj);
6372 _damage_trace_post_objs = NULL;
6374 evas_event_callback_del(e_comp->evas,
6375 EVAS_CALLBACK_RENDER_PRE,
6376 _e_comp_object_damage_trace_render_pre_cb);
6378 evas_event_callback_del(e_comp->evas,
6379 EVAS_CALLBACK_RENDER_POST,
6380 _e_comp_object_damage_trace_render_post_cb);
6383 _damage_trace = onoff;
6387 e_comp_object_redirected_get(Evas_Object *obj)
6389 API_ENTRY EINA_FALSE;
6390 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6392 return cw->redirected;
6396 e_comp_object_color_visible_get(Evas_Object *obj)
6398 API_ENTRY EINA_FALSE;
6401 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6403 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6407 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6411 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6415 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6423 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6425 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6427 return e_map_set_to_comp_object(em, obj);
6431 e_comp_object_map_get(const Evas_Object *obj)
6433 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6435 return e_map_get_from_comp_object(obj);
6439 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6441 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6443 evas_object_map_enable_set(obj, enable);
6449 e_comp_object_render_update_lock(Evas_Object *obj)
6451 E_Comp_Wl_Buffer *buffer;
6452 struct wayland_tbm_client_queue *cqueue;
6454 API_ENTRY EINA_FALSE;
6456 if (cw->render_update_lock.lock == 0)
6458 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6460 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6461 if ((buffer) && (buffer->resource))
6463 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6465 wayland_tbm_server_client_queue_flush(cqueue);
6468 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6469 e_comp_object_render_update_del(obj);
6471 ELOGF("COMP", "Render update lock enabled", cw->ec);
6474 cw->render_update_lock.lock++;
6480 e_comp_object_render_update_unlock(Evas_Object *obj)
6484 if (cw->render_update_lock.lock == 0)
6487 cw->render_update_lock.lock--;
6489 if (cw->render_update_lock.lock == 0)
6492 if (cw->render_update_lock.pending_move_set)
6494 evas_object_move(obj,
6495 cw->render_update_lock.pending_move_x,
6496 cw->render_update_lock.pending_move_y);
6497 cw->render_update_lock.pending_move_x = 0;
6498 cw->render_update_lock.pending_move_y = 0;
6499 cw->render_update_lock.pending_move_set = EINA_FALSE;
6502 if (cw->render_update_lock.pending_resize_set)
6504 evas_object_resize(obj,
6505 cw->render_update_lock.pending_resize_w,
6506 cw->render_update_lock.pending_resize_h);
6507 cw->render_update_lock.pending_resize_w = 0;
6508 cw->render_update_lock.pending_resize_h = 0;
6509 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6512 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6514 if ((cw->ec->exp_iconify.buffer_flush) &&
6515 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6516 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6517 e_comp_object_clear(obj);
6519 e_comp_object_render_update_add(obj);
6521 ELOGF("COMP", "Render update lock disabled", cw->ec);
6526 e_comp_object_render_update_lock_get(Evas_Object *obj)
6528 API_ENTRY EINA_FALSE;
6530 if (cw->render_update_lock.lock > 0)
6537 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6541 if (cw->transparent.set)
6543 if (r) *r = cw->transparent.user_r;
6544 if (g) *g = cw->transparent.user_g;
6545 if (b) *b = cw->transparent.user_b;
6546 if (a) *a = cw->transparent.user_a;
6550 evas_object_color_get(obj, r, g, b, a);
6555 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6559 evas_object_render_op_set(cw->obj, op);
6562 EINTERN Evas_Render_Op
6563 e_comp_object_render_op_get(Evas_Object *obj)
6565 API_ENTRY EVAS_RENDER_BLEND;
6567 return evas_object_render_op_get(cw->obj);
6571 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6574 wl_signal_add(&cw->events.lower, listener);
6578 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6581 wl_signal_add(&cw->events.show, listener);
6585 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6588 wl_signal_add(&cw->events.hide, listener);