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,shaded", "e");
1143 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1145 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1146 /* visibility must always be enabled for re_manage clients to prevent
1147 * pop-in animations every time the user sees a persistent client again;
1148 * applying visibility for iconic clients prevents the client from getting
1151 if (cw->visible || cw->ec->re_manage)
1152 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1154 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1156 /* breaks animation counter */
1157 if (cw->frame_object)
1159 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1160 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1161 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1162 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1168 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1172 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1175 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1177 if (input_rect_data->obj)
1179 pass_event_flag = EINA_TRUE;
1185 if (cw->indicator.obj)
1187 Evas_Object *indicator;
1188 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1189 if (indicator != cw->indicator.obj)
1191 edje_object_part_unswallow(cw->shobj, indicator);
1192 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1193 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1197 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1198 evas_object_pass_events_set(cw->obj, pass_event_flag);
1203 /////////////////////////////////////////////
1206 _e_comp_object_animating_begin(E_Comp_Object *cw)
1209 if (cw->animating == 1)
1211 e_comp->animating++;
1213 e_object_ref(E_OBJECT(cw->ec));
1218 _e_comp_object_animating_end(E_Comp_Object *cw)
1227 if (cw->ec->launching)
1229 if (!cw->ec->extra_animating)
1231 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1232 cw->ec->launching = EINA_FALSE;
1233 if (cw->ec->first_mapped)
1235 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1236 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1239 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1243 e_comp->animating--;
1244 cw->showing = cw->hiding = 0;
1246 if (e_comp->animating == 0)
1247 e_comp_visibility_calculation_set(EINA_TRUE);
1248 /* remove ref from animation start, account for possibility of deletion from unref */
1249 return !!e_object_unref(E_OBJECT(cw->ec));
1255 /* handle the end of a compositor animation */
1257 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1259 E_Comp_Object *cw = data;
1261 /* visible clients which have never been sized are a bug */
1262 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1263 CRI("ACK! ec:%p", cw->ec);
1264 if (!_e_comp_object_animating_end(cw)) return;
1265 if (cw->animating) return;
1266 /* hide only after animation finishes to guarantee a full run of the animation */
1267 if (!cw->defer_hide) return;
1268 if ((!strcmp(emission, "e,action,hide,done")) ||
1269 (!strcmp(emission, "e,action,done")) ||
1270 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1272 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1273 evas_object_hide(cw->smart_obj);
1277 /* run a visibility compositor effect if available, return false if object is dead */
1279 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1285 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1286 if (!cw->effect_running)
1287 _e_comp_object_animating_begin(cw);
1288 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1289 return _e_comp_object_animating_end(cw);
1290 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1291 return _e_comp_object_animating_end(cw);
1293 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1296 zone = e_comp_zone_find_by_ec(cw->ec);
1298 zw = zone->w, zh = zone->h;
1303 zone = e_comp_object_util_zone_get(cw->smart_obj);
1304 if (!zone) zone = e_zone_current_get();
1311 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1312 cw->w, cw->h, zw, zh, x, y}, 8);
1313 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1314 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1317 /////////////////////////////////////////////
1319 /* create necessary objects for clients that e manages */
1321 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1323 if (cw->set_mouse_callbacks) return;
1324 if (!cw->smart_obj) return;
1326 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1327 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1328 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1329 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1330 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1331 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1333 cw->set_mouse_callbacks = EINA_TRUE;
1337 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1339 if (!cw->set_mouse_callbacks) return;
1340 if (!cw->smart_obj) return;
1342 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1343 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1344 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1345 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1346 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1347 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1349 cw->set_mouse_callbacks = EINA_FALSE;
1353 _e_comp_object_setup(E_Comp_Object *cw)
1355 cw->clip = evas_object_rectangle_add(e_comp->evas);
1356 evas_object_move(cw->clip, -9999, -9999);
1357 evas_object_resize(cw->clip, 999999, 999999);
1358 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1359 cw->effect_obj = edje_object_add(e_comp->evas);
1360 evas_object_move(cw->effect_obj, cw->x, cw->y);
1361 evas_object_clip_set(cw->effect_obj, cw->clip);
1362 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1363 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1364 cw->shobj = edje_object_add(e_comp->evas);
1365 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1366 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1367 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1369 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1370 if (cw->ec->override)
1372 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1373 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1374 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1376 else if (!cw->ec->input_only)
1378 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1379 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1380 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1382 cw->real_hid = !cw->ec->input_only;
1383 if (!cw->ec->input_only)
1385 e_util_size_debug_set(cw->effect_obj, 1);
1386 _e_comp_object_mouse_event_callback_set(cw);
1389 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1390 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1391 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1392 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1393 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1394 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1396 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1399 /////////////////////////////////////////////
1401 /* for fast path evas rendering; only called during render */
1403 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1405 E_Comp_Object *cw = data;
1406 E_Client *ec = cw->ec;
1408 int bx, by, bxx, byy;
1410 if (e_object_is_del(E_OBJECT(ec))) return;
1411 if (cw->external_content) return;
1412 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1413 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1416 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1417 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1419 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1421 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1422 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1426 bx = by = bxx = byy = 0;
1427 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1430 Edje_Message_Int_Set *msg;
1431 Edje_Message_Int msg2;
1432 Eina_Bool id = (bx || by || bxx || byy);
1434 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1440 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1442 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1446 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1447 e_comp_client_post_update_add(cw->ec);
1449 else if (e_comp_object_render(ec->frame))
1451 /* apply shape mask if necessary */
1452 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1453 e_comp_object_shape_apply(ec->frame);
1454 ec->shape_changed = 0;
1456 /* shaped clients get precise mouse events to handle transparent pixels */
1457 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1459 /* queue another render if client is still dirty; cannot refresh here. */
1460 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1461 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1463 if (cw->render_trace)
1465 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1471 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1473 E_Comp_Object *cw = data;
1474 E_Client *ec = cw->ec;
1476 if (e_object_is_del(E_OBJECT(ec))) return;
1477 if (cw->external_content) return;
1478 if (!e_comp->hwc) return;
1480 e_comp_client_render_list_add(cw->ec);
1482 if (!ec->hwc_window) return;
1484 e_hwc_windows_rendered_window_add(ec->hwc_window);
1487 /////////////////////////////////////////////
1490 _e_comp_object_client_pending_resize_add(E_Client *ec,
1493 unsigned int serial)
1495 E_Client_Pending_Resize *pnd;
1497 pnd = E_NEW(E_Client_Pending_Resize, 1);
1501 pnd->serial = serial;
1502 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1506 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1508 E_Comp_Object *cw = data;
1511 if (cw->render_update_lock.lock)
1513 cw->render_update_lock.pending_move_x = x;
1514 cw->render_update_lock.pending_move_y = y;
1515 cw->render_update_lock.pending_move_set = EINA_TRUE;
1519 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1520 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1521 (cw->external_content))
1523 /* delay to move until the external content is unset */
1524 cw->ec->changes.pos = 1;
1529 if (cw->ec->move_after_resize)
1531 if ((x != cw->ec->x) || (y != cw->ec->y))
1533 if (!cw->ec->is_cursor)
1534 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1535 e_client_pos_set(cw->ec, x, y);
1536 cw->ec->changes.pos = 1;
1542 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1543 (cw->ec->manage_resize.resize_obj))
1545 e_client_pos_set(cw->ec, x, y);
1546 cw->ec->client.x = x + cw->client_inset.l;
1547 cw->ec->client.y = y + cw->client_inset.t;
1548 e_policy_visibility_client_defer_move(cw->ec);
1552 /* if frame_object does not exist, client_inset indicates CSD.
1553 * this means that ec->client matches cw->x/y, the opposite
1556 fx = (!cw->frame_object) * cw->client_inset.l;
1557 fy = (!cw->frame_object) * cw->client_inset.t;
1558 if ((cw->x == x + fx) && (cw->y == y + fy))
1560 if ((cw->ec->x != x) || (cw->ec->y != y))
1562 /* handle case where client tries to move to position and back very quickly */
1563 e_client_pos_set(cw->ec, x, y);
1564 cw->ec->client.x = x + cw->client_inset.l;
1565 cw->ec->client.y = y + cw->client_inset.t;
1569 if (!cw->ec->maximize_override)
1571 /* prevent moving in some directions while directionally maximized */
1572 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1574 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1577 ix = x + cw->client_inset.l;
1578 iy = y + cw->client_inset.t;
1579 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1580 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1581 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1583 /* prevent moving at all if move isn't allowed in current maximize state */
1584 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1585 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1586 if ((!cw->ec->shading) && (!cw->ec->shaded))
1589 zone = e_comp_zone_find_by_ec(cw->ec);
1592 cw->ec->changes.need_unmaximize = 1;
1593 cw->ec->saved.x = ix - zone->x;
1594 cw->ec->saved.y = iy - zone->y;
1595 cw->ec->saved.w = cw->ec->client.w;
1596 cw->ec->saved.h = cw->ec->client.h;
1602 /* only update during resize if triggered by resize */
1603 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1604 /* delay to move while surface waits paired commit serial*/
1605 if (e_client_pending_geometry_has(cw->ec))
1607 /* do nothing while waiting paired commit serial*/
1611 e_client_pos_set(cw->ec, x, y);
1612 if (cw->ec->new_client)
1614 /* don't actually do anything until first client idler loop */
1615 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1616 cw->ec->changes.pos = 1;
1621 /* only update xy position of client to avoid invalid
1622 * first damage region if it is not a new_client. */
1623 if (!cw->ec->shading)
1625 cw->ec->client.x = ix;
1626 cw->ec->client.y = iy;
1629 if (!cw->frame_object)
1631 evas_object_move(obj, x, y);
1636 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1638 E_Comp_Object *cw = data;
1639 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1642 if (cw->render_update_lock.lock)
1644 cw->render_update_lock.pending_resize_w = w;
1645 cw->render_update_lock.pending_resize_h = h;
1646 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1650 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1652 e_client_size_set(cw->ec, w, h);
1653 evas_object_resize(obj, w, h);
1657 /* if frame_object does not exist, client_inset indicates CSD.
1658 * this means that ec->client matches cw->w/h, the opposite
1661 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1662 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1663 if ((cw->w == w + fw) && (cw->h == h + fh))
1665 if (cw->ec->shading || cw->ec->shaded) return;
1666 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1667 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1668 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1670 /* handle case where client tries to resize itself and back very quickly */
1671 e_client_size_set(cw->ec, w, h);
1672 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1673 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1674 evas_object_smart_callback_call(obj, "client_resize", NULL);
1678 /* guarantee that fullscreen is fullscreen */
1679 zone = e_comp_zone_find_by_ec(cw->ec);
1681 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1683 if (!e_client_transform_core_enable_get(cw->ec))
1686 /* calculate client size */
1687 iw = w - cw->client_inset.l - cw->client_inset.r;
1688 ih = h - cw->client_inset.t - cw->client_inset.b;
1689 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1691 /* prevent resizing while maximized depending on direction and config */
1692 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1693 if ((!cw->ec->shading) && (!cw->ec->shaded))
1695 Eina_Bool reject = EINA_FALSE;
1696 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1698 if (cw->ec->client.h != ih)
1700 cw->ec->saved.h = ih;
1701 cw->ec->saved.y = cw->ec->client.y - zone->y;
1702 reject = cw->ec->changes.need_unmaximize = 1;
1705 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1707 if (cw->ec->client.w != iw)
1709 cw->ec->saved.w = iw;
1710 cw->ec->saved.x = cw->ec->client.x - zone->x;
1711 reject = cw->ec->changes.need_unmaximize = 1;
1721 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1723 /* do nothing until client idler loops */
1724 if ((cw->ec->w != w) || (cw->ec->h != h))
1726 e_client_size_set(cw->ec, w, h);
1727 cw->ec->changes.size = 1;
1732 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1733 ((cw->ec->w != w) || (cw->ec->h != h)))
1736 /* netwm sync resizes queue themselves and then trigger later on */
1737 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1739 if (e_client_pending_geometry_has(cw->ec))
1741 /* do nothing while waiting paired commit serial*/
1745 e_client_size_set(cw->ec, w, h);
1746 if ((!cw->ec->shading) && (!cw->ec->shaded))
1748 /* client geom never changes when shading since the client is never altered */
1749 cw->ec->client.w = iw;
1750 cw->ec->client.h = ih;
1751 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1754 /* The size of non-compositing window can be changed, so there is a
1755 * need to check that cw is H/W composited if cw is not redirected.
1756 * And of course we have to change size of evas object of H/W composited cw,
1757 * otherwise cw can't receive input events even if it is shown on the screen.
1759 Eina_Bool redirected = cw->redirected;
1761 redirected = e_comp_is_on_overlay(cw->ec);
1763 if ((!cw->ec->input_only) && (redirected) &&
1764 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1765 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1766 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1767 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1770 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1771 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1773 prev_w = cw->w, prev_h = cw->h;
1774 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1775 /* check shading and clamp to pixmap size for regular clients */
1776 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1777 (((w - fw != pw) || (h - fh != ph))))
1779 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1780 evas_object_smart_callback_call(obj, "client_resize", NULL);
1782 if (cw->frame_object || cw->ec->input_only)
1783 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1786 if ((cw->w == w) && (cw->h == h))
1788 /* going to be a noop resize which won't trigger smart resize */
1789 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1790 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1792 evas_object_resize(obj, w, h);
1796 evas_object_smart_callback_call(obj, "client_resize", NULL);
1799 if ((!cw->frame_object) && (!cw->ec->input_only))
1801 /* "just do it" for overrides */
1802 evas_object_resize(obj, w, h);
1804 if (!cw->ec->override)
1806 /* shape probably changed for non-overrides */
1807 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1808 cw->ec->need_shape_export |= cw->ec->shaped;
1809 if (cw->ec->shaped || cw->ec->shaped_input)
1813 /* this fixes positioning jiggles when using a resize mode
1814 * which also changes the client's position
1817 if (cw->frame_object)
1818 x = cw->x, y = cw->y;
1820 x = cw->ec->x, y = cw->ec->y;
1821 switch (cw->ec->resize_mode)
1823 case E_POINTER_RESIZE_BL:
1824 case E_POINTER_RESIZE_L:
1825 evas_object_move(obj, x + prev_w - cw->w, y);
1827 case E_POINTER_RESIZE_TL:
1828 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1830 case E_POINTER_RESIZE_T:
1831 case E_POINTER_RESIZE_TR:
1832 evas_object_move(obj, x, y + prev_h - cw->h);
1841 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1843 E_Comp_Object *cw = data;
1844 E_Comp_Wl_Client_Data *child_cdata;
1845 unsigned int l = e_comp_canvas_layer_map(layer);
1848 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1850 /* doing a compositor effect, follow directions */
1851 _e_comp_object_layer_set(obj, layer);
1852 if (layer == cw->ec->layer) //trying to put layer back
1856 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1857 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1858 if (cw->layer != l) goto layer_set;
1862 e_comp_render_queue();
1864 ec = e_client_above_get(cw->ec);
1865 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1866 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1867 ec = e_client_above_get(ec);
1868 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1870 ec = e_client_below_get(cw->ec);
1871 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1872 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1873 ec = e_client_below_get(ec);
1874 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1876 evas_object_stack_above(obj, ec->frame);
1881 if (ec && (cw->ec->parent == ec))
1883 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1884 evas_object_stack_above(obj, ec->frame);
1886 evas_object_stack_below(obj, ec->frame);
1889 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1895 if (cw->layer == l) return;
1896 if (e_comp_canvas_client_layer_map(layer) == 9999)
1897 return; //invalid layer for clients not doing comp effects
1898 if (cw->ec->fullscreen)
1900 cw->ec->saved.layer = layer;
1903 oldraise = e_config->transient.raise;
1905 /* clamp to valid client layer */
1906 layer = e_comp_canvas_client_layer_map_nearest(layer);
1907 cw->ec->layer = layer;
1908 if (e_config->transient.layer)
1911 Eina_List *list = eina_list_clone(cw->ec->transients);
1913 /* We need to set raise to one, else the child wont
1914 * follow to the new layer. It should be like this,
1915 * even if the user usually doesn't want to raise
1918 e_config->transient.raise = 1;
1919 EINA_LIST_FREE(list, child)
1921 child_cdata = e_client_cdata_get(child);
1922 if (child_cdata && !child_cdata->mapped)
1924 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1927 e_client_layer_set(child, layer);
1931 e_config->transient.raise = oldraise;
1933 _e_comp_object_layers_remove(cw);
1934 cw->layer = e_comp_canvas_layer_map(layer);
1935 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1936 //if (cw->ec->new_client)
1937 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1938 _e_comp_object_layer_set(obj, layer);
1939 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1940 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1941 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1943 /* can't stack a client above its own layer marker */
1944 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1946 if (!cw->visible) return;
1947 e_comp_render_queue();
1948 _e_comp_object_transform_obj_stack_update(obj);
1951 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1954 _e_comp_object_raise(Evas_Object *obj)
1956 evas_object_raise(obj);
1958 if (evas_object_smart_smart_get(obj))
1960 E_Client *ec = e_comp_object_client_get(obj);
1962 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1967 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1969 evas_object_lower(obj);
1971 if (evas_object_smart_smart_get(obj))
1973 E_Client *ec = e_comp_object_client_get(obj);
1976 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1977 wl_signal_emit_mutable(&cw->events.lower, NULL);
1983 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1985 evas_object_stack_above(obj, target);
1987 if (evas_object_smart_smart_get(obj))
1989 E_Client *ec = e_comp_object_client_get(obj);
1991 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1996 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1998 evas_object_stack_below(obj, target);
2000 if (evas_object_smart_smart_get(obj))
2002 E_Client *ec = e_comp_object_client_get(obj);
2004 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2009 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2011 evas_object_layer_set(obj, layer);
2013 if (evas_object_smart_smart_get(obj))
2015 E_Client *ec = e_comp_object_client_get(obj);
2017 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2022 _e_comp_object_is_pending(E_Client *ec)
2026 if (!ec) return EINA_FALSE;
2028 topmost = e_comp_wl_topmost_parent_get(ec);
2030 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2034 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2036 E_Comp_Object *cw2 = NULL;
2039 Evas_Object *o = stack;
2040 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2042 /* We should consider topmost's layer_pending for subsurface */
2043 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2045 if (_e_comp_object_is_pending(cw->ec))
2046 e_comp_object_layer_update(cw->smart_obj,
2047 raising? stack : NULL,
2048 raising? NULL : stack);
2050 /* obey compositor effects! */
2051 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2052 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2053 stack_cb(cw->smart_obj, stack);
2054 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2055 evas_object_data_del(cw->smart_obj, "client_restack");
2059 cw2 = evas_object_data_get(o, "comp_obj");
2061 /* assume someone knew what they were doing during client init */
2062 if (cw->ec->new_client)
2063 layer = cw->ec->layer;
2064 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2065 layer = cw2->ec->layer;
2067 layer = evas_object_layer_get(stack);
2068 ecstack = e_client_below_get(cw->ec);
2069 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2071 evas_object_layer_set(cw->smart_obj, layer);
2072 /* we got our layer wrangled, return now! */
2073 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2076 /* check if we're stacking below another client */
2079 /* check for non-client layer object */
2080 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2082 /* find an existing client to use for layering
2083 * by walking up the object stack
2085 * this is guaranteed to be pretty quick since we'll either:
2086 * - run out of client layers
2087 * - find a stacking client
2089 o = evas_object_above_get(o);
2090 if ((!o) || (o == cw->smart_obj)) break;
2091 if (evas_object_layer_get(o) != layer)
2093 /* reached the top client layer somehow
2094 * use top client object
2096 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2099 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2100 * return here since the top client layer window
2105 ec = e_client_top_get();
2110 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2113 if (cw2 && cw->layer != cw2->layer)
2116 /* remove existing layers */
2117 _e_comp_object_layers_remove(cw);
2120 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2121 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2122 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2123 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2124 else //if no stacking objects found, either raise or lower
2125 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2128 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2130 /* find new object for stacking if cw2 is on state of layer_pending */
2131 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2133 E_Client *new_stack = NULL, *current_ec = NULL;
2134 current_ec = cw2->ec;
2137 while ((new_stack = e_client_below_get(current_ec)))
2139 current_ec = new_stack;
2140 if (new_stack == cw->ec) continue;
2141 if (new_stack->layer != cw2->ec->layer) break;
2142 if (!_e_comp_object_is_pending(new_stack)) break;
2144 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2145 stack = new_stack->frame;
2148 /* stack it above layer object */
2150 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2151 stack = e_comp->layers[below_layer].obj;
2156 while ((new_stack = e_client_above_get(current_ec)))
2158 current_ec = new_stack;
2159 if (new_stack == cw->ec) continue;
2160 if (new_stack->layer != cw2->ec->layer) break;
2161 if (!_e_comp_object_is_pending(new_stack)) break;
2163 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2164 stack = new_stack->frame;
2166 stack = e_comp->layers[cw2->layer].obj;
2170 /* set restack if stacking has changed */
2171 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2172 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2173 stack_cb(cw->smart_obj, stack);
2174 if (e_comp->layers[cw->layer].obj)
2175 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2177 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2179 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2180 evas_object_data_del(cw->smart_obj, "client_restack");
2181 if (!cw->visible) return;
2182 e_comp_render_queue();
2186 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2188 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2190 if (evas_object_below_get(obj) == above)
2192 e_comp_object_layer_update(obj, above, NULL);
2196 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2197 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2198 _e_comp_object_transform_obj_stack_update(obj);
2199 _e_comp_object_transform_obj_stack_update(above);
2204 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2206 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2207 if (evas_object_above_get(obj) == below)
2209 e_comp_object_layer_update(obj, NULL, below);
2213 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2214 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2215 if (evas_object_smart_smart_get(obj))
2216 _e_comp_object_transform_obj_stack_update(obj);
2217 if (evas_object_smart_smart_get(below))
2218 _e_comp_object_transform_obj_stack_update(below);
2223 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2225 E_Comp_Object *cw = data;
2228 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2230 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2232 if (cw->ec->layer_pending)
2233 e_comp_object_layer_update(obj, NULL, obj);
2235 _e_comp_object_lower(cw, obj);
2238 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2239 o = evas_object_below_get(obj);
2240 _e_comp_object_layers_remove(cw);
2241 /* prepend to client list since this client should be the first item now */
2242 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2243 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2244 evas_object_data_set(obj, "client_restack", (void*)1);
2245 _e_comp_object_lower(cw, obj);
2246 evas_object_data_del(obj, "client_restack");
2247 if (!cw->visible) goto end;
2248 e_comp_render_queue();
2249 _e_comp_object_transform_obj_stack_update(obj);
2256 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2258 E_Comp_Object *cw = data;
2262 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2264 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2266 if (cw->ec->layer_pending)
2268 int obj_layer = evas_object_layer_get(obj);
2269 if (cw->ec->layer != obj_layer)
2270 e_comp_object_layer_update(obj, NULL, NULL);
2273 _e_comp_object_raise(obj);
2276 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2277 o = evas_object_above_get(obj);
2278 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2280 /* still stack below override below the layer marker */
2281 for (op = o = e_comp->layers[cw->layer].obj;
2282 o && o != e_comp->layers[cw->layer - 1].obj;
2283 op = o, o = evas_object_below_get(o))
2285 if (evas_object_smart_smart_get(o))
2289 ec = e_comp_object_client_get(o);
2290 if (ec && (!ec->override)) break;
2293 _e_comp_object_stack_below(obj, op);
2294 e_client_focus_defer_set(cw->ec);
2296 if (!cw->visible) goto end;
2297 e_comp_render_queue();
2298 _e_comp_object_transform_obj_stack_update(obj);
2305 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2307 E_Comp_Object *cw = data;
2309 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2310 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2312 ELOGF("COMP", "Hide. intercepted", cw->ec);
2317 if (cw->ec->launching == EINA_TRUE)
2319 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2320 cw->ec->launching = EINA_FALSE;
2325 /* hidden flag = just do it */
2326 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2327 evas_object_hide(obj);
2329 wl_signal_emit_mutable(&cw->events.hide, NULL);
2334 if (cw->ec->input_only)
2336 /* input_only = who cares */
2337 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2338 evas_object_hide(obj);
2340 wl_signal_emit_mutable(&cw->events.hide, NULL);
2344 /* already hidden or currently animating */
2345 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2347 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2351 /* don't try hiding during shutdown */
2352 cw->defer_hide |= stopping;
2353 if (!cw->defer_hide)
2355 if ((!cw->ec->iconic) && (!cw->ec->override))
2356 /* unset delete requested so the client doesn't break */
2357 cw->ec->delete_requested = 0;
2358 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2360 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2361 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2364 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2367 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2369 _e_comp_object_animating_begin(cw);
2370 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2372 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2373 cw->defer_hide = !!cw->animating;
2375 e_comp_object_effect_set(obj, NULL);
2378 if (cw->animating) return;
2379 /* if we have no animations running, go ahead and hide */
2381 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2382 evas_object_hide(obj);
2384 wl_signal_emit_mutable(&cw->events.hide, NULL);
2388 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2390 E_Client *ec = cw->ec;
2393 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2395 if (ec->show_pending.count > 0)
2397 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2398 ec->show_pending.running = EINA_TRUE;
2402 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2403 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2405 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2410 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,
2411 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2412 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2415 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2418 if (ec->iconic && cw->animating)
2420 /* triggered during iconify animation */
2421 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2424 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2427 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2428 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2430 evas_object_move(cw->smart_obj, ec->x, ec->y);
2431 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2432 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2434 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2435 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2438 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2439 evas_object_show(cw->smart_obj);
2442 e_client_focus_defer_set(ec);
2446 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2450 pw = ec->client.w, ph = ec->client.h;
2452 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2454 ec->changes.visible = !ec->hidden;
2457 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2461 cw->updates = eina_tiler_new(pw, ph);
2464 ec->changes.visible = !ec->hidden;
2467 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2472 eina_tiler_tile_size_set(cw->updates, 1, 1);
2475 /* ignore until client idler first run */
2476 ec->changes.visible = !ec->hidden;
2479 ELOGF("COMP", "show_helper. return. new_client", ec);
2486 evas_object_move(cw->smart_obj, ec->x, ec->y);
2487 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2488 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2489 evas_object_show(cw->smart_obj);
2492 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2494 /* start_drag not received */
2495 ec->changes.visible = 1;
2498 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2501 /* re-set geometry */
2502 evas_object_move(cw->smart_obj, ec->x, ec->y);
2503 /* force resize in case it hasn't happened yet, or just to update size */
2504 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2505 if ((cw->w < 1) || (cw->h < 1))
2507 /* if resize didn't go through, try again */
2508 ec->visible = ec->changes.visible = 1;
2510 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2513 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2514 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2515 e_pixmap_clear(ec->pixmap);
2517 if (cw->real_hid && w && h)
2520 /* force comp theming in case it didn't happen already */
2521 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2522 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2523 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2526 /* only do the show if show is allowed */
2529 if (ec->internal) //internal clients render when they feel like it
2530 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2532 if (!e_client_is_iconified_by_client(ec)||
2533 e_policy_visibility_client_is_uniconic(ec))
2535 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2536 evas_object_show(cw->smart_obj);
2538 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2539 it is rendered in idle callback without native surface and
2540 compositor shows an empty frame if other objects aren't shown
2541 because job callback of e_comp called at the next loop.
2542 it causes a visual defect when windows are switched.
2546 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2547 e_comp_object_dirty(cw->smart_obj);
2548 e_comp_object_render(cw->smart_obj);
2553 wl_signal_emit_mutable(&cw->events.show, NULL);
2557 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2559 E_Comp_Object *cw = data;
2560 E_Client *ec = cw->ec;
2562 E_Input_Rect_Data *input_rect_data;
2563 E_Input_Rect_Smart_Data *input_rect_sd;
2566 if (ec->ignored) return;
2570 //INF("SHOW2 %p", ec);
2571 _e_comp_intercept_show_helper(cw);
2574 //INF("SHOW %p", ec);
2577 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2578 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2579 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2580 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2584 if ((!cw->obj) && (cw->external_content))
2586 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2590 _e_comp_object_setup(cw);
2593 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2594 cw->obj = evas_object_image_filled_add(e_comp->evas);
2595 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2596 e_util_size_debug_set(cw->obj, 1);
2597 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2598 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2599 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2600 evas_object_name_set(cw->obj, "cw->obj");
2601 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2603 _e_comp_object_alpha_set(cw);
2606 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2609 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2610 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2613 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2616 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2618 if (input_rect_data->obj)
2620 evas_object_geometry_set(input_rect_data->obj,
2621 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2622 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2623 input_rect_data->rect.w, input_rect_data->rect.h);
2630 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2632 _e_comp_intercept_show_helper(cw);
2636 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2638 E_Comp_Object *cw = data;
2642 /* note: this is here as it seems there are enough apps that do not even
2643 * expect us to emulate a look of focus but not actually set x input
2644 * focus as we do - so simply abort any focus set on such windows */
2645 /* be strict about accepting focus hint */
2646 /* be strict about accepting focus hint */
2647 if ((!ec->icccm.accepts_focus) &&
2648 (!ec->icccm.take_focus))
2652 if (e_client_focused_get() == ec)
2653 e_client_focused_set(NULL);
2655 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2656 evas_object_focus_set(obj, focus);
2660 if (focus && ec->lock_focus_out) return;
2661 if (e_object_is_del(E_OBJECT(ec)) && focus)
2662 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2664 /* filter focus setting based on current state */
2669 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2670 evas_object_focus_set(obj, focus);
2673 if ((ec->iconic) && (!ec->deskshow))
2675 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2677 /* don't focus an iconified window. that's silly! */
2678 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2679 e_client_uniconify(ec);
2680 e_client_focus_latest_set(ec);
2694 /* not yet visible, wait till the next time... */
2695 ec->want_focus = !ec->hidden;
2700 e_client_focused_set(ec);
2704 if (e_client_focused_get() == ec)
2705 e_client_focused_set(NULL);
2709 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2711 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2713 evas_object_focus_set(obj, focus);
2717 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2719 E_Comp_Object *cw = data;
2721 if (cw->transparent.set)
2723 cw->transparent.user_r = r;
2724 cw->transparent.user_g = g;
2725 cw->transparent.user_b = b;
2726 cw->transparent.user_a = a;
2728 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2730 cw->transparent.user_r,
2731 cw->transparent.user_g,
2732 cw->transparent.user_b,
2733 cw->transparent.user_a);
2737 evas_object_color_set(obj, r, g, b, a);
2740 ////////////////////////////////////////////////////
2743 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2745 int w, h, ox, oy, ow, oh;
2747 Eina_Bool pass_event_flag = EINA_FALSE;
2748 E_Input_Rect_Data *input_rect_data;
2749 E_Input_Rect_Smart_Data *input_rect_sd;
2751 if (cw->frame_object)
2753 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2754 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2755 /* set a fixed size, force edje calc, check size difference */
2756 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2757 edje_object_message_signal_process(cw->frame_object);
2758 edje_object_calc_force(cw->frame_object);
2759 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2760 cw->client_inset.l = ox;
2761 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2762 cw->client_inset.t = oy;
2763 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2764 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2765 evas_object_resize(cw->frame_object, w, h);
2769 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2772 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2774 if (input_rect_data->obj)
2776 pass_event_flag = EINA_TRUE;
2782 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2783 evas_object_pass_events_set(cw->obj, pass_event_flag);
2787 cw->client_inset.l = 0;
2788 cw->client_inset.r = 0;
2789 cw->client_inset.t = 0;
2790 cw->client_inset.b = 0;
2792 cw->client_inset.calc = !!cw->frame_object;
2796 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2798 E_Comp_Object *cw = data;
2802 /* - get current size
2804 * - readjust for new frame size
2807 w = cw->ec->w, h = cw->ec->h;
2808 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2810 _e_comp_object_frame_recalc(cw);
2812 if (!cw->ec->fullscreen)
2813 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2815 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2816 if (cw->ec->shading || cw->ec->shaded) return;
2817 if (cw->ec->fullscreen)
2819 zone = e_comp_zone_find_by_ec(cw->ec);
2821 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2823 else if (cw->ec->new_client)
2825 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2826 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2827 evas_object_resize(cw->ec->frame, w, h);
2829 else if ((w != cw->ec->w) || (h != cw->ec->h))
2830 evas_object_resize(cw->ec->frame, w, h);
2834 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2836 E_Comp_Object *cw = data;
2838 if (!cw->ec) return; //NYI
2839 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2841 cw->shade.x = cw->x;
2842 cw->shade.y = cw->y;
2843 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2847 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2849 E_Comp_Object *cw = data;
2851 if (!cw->ec) return; //NYI
2852 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2854 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2858 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2860 E_Comp_Object *cw = data;
2862 if (!cw->ec) return; //NYI
2863 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2865 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2869 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2871 E_Comp_Object *cw = data;
2873 if (!cw->ec) return; //NYI
2874 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2876 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2880 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2882 E_Comp_Object *cw = data;
2884 _e_comp_object_shadow_setup(cw);
2885 if (cw->frame_object)
2887 _e_comp_object_shadow(cw);
2888 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2889 _e_comp_object_frame_recalc(cw);
2890 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2895 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2897 E_Comp_Object *cw = data;
2899 if (_e_comp_object_shadow_setup(cw))
2900 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2901 if (cw->frame_object)
2903 _e_comp_object_shadow(cw);
2904 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2905 _e_comp_object_frame_recalc(cw);
2906 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2911 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2913 E_Comp_Object *cw = data;
2915 if (cw->frame_object)
2917 _e_comp_object_shadow(cw);
2918 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2919 _e_comp_object_frame_recalc(cw);
2920 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2925 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2927 E_Comp_Object *cw = data;
2929 if (_e_comp_object_shadow_setup(cw))
2932 cw->ec->changes.size = 1;
2934 if (cw->frame_object)
2936 _e_comp_object_shadow(cw);
2937 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2938 _e_comp_object_frame_recalc(cw);
2939 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2944 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2946 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2950 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2952 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2956 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2958 E_Comp_Object *cw = data;
2960 if (!cw->ec) return; //NYI
2961 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2965 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2967 E_Comp_Object *cw = data;
2969 if (!cw->ec) return; //NYI
2970 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2974 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2976 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2980 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2982 E_Comp_Object *cw = data;
2984 if (!e_object_is_del(E_OBJECT(cw->ec)))
2985 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2989 _e_comp_input_obj_smart_add(Evas_Object *obj)
2991 E_Input_Rect_Smart_Data *input_rect_sd;
2992 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2994 if (!input_rect_sd) return;
2995 evas_object_smart_data_set(obj, input_rect_sd);
2999 _e_comp_input_obj_smart_del(Evas_Object *obj)
3001 E_Input_Rect_Smart_Data *input_rect_sd;
3002 E_Input_Rect_Data *input_rect_data;
3004 input_rect_sd = evas_object_smart_data_get(obj);
3005 if (!input_rect_sd) return;
3007 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3009 if (input_rect_data->obj)
3011 evas_object_smart_member_del(input_rect_data->obj);
3012 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3014 E_FREE(input_rect_data);
3016 E_FREE(input_rect_sd);
3020 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3022 E_Input_Rect_Smart_Data *input_rect_sd;
3023 E_Input_Rect_Data *input_rect_data;
3027 input_rect_sd = evas_object_smart_data_get(obj);
3028 if (!input_rect_sd) return;
3030 cw = input_rect_sd->cw;
3031 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3033 if (input_rect_data->obj)
3035 evas_object_geometry_set(input_rect_data->obj,
3036 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3037 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3038 input_rect_data->rect.w, input_rect_data->rect.h);
3044 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3046 E_Input_Rect_Smart_Data *input_rect_sd;
3047 E_Input_Rect_Data *input_rect_data;
3051 input_rect_sd = evas_object_smart_data_get(obj);
3052 if (!input_rect_sd) return;
3054 cw = input_rect_sd->cw;
3055 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3057 if (input_rect_data->obj)
3059 evas_object_geometry_set(input_rect_data->obj,
3060 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3061 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3062 input_rect_data->rect.w, input_rect_data->rect.h);
3068 _e_comp_input_obj_smart_show(Evas_Object *obj)
3070 E_Input_Rect_Smart_Data *input_rect_sd;
3071 E_Input_Rect_Data *input_rect_data;
3074 input_rect_sd = evas_object_smart_data_get(obj);
3075 if (!input_rect_sd) return;
3077 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3079 if (input_rect_data->obj)
3081 evas_object_show(input_rect_data->obj);
3087 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3089 E_Input_Rect_Smart_Data *input_rect_sd;
3090 E_Input_Rect_Data *input_rect_data;
3093 input_rect_sd = evas_object_smart_data_get(obj);
3094 if (!input_rect_sd) return;
3096 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3098 if (input_rect_data->obj)
3100 evas_object_hide(input_rect_data->obj);
3106 _e_comp_input_obj_smart_init(void)
3108 if (_e_comp_input_obj_smart) return;
3110 static const Evas_Smart_Class sc =
3112 INPUT_OBJ_SMART_NAME,
3113 EVAS_SMART_CLASS_VERSION,
3114 _e_comp_input_obj_smart_add,
3115 _e_comp_input_obj_smart_del,
3116 _e_comp_input_obj_smart_move,
3117 _e_comp_input_obj_smart_resize,
3118 _e_comp_input_obj_smart_show,
3119 _e_comp_input_obj_smart_hide,
3132 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3138 _e_comp_smart_add(Evas_Object *obj)
3142 cw = E_NEW(E_Comp_Object, 1);
3143 EINA_SAFETY_ON_NULL_RETURN(cw);
3145 wl_signal_init(&cw->events.lower);
3146 wl_signal_init(&cw->events.show);
3147 wl_signal_init(&cw->events.hide);
3149 cw->smart_obj = obj;
3150 cw->x = cw->y = cw->w = cw->h = -1;
3151 evas_object_smart_data_set(obj, cw);
3152 cw->opacity = 255.0;
3153 cw->external_content = 0;
3154 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3155 cw->transform_bg_color.r = 0;
3156 cw->transform_bg_color.g = 0;
3157 cw->transform_bg_color.b = 0;
3158 cw->transform_bg_color.a = 255;
3159 evas_object_data_set(obj, "comp_obj", cw);
3160 evas_object_move(obj, -1, -1);
3161 /* intercept ALL the callbacks! */
3162 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3163 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3164 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3165 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3166 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3167 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3168 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3169 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3170 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3171 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3172 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3174 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3175 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3176 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3177 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3179 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3180 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3181 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3182 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3184 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3185 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3187 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3188 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3190 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3192 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3193 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3197 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3200 evas_object_color_set(cw->clip, r, g, b, a);
3201 evas_object_smart_callback_call(obj, "color_set", NULL);
3206 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3209 evas_object_clip_set(cw->clip, clip);
3213 _e_comp_smart_clip_unset(Evas_Object *obj)
3216 evas_object_clip_unset(cw->clip);
3220 _e_comp_smart_hide(Evas_Object *obj)
3222 TRACE_DS_BEGIN(COMP:SMART HIDE);
3227 evas_object_hide(cw->clip);
3228 if (cw->input_obj) evas_object_hide(cw->input_obj);
3229 evas_object_hide(cw->effect_obj);
3230 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3231 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3232 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3239 /* unset native surface if current displaying buffer was destroied */
3240 if (!cw->buffer_destroy_listener.notify)
3242 Evas_Native_Surface *ns;
3243 ns = evas_object_image_native_surface_get(cw->obj);
3244 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3245 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3248 if (!cw->ec->input_only)
3250 edje_object_freeze(cw->effect_obj);
3251 edje_object_freeze(cw->shobj);
3252 edje_object_play_set(cw->shobj, 0);
3253 if (cw->frame_object)
3254 edje_object_play_set(cw->frame_object, 0);
3257 e_comp_render_queue(); //force nocomp recheck
3263 _e_comp_smart_show(Evas_Object *obj)
3271 if ((cw->w < 0) || (cw->h < 0))
3272 CRI("ACK! ec:%p", cw->ec);
3274 TRACE_DS_BEGIN(COMP:SMART SHOW);
3276 e_comp_object_map_update(obj);
3278 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3279 evas_object_show(tmp->frame);
3281 evas_object_show(cw->clip);
3282 if (cw->input_obj) evas_object_show(cw->input_obj);
3283 if (!cw->ec->input_only)
3285 edje_object_thaw(cw->effect_obj);
3286 edje_object_thaw(cw->shobj);
3287 edje_object_play_set(cw->shobj, 1);
3288 if (cw->frame_object)
3289 edje_object_play_set(cw->frame_object, 1);
3291 evas_object_show(cw->effect_obj);
3292 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3293 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3294 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3295 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3296 e_comp_render_queue();
3297 if (cw->ec->input_only)
3302 if (cw->ec->iconic && (!cw->ec->new_client))
3304 if (e_client_is_iconified_by_client(cw->ec))
3306 ELOGF("COMP", "Set launching flag..", cw->ec);
3307 cw->ec->launching = EINA_TRUE;
3310 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3312 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3315 ELOGF("COMP", "Set launching flag..", cw->ec);
3316 cw->ec->launching = EINA_TRUE;
3318 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3319 _e_comp_object_animating_begin(cw);
3320 if (!_e_comp_object_effect_visibility_start(cw, 1))
3326 /* ensure some random effect doesn't lock the client offscreen */
3330 e_comp_object_effect_set(obj, NULL);
3333 _e_comp_object_dim_update(cw);
3339 _e_comp_smart_del(Evas_Object *obj)
3345 if (cw->buffer_destroy_listener.notify)
3347 wl_list_remove(&cw->buffer_destroy_listener.link);
3348 cw->buffer_destroy_listener.notify = NULL;
3351 if (cw->tbm_surface)
3353 tbm_surface_internal_unref(cw->tbm_surface);
3354 cw->tbm_surface = NULL;
3357 if (cw->render_update_lock.buffer_ref.buffer)
3359 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3360 cw->ec, cw->render_update_lock.lock);
3361 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3364 e_comp_object_render_update_del(cw->smart_obj);
3365 E_FREE_FUNC(cw->updates, eina_tiler_free);
3366 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3373 EINA_LIST_FREE(cw->obj_mirror, o)
3375 evas_object_image_data_set(o, NULL);
3376 evas_object_freeze_events_set(o, 1);
3377 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3381 _e_comp_object_layers_remove(cw);
3382 l = evas_object_data_get(obj, "comp_object-to_del");
3383 E_FREE_LIST(l, evas_object_del);
3384 _e_comp_object_mouse_event_callback_unset(cw);
3385 evas_object_del(cw->clip);
3386 evas_object_del(cw->obj);
3387 evas_object_del(cw->shobj);
3388 evas_object_del(cw->effect_obj);
3389 evas_object_del(cw->frame_object);
3390 evas_object_del(cw->input_obj);
3391 evas_object_del(cw->mask.obj);
3392 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3393 evas_object_del(cw->transform_bg_obj);
3394 evas_object_del(cw->transform_tranp_obj);
3395 evas_object_del(cw->default_input_obj);
3396 eina_stringshare_del(cw->frame_theme);
3397 eina_stringshare_del(cw->frame_name);
3401 e_comp->animating--;
3403 e_object_unref(E_OBJECT(cw->ec));
3405 cw->ec->frame = NULL;
3410 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3414 cw->x = x, cw->y = y;
3415 evas_object_move(cw->effect_obj, x, y);
3416 evas_object_move(cw->default_input_obj, x, y);
3417 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3419 e_comp_object_map_update(obj);
3423 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3425 Eina_Bool first = EINA_FALSE;
3430 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3432 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3434 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3436 if (cw->w != w || cw->h != h)
3437 e_comp_object_map_update(obj);
3439 first = ((cw->w < 1) || (cw->h < 1));
3440 cw->w = w, cw->h = h;
3441 if ((!cw->ec->shading) && (!cw->ec->shaded))
3445 if (cw->frame_object)
3446 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3449 /* verify pixmap:object size */
3450 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3452 if ((ww != pw) || (hh != ph))
3453 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3455 evas_object_resize(cw->effect_obj, tw, th);
3456 evas_object_resize(cw->default_input_obj, w, h);
3458 evas_object_resize(cw->input_obj, w, h);
3460 evas_object_resize(cw->mask.obj, w, h);
3461 /* resize render update tiler */
3464 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3465 cw->updates_full = 0;
3466 if (cw->updates) eina_tiler_clear(cw->updates);
3470 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3471 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3476 evas_object_resize(cw->effect_obj, tw, th);
3477 evas_object_resize(cw->default_input_obj, w, h);
3484 e_comp_render_queue();
3490 _e_comp_smart_init(void)
3492 if (_e_comp_smart) return;
3494 static const Evas_Smart_Class sc =
3497 EVAS_SMART_CLASS_VERSION,
3501 _e_comp_smart_resize,
3504 _e_comp_smart_color_set,
3505 _e_comp_smart_clip_set,
3506 _e_comp_smart_clip_unset,
3516 _e_comp_smart = evas_smart_class_new(&sc);
3521 e_comp_object_init(void)
3523 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3524 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3525 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3526 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3530 e_comp_object_shutdown(void)
3536 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3538 API_ENTRY EINA_FALSE;
3539 return !!cw->force_visible;
3541 /////////////////////////////////////////////////////////
3544 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3547 Eina_Bool comp_object;
3549 comp_object = !!evas_object_data_get(obj, "comp_object");
3554 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3556 e_comp_render_queue();
3558 l = evas_object_data_get(obj, "comp_object-to_del");
3559 E_FREE_LIST(l, evas_object_del);
3563 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3565 if (e_comp_util_object_is_above_nocomp(obj) &&
3566 (!evas_object_data_get(obj, "comp_override")))
3568 evas_object_data_set(obj, "comp_override", (void*)1);
3569 e_comp_override_add();
3574 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3576 Eina_Bool ref = EINA_TRUE;
3577 if (evas_object_visible_get(obj))
3581 d = evas_object_data_del(obj, "comp_hiding");
3583 /* currently trying to hide */
3586 /* already visible */
3590 evas_object_show(obj);
3593 evas_object_ref(obj);
3594 evas_object_data_set(obj, "comp_ref", (void*)1);
3596 edje_object_signal_emit(obj, "e,state,visible", "e");
3597 evas_object_data_set(obj, "comp_showing", (void*)1);
3598 if (e_comp_util_object_is_above_nocomp(obj))
3600 evas_object_data_set(obj, "comp_override", (void*)1);
3601 e_comp_override_add();
3606 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3608 if (!evas_object_visible_get(obj)) return;
3609 /* already hiding */
3610 if (evas_object_data_get(obj, "comp_hiding")) return;
3611 if (!evas_object_data_del(obj, "comp_showing"))
3613 evas_object_ref(obj);
3614 evas_object_data_set(obj, "comp_ref", (void*)1);
3616 edje_object_signal_emit(obj, "e,state,hidden", "e");
3617 evas_object_data_set(obj, "comp_hiding", (void*)1);
3619 if (evas_object_data_del(obj, "comp_override"))
3620 e_comp_override_timed_pop();
3624 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3626 if (!e_util_strcmp(emission, "e,action,hide,done"))
3628 if (!evas_object_data_del(obj, "comp_hiding")) return;
3629 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3630 evas_object_hide(obj);
3631 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3634 evas_object_data_del(obj, "comp_showing");
3635 if (evas_object_data_del(obj, "comp_ref"))
3636 evas_object_unref(obj);
3640 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3646 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3650 E_API E_Comp_Object_Hook *
3651 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3653 E_Comp_Object_Hook *ch;
3655 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3656 ch = E_NEW(E_Comp_Object_Hook, 1);
3657 if (!ch) return NULL;
3658 ch->hookpoint = hookpoint;
3660 ch->data = (void*)data;
3661 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3666 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3669 if (_e_comp_object_hooks_walking == 0)
3671 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3675 _e_comp_object_hooks_delete++;
3678 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3679 E_API E_Comp_Object_Intercept_Hook *
3680 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3682 E_Comp_Object_Intercept_Hook *ch;
3684 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3685 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3686 if (!ch) return NULL;
3687 ch->hookpoint = hookpoint;
3689 ch->data = (void*)data;
3690 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3695 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3698 if (_e_comp_object_intercept_hooks_walking == 0)
3700 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3704 _e_comp_object_intercept_hooks_delete++;
3709 e_comp_object_util_add(Evas_Object *obj)
3713 E_Comp_Config *conf = e_comp_config_get();
3714 Eina_Bool skip = EINA_FALSE;
3720 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3722 name = evas_object_name_get(obj);
3723 vis = evas_object_visible_get(obj);
3724 o = edje_object_add(e_comp->evas);
3725 evas_object_data_set(o, "comp_object", (void*)1);
3727 skip = (!strncmp(name, "noshadow", 8));
3729 evas_object_data_set(o, "comp_object_skip", (void*)1);
3731 if (conf->shadow_style)
3733 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3734 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3737 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3738 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3739 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3741 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3743 evas_object_geometry_get(obj, &x, &y, &w, &h);
3744 evas_object_geometry_set(o, x, y, w, h);
3745 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3747 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3749 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3750 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3751 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3752 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3753 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3754 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3756 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3758 edje_object_part_swallow(o, "e.swallow.content", obj);
3760 _e_comp_object_event_add(o);
3763 evas_object_show(o);
3768 /* utility functions for deleting objects when their "owner" is deleted */
3770 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3775 EINA_SAFETY_ON_NULL_RETURN(to_del);
3776 l = evas_object_data_get(obj, "comp_object-to_del");
3777 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3778 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3779 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3783 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3788 EINA_SAFETY_ON_NULL_RETURN(to_del);
3789 l = evas_object_data_get(obj, "comp_object-to_del");
3791 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3794 /////////////////////////////////////////////////////////
3796 EINTERN Evas_Object *
3797 e_comp_object_client_add(E_Client *ec)
3802 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3803 if (ec->frame) return NULL;
3804 _e_comp_smart_init();
3805 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3806 cw = evas_object_smart_data_get(o);
3807 if (!cw) return NULL;
3808 evas_object_data_set(o, "E_Client", ec);
3811 evas_object_data_set(o, "comp_object", (void*)1);
3813 _e_comp_object_event_add(o);
3818 /* utility functions for getting client inset */
3820 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3823 if (!cw->client_inset.calc)
3829 if (ax) *ax = x - cw->client_inset.l;
3830 if (ay) *ay = y - cw->client_inset.t;
3834 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3837 if (!cw->client_inset.calc)
3843 if (ax) *ax = x + cw->client_inset.l;
3844 if (ay) *ay = y + cw->client_inset.t;
3848 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3851 if (!cw->client_inset.calc)
3857 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3858 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3862 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3865 if (!cw->client_inset.calc)
3871 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3872 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3876 e_comp_object_client_get(Evas_Object *obj)
3881 /* FIXME: remove this when eo is used */
3882 o = evas_object_data_get(obj, "comp_smart_obj");
3884 return e_comp_object_client_get(o);
3885 return cw ? cw->ec : NULL;
3889 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3892 if (cw->frame_extends)
3893 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3898 if (w) *w = cw->ec->w;
3899 if (h) *h = cw->ec->h;
3904 e_comp_object_util_zone_get(Evas_Object *obj)
3906 E_Zone *zone = NULL;
3910 zone = e_comp_zone_find_by_ec(cw->ec);
3915 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3916 zone = e_comp_zone_xy_get(x, y);
3922 e_comp_object_util_center(Evas_Object *obj)
3924 int x, y, w, h, ow, oh;
3929 zone = e_comp_object_util_zone_get(obj);
3930 EINA_SAFETY_ON_NULL_RETURN(zone);
3931 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3932 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3933 ow = cw->ec->w, oh = cw->ec->h;
3935 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3936 x = x + (w - ow) / 2;
3937 y = y + (h - oh) / 2;
3938 evas_object_move(obj, x, y);
3942 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3944 int x, y, w, h, ow, oh;
3947 EINA_SAFETY_ON_NULL_RETURN(on);
3948 evas_object_geometry_get(on, &x, &y, &w, &h);
3949 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3950 ow = cw->ec->w, oh = cw->ec->h;
3952 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3953 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3957 e_comp_object_util_fullscreen(Evas_Object *obj)
3962 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3965 evas_object_move(obj, 0, 0);
3966 evas_object_resize(obj, e_comp->w, e_comp->h);
3971 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3979 ow = cw->w, oh = cw->h;
3981 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3982 zone = e_comp_object_util_zone_get(obj);
3983 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3984 if (x) *x = zx + (zw - ow) / 2;
3985 if (y) *y = zy + (zh - oh) / 2;
3989 e_comp_object_input_objs_del(Evas_Object *obj)
3992 E_Input_Rect_Data *input_rect_data;
3993 E_Input_Rect_Smart_Data *input_rect_sd;
3998 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3999 if (!input_rect_sd) return;
4001 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4003 if (input_rect_data->obj)
4005 evas_object_smart_member_del(input_rect_data->obj);
4006 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4008 E_FREE(input_rect_data);
4013 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4016 E_Input_Rect_Data *input_rect_data = NULL;
4017 E_Input_Rect_Smart_Data *input_rect_sd;
4018 int client_w, client_h;
4020 if (cw->ec->client.w)
4021 client_w = cw->ec->client.w;
4023 client_w = cw->ec->w;
4025 if (cw->ec->client.h)
4026 client_h = cw->ec->client.h;
4028 client_h = cw->ec->h;
4030 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4034 _e_comp_input_obj_smart_init();
4035 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4036 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4037 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4040 input_rect_sd->cw = cw;
4043 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4046 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4047 if (input_rect_data)
4049 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4050 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4054 if ((input_rect_data) &&
4055 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4057 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4058 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4059 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4060 evas_object_clip_set(input_rect_data->obj, cw->clip);
4061 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4062 evas_object_geometry_set(input_rect_data->obj,
4063 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4064 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4065 evas_object_pass_events_set(cw->default_input_obj, 1);
4066 evas_object_pass_events_set(cw->obj, 1);
4069 evas_object_show(input_rect_data->obj);
4070 evas_object_show(cw->input_obj);
4075 evas_object_smart_member_del(cw->input_obj);
4076 E_FREE_FUNC(cw->input_obj, evas_object_del);
4077 evas_object_pass_events_set(cw->default_input_obj, 0);
4078 evas_object_pass_events_set(cw->obj, 0);
4083 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4086 E_Input_Rect_Smart_Data *input_rect_sd;
4087 E_Input_Rect_Data *input_rect_data;
4090 if (!cw->input_obj) return;
4092 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4095 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4097 *list = eina_list_append(*list, &input_rect_data->rect);
4103 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4106 if (l) *l = cw->client_inset.l;
4107 if (r) *r = cw->client_inset.r;
4108 if (t) *t = cw->client_inset.t;
4109 if (b) *b = cw->client_inset.b;
4112 /* set geometry for CSD */
4114 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4120 if (cw->frame_object)
4121 CRI("ACK! ec:%p", cw->ec);
4122 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4123 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4124 calc = cw->client_inset.calc;
4125 cw->client_inset.calc = l || r || t || b;
4126 eina_stringshare_replace(&cw->frame_theme, "borderless");
4127 if (cw->client_inset.calc)
4129 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4130 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4131 e_client_size_set(cw->ec, tw, th);
4133 else if (cw->ec->maximized || cw->ec->fullscreen)
4135 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4136 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4138 if (!cw->ec->new_client)
4140 if (calc && cw->client_inset.calc)
4142 tx = cw->ec->x - (l - cw->client_inset.l);
4143 ty = cw->ec->y - (t - cw->client_inset.t);
4144 e_client_pos_set(cw->ec, tx, ty);
4146 cw->ec->changes.pos = cw->ec->changes.size = 1;
4149 cw->client_inset.l = l;
4150 cw->client_inset.r = r;
4151 cw->client_inset.t = t;
4152 cw->client_inset.b = b;
4156 e_comp_object_frame_allowed(Evas_Object *obj)
4158 API_ENTRY EINA_FALSE;
4159 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4163 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4165 API_ENTRY EINA_FALSE;
4166 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4167 eina_stringshare_replace(&cw->frame_name, name);
4168 if (cw->frame_object)
4169 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4174 e_comp_object_frame_exists(Evas_Object *obj)
4176 API_ENTRY EINA_FALSE;
4177 return !!cw->frame_object;
4181 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4183 Evas_Object *o, *pbg;
4186 Eina_Stringshare *theme;
4188 API_ENTRY EINA_FALSE;
4190 if (!e_util_strcmp(cw->frame_theme, name))
4191 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4192 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4193 return _e_comp_object_shadow_setup(cw);
4194 pbg = cw->frame_object;
4195 theme = eina_stringshare_add(name);
4197 if (cw->frame_object)
4201 w = cw->ec->w, h = cw->ec->h;
4202 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4203 if ((cw->ec->w != w) || (cw->ec->h != h))
4205 cw->ec->changes.size = 1;
4208 E_FREE_FUNC(cw->frame_object, evas_object_del);
4209 if (!name) goto reshadow;
4211 o = edje_object_add(e_comp->evas);
4212 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4213 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4214 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4216 cw->frame_object = NULL;
4218 eina_stringshare_del(cw->frame_theme);
4219 cw->frame_theme = theme;
4224 if (theme != e_config->theme_default_border_style)
4226 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4227 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4231 ok = e_theme_edje_object_set(o, "base/theme/border",
4232 "e/widgets/border/default/border");
4233 if (ok && (theme == e_config->theme_default_border_style))
4235 /* Reset default border style to default */
4236 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4237 e_config_save_queue();
4244 cw->frame_object = o;
4245 eina_stringshare_del(cw->frame_theme);
4246 cw->frame_theme = theme;
4247 evas_object_name_set(o, "cw->frame_object");
4250 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4254 cw->ec->changes.icon = 1;
4260 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4265 _e_comp_object_shadow_setup(cw);
4268 int old_x, old_y, new_x = 0, new_y = 0;
4270 old_x = cw->x, old_y = cw->y;
4272 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4274 new_x = cw->ec->x, new_y = cw->ec->y;
4275 else if (cw->ec->placed || (!cw->ec->new_client))
4277 /* if no previous frame:
4278 * - reapply client_inset
4283 if (cw->ec->changes.size)
4291 zone = e_comp_zone_find_by_ec(cw->ec);
4294 x = cw->ec->client.x, y = cw->ec->client.y;
4295 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4296 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4298 new_x = x, new_y = y;
4301 if (old_x != new_x || old_y != new_y)
4303 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4304 cw->y = cw->x = -99999;
4305 evas_object_move(obj, new_x, new_y);
4309 if (cw->ec->maximized)
4311 cw->ec->changes.need_maximize = 1;
4314 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4315 if (cw->frame_object)
4317 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4320 cw->frame_extends = 0;
4321 evas_object_del(pbg);
4326 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4328 E_Comp_Object_Mover *prov;
4331 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4332 edje_object_signal_emit(cw->shobj, sig, src);
4333 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4334 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4335 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4337 /* start with highest priority callback first */
4338 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4340 if (!e_util_glob_match(sig, prov->sig)) continue;
4341 if (prov->func(prov->data, obj, sig)) break;
4346 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4348 /* FIXME: at some point I guess this should use eo to inherit
4349 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4350 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4353 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4357 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4360 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4364 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4367 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4371 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4374 Eina_Rectangle rect;
4377 if (cw->ec->input_only || (!cw->updates)) return;
4378 if (cw->nocomp) return;
4379 rect.x = x, rect.y = y;
4380 rect.w = w, rect.h = h;
4381 evas_object_smart_callback_call(obj, "damage", &rect);
4383 if (e_comp_is_on_overlay(cw->ec))
4385 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4386 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4387 * E module attempts to block screen update due to the particular policy.
4389 if (e_pixmap_resource_get(cw->ec->pixmap))
4390 cw->hwc_need_update = EINA_TRUE;
4393 /* ignore overdraw */
4394 if (cw->updates_full)
4396 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4397 e_comp_object_render_update_add(obj);
4399 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4400 evas_object_show(cw->smart_obj);
4404 /* clip rect to client surface */
4405 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4406 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4407 /* if rect is the total size of the client after clip, clear the updates
4408 * since this is guaranteed to be the whole region anyway
4410 eina_tiler_area_size_get(cw->updates, &tw, &th);
4411 if ((w > tw) || (h > th))
4413 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4414 eina_tiler_clear(cw->updates);
4415 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4417 tw = cw->ec->client.w, th = cw->ec->client.h;
4419 if ((!x) && (!y) && (w == tw) && (h == th))
4421 eina_tiler_clear(cw->updates);
4422 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4423 cw->updates_full = 1;
4424 cw->update_count = 0;
4427 if (cw->update_count > UPDATE_MAX)
4429 /* this is going to get really dumb, so just update the whole thing */
4430 eina_tiler_clear(cw->updates);
4431 cw->update_count = cw->updates_full = 1;
4432 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4433 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4437 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4438 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4440 cw->updates_exist = 1;
4441 e_comp_object_render_update_add(obj);
4443 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4444 evas_object_show(cw->smart_obj);
4448 e_comp_object_damage_exists(Evas_Object *obj)
4450 API_ENTRY EINA_FALSE;
4451 return cw->updates_exist;
4455 e_comp_object_render_update_add(Evas_Object *obj)
4459 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4460 if (cw->render_update_lock.lock) return;
4461 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4465 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4467 e_comp_render_queue();
4471 e_comp_object_render_update_del(Evas_Object *obj)
4475 if (cw->ec->input_only || (!cw->updates)) return;
4476 if (!cw->update) return;
4478 /* this gets called during comp animating to clear the update flag */
4479 if (e_comp->grabbed) return;
4480 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4481 if (!e_comp->updates)
4483 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4484 if (e_comp->render_animator)
4485 ecore_animator_freeze(e_comp->render_animator);
4490 e_comp_object_shape_apply(Evas_Object *obj)
4494 unsigned int i, *pix, *p;
4498 if (!cw->ec) return; //NYI
4499 if (cw->external_content) return;
4502 if ((cw->ec->shape_rects_num >= 1) &&
4503 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4508 ERR("BUGGER: shape with native surface? cw=%p", cw);
4511 evas_object_image_size_get(cw->obj, &w, &h);
4512 if ((w < 1) || (h < 1)) return;
4515 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4516 _e_comp_object_alpha_set(cw);
4517 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4518 evas_object_image_alpha_set(o, 1);
4520 p = pix = evas_object_image_data_get(cw->obj, 1);
4523 evas_object_image_data_set(cw->obj, pix);
4528 unsigned char *spix, *sp;
4530 spix = calloc(w * h, sizeof(unsigned char));
4532 for (i = 0; i < cw->ec->shape_rects_num; i++)
4536 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4537 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4538 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4539 sp = spix + (w * ry) + rx;
4540 for (py = 0; py < rh; py++)
4542 for (px = 0; px < rw; px++)
4550 for (py = 0; py < h; py++)
4552 for (px = 0; px < w; px++)
4554 unsigned int mask, imask;
4556 mask = ((unsigned int)(*sp)) << 24;
4558 imask |= imask >> 8;
4559 imask |= imask >> 8;
4560 *p = mask | (*p & imask);
4561 //if (*sp) *p = 0xff000000 | *p;
4562 //else *p = 0x00000000;
4571 for (py = 0; py < h; py++)
4573 for (px = 0; px < w; px++)
4577 evas_object_image_data_set(cw->obj, pix);
4578 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4579 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4581 evas_object_image_data_set(o, pix);
4582 evas_object_image_data_update_add(o, 0, 0, w, h);
4584 // don't need to fix alpha chanel as blending
4585 // should be totally off here regardless of
4586 // alpha channel content
4590 _e_comp_object_clear(E_Comp_Object *cw)
4595 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4597 if (cw->render_update_lock.lock) return;
4600 e_pixmap_clear(cw->ec->pixmap);
4602 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4603 evas_object_image_size_set(cw->obj, 1, 1);
4604 evas_object_image_data_set(cw->obj, NULL);
4605 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4607 evas_object_image_size_set(o, 1, 1);
4608 evas_object_image_data_set(o, NULL);
4611 e_comp_object_render_update_del(cw->smart_obj);
4615 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4619 API_ENTRY EINA_FALSE;
4621 if (cw->transparent.set == set)
4626 evas_object_color_get(obj, &r, &g, &b, &a);
4627 evas_object_color_set(obj, 0, 0, 0, 0);
4629 cw->transparent.user_r = r;
4630 cw->transparent.user_g = g;
4631 cw->transparent.user_b = b;
4632 cw->transparent.user_a = a;
4634 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4636 cw->transparent.user_r,
4637 cw->transparent.user_g,
4638 cw->transparent.user_b,
4639 cw->transparent.user_a);
4641 cw->transparent.set = EINA_TRUE;
4645 cw->transparent.set = EINA_FALSE;
4647 evas_object_color_set(obj,
4648 cw->transparent.user_r,
4649 cw->transparent.user_g,
4650 cw->transparent.user_b,
4651 cw->transparent.user_a);
4653 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4655 cw->transparent.user_r,
4656 cw->transparent.user_g,
4657 cw->transparent.user_b,
4658 cw->transparent.user_a);
4664 /* helper function to simplify toggling of redirection for display servers which support it */
4666 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4671 if (cw->redirected == set) return;
4672 cw->redirected = set;
4673 if (cw->external_content) return;
4675 e_comp_object_map_update(obj);
4679 if (cw->updates_exist)
4680 e_comp_object_render_update_add(obj);
4682 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4684 _e_comp_object_transparent_set(obj, EINA_FALSE);
4685 evas_object_smart_callback_call(obj, "redirected", NULL);
4689 _e_comp_object_clear(cw);
4690 _e_comp_object_transparent_set(obj, EINA_TRUE);
4691 evas_object_smart_callback_call(obj, "unredirected", NULL);
4696 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4699 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4701 if (cw->buffer_destroy_listener.notify)
4703 cw->buffer_destroy_listener.notify = NULL;
4704 wl_list_remove(&cw->buffer_destroy_listener.link);
4707 if (e_object_is_del(E_OBJECT(cw->ec)))
4709 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4714 /* if it's current displaying buffer, do not remove its content */
4715 if (!evas_object_visible_get(cw->ec->frame))
4716 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4721 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4726 if (cw->buffer_destroy_listener.notify)
4728 wl_list_remove(&cw->buffer_destroy_listener.link);
4729 cw->buffer_destroy_listener.notify = NULL;
4732 if (cw->tbm_surface)
4734 tbm_surface_internal_unref(cw->tbm_surface);
4735 cw->tbm_surface = NULL;
4740 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4742 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4743 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4745 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4747 tbm_surface_internal_ref(ns->data.tbm.buffer);
4748 cw->tbm_surface = ns->data.tbm.buffer;
4752 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4753 evas_object_image_native_surface_set(cw->obj, ns);
4757 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4759 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4760 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4761 evas_object_image_native_surface_set(o, ns);
4768 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4770 Evas_Native_Surface ns;
4773 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4774 if (cw->ec->input_only) return;
4775 if (cw->external_content) return;
4776 if (cw->render_update_lock.lock) return;
4779 memset(&ns, 0, sizeof(Evas_Native_Surface));
4783 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4784 set = (!cw->ec->shaped);
4786 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4790 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4794 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4797 if (cw->ec->input_only) return;
4800 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4801 _e_comp_object_alpha_set(cw);
4803 e_comp_object_native_surface_set(obj, cw->native);
4804 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4808 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4814 if (cw->blanked == set) return;
4816 _e_comp_object_alpha_set(cw);
4819 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4820 evas_object_image_data_set(cw->obj, NULL);
4824 e_comp_object_native_surface_set(obj, 1);
4825 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4829 _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)
4834 if (!_damage_trace) return;
4838 if (!evas_object_visible_get(cw->obj)) return;
4840 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4842 o = evas_object_rectangle_add(e_comp->evas);
4843 evas_object_layer_set(o, E_LAYER_MAX);
4844 evas_object_name_set(o, "damage_trace");
4845 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4846 evas_object_resize(o, dmg_w, dmg_h);
4847 evas_object_color_set(o, 0, 128, 0, 128);
4848 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4849 evas_object_pass_events_set(o, EINA_TRUE);
4850 evas_object_show(o);
4852 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4854 dmg_w, dmg_h, dmg_x, dmg_y,
4855 origin->w, origin->h, origin->x, origin->y);
4857 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4860 /* mark an object as dirty and setup damages */
4862 e_comp_object_dirty(Evas_Object *obj)
4865 Eina_Rectangle *rect;
4869 Eina_Bool dirty, visible;
4873 if (cw->external_content) return;
4874 if (!cw->redirected) return;
4875 if (cw->render_update_lock.lock)
4877 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4880 /* only actually dirty if pixmap is available */
4881 if (!e_pixmap_resource_get(cw->ec->pixmap))
4883 // e_pixmap_size_get returns last attached buffer size
4884 // eventhough it is destroyed
4885 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4888 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4889 visible = cw->visible;
4890 if (!dirty) w = h = 1;
4891 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4893 evas_object_image_data_set(cw->obj, NULL);
4894 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4895 evas_object_image_size_set(cw->obj, tw, th);
4896 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4897 if (cw->pending_updates)
4898 eina_tiler_area_size_set(cw->pending_updates, w, h);
4899 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4901 evas_object_image_pixels_dirty_set(o, dirty);
4903 evas_object_image_data_set(o, NULL);
4904 evas_object_image_size_set(o, tw, th);
4905 visible |= evas_object_visible_get(o);
4909 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4913 e_comp_object_native_surface_set(obj, 1);
4915 m = _e_comp_object_map_damage_transform_get(cw->ec);
4916 it = eina_tiler_iterator_new(cw->updates);
4917 EINA_ITERATOR_FOREACH(it, rect)
4919 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4920 * of evas engine and doesn't convert damage according to evas_map.
4921 * so damage of evas_object_image use surface coordinate.
4925 int damage_x, damage_y, damage_w, damage_h;
4927 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4928 &damage_x, &damage_y, &damage_w, &damage_h);
4929 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4930 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4934 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4935 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4938 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4939 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4940 if (cw->pending_updates)
4941 eina_tiler_rect_add(cw->pending_updates, rect);
4943 eina_iterator_free(it);
4944 if (m) e_map_free(m);
4945 if (cw->pending_updates)
4946 eina_tiler_clear(cw->updates);
4949 cw->pending_updates = cw->updates;
4950 cw->updates = eina_tiler_new(w, h);
4951 eina_tiler_tile_size_set(cw->updates, 1, 1);
4953 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4954 evas_object_smart_callback_call(obj, "dirty", NULL);
4955 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4956 /* force render if main object is hidden but mirrors are visible */
4957 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4958 e_comp_object_render(obj);
4962 e_comp_object_render(Evas_Object *obj)
4969 API_ENTRY EINA_FALSE;
4971 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4972 if (cw->ec->input_only) return EINA_TRUE;
4973 if (cw->external_content) return EINA_TRUE;
4974 if (cw->native) return EINA_FALSE;
4975 /* if comp object is not redirected state, comp object should not be set by newly committed data
4976 because image size of comp object is 1x1 and it should not be shown on canvas */
4977 if (!cw->redirected) return EINA_TRUE;
4978 if (cw->render_update_lock.lock)
4980 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4983 e_comp_object_render_update_del(obj);
4984 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4986 if (!cw->pending_updates)
4988 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4989 evas_object_image_data_set(cw->obj, NULL);
4990 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4991 evas_object_image_data_set(o, NULL);
4995 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4997 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4999 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5002 e_pixmap_image_refresh(cw->ec->pixmap);
5003 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5006 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5007 e_pixmap_image_data_ref(cw->ec->pixmap);
5009 /* set pixel data */
5010 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5011 _e_comp_object_alpha_set(cw);
5012 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5014 evas_object_image_data_set(o, pix);
5015 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5016 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5019 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5021 e_comp_client_post_update_add(cw->ec);
5026 /* create a duplicate of an evas object */
5028 e_comp_object_util_mirror_add(Evas_Object *obj)
5032 unsigned int *pix = NULL;
5033 Eina_Bool argb = EINA_FALSE;
5038 cw = evas_object_data_get(obj, "comp_mirror");
5041 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5042 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5043 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5044 evas_object_image_alpha_set(o, 1);
5045 evas_object_image_source_set(o, obj);
5048 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5049 if (cw->external_content)
5051 ERR("%p of client %p is external content.", obj, cw->ec);
5054 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5055 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5056 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5057 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5058 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5059 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5060 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5061 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5062 evas_object_data_set(o, "comp_mirror", cw);
5064 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5065 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5067 evas_object_image_size_set(o, tw, th);
5070 pix = evas_object_image_data_get(cw->obj, 0);
5076 evas_object_image_native_surface_set(o, cw->ns);
5079 Evas_Native_Surface ns;
5080 memset(&ns, 0, sizeof(Evas_Native_Surface));
5081 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5082 evas_object_image_native_surface_set(o, &ns);
5087 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5088 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5090 (e_pixmap_image_exists(cw->ec->pixmap)))
5091 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5093 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5100 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5101 evas_object_image_pixels_dirty_set(o, dirty);
5102 evas_object_image_data_set(o, pix);
5103 evas_object_image_data_set(cw->obj, pix);
5105 evas_object_image_data_update_add(o, 0, 0, tw, th);
5110 //////////////////////////////////////////////////////
5113 e_comp_object_effect_allowed_get(Evas_Object *obj)
5115 API_ENTRY EINA_FALSE;
5117 if (!cw->shobj) return EINA_FALSE;
5118 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5119 return !e_comp_config_get()->match.disable_borders;
5122 /* setup an api effect for a client */
5124 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5127 Eina_Stringshare *grp;
5128 E_Comp_Config *config;
5129 Eina_Bool loaded = EINA_FALSE;
5131 API_ENTRY EINA_FALSE;
5132 if (!cw->shobj) return EINA_FALSE; //input window
5134 if (!effect) effect = "none";
5135 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5137 config = e_comp_config_get();
5138 if ((config) && (config->effect_file))
5140 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5142 cw->effect_set = EINA_TRUE;
5149 edje_object_file_get(cw->effect_obj, NULL, &grp);
5150 cw->effect_set = !eina_streq(effect, "none");
5151 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5152 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5154 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5155 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5156 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5158 if (cw->effect_running)
5160 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5163 cw->effect_set = EINA_FALSE;
5164 return cw->effect_set;
5168 if (cw->effect_running)
5170 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5173 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5174 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5175 if (cw->effect_clip)
5177 evas_object_clip_unset(cw->clip);
5178 cw->effect_clip = 0;
5180 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5182 _e_comp_object_dim_update(cw);
5184 return cw->effect_set;
5187 /* set params for embryo scripts in effect */
5189 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5191 Edje_Message_Int_Set *msg;
5195 EINA_SAFETY_ON_NULL_RETURN(params);
5196 EINA_SAFETY_ON_FALSE_RETURN(count);
5197 if (!cw->effect_set) return;
5199 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5200 msg->count = (int)count;
5201 for (x = 0; x < count; x++)
5202 msg->val[x] = params[x];
5203 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5204 edje_object_message_signal_process(cw->effect_obj);
5208 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5210 Edje_Signal_Cb end_cb;
5212 E_Comp_Object *cw = data;
5214 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5215 cw->effect_running = 0;
5216 if (!_e_comp_object_animating_end(cw)) return;
5218 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5220 evas_object_data_del(cw->smart_obj, "effect_running");
5221 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5222 e_comp_visibility_calculation_set(EINA_TRUE);
5225 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5226 if (!end_cb) return;
5227 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5228 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5229 end_cb(end_data, cw->smart_obj, emission, source);
5232 /* clip effect to client's zone */
5234 e_comp_object_effect_clip(Evas_Object *obj)
5238 zone = e_comp_zone_find_by_ec(cw->ec);
5240 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5241 if (!cw->effect_clip_able) return;
5242 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5243 cw->effect_clip = 1;
5246 /* unclip effect from client's zone */
5248 e_comp_object_effect_unclip(Evas_Object *obj)
5251 if (!cw->effect_clip) return;
5252 evas_object_clip_unset(cw->smart_obj);
5253 cw->effect_clip = 0;
5256 /* start effect, running end_cb after */
5258 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5260 API_ENTRY EINA_FALSE;
5261 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5262 if (!cw->effect_set) return EINA_FALSE;
5264 if (cw->effect_running)
5266 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5269 e_comp_object_effect_clip(obj);
5270 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5272 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5273 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5274 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5275 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5277 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5278 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5280 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5281 _e_comp_object_animating_begin(cw);
5282 cw->effect_running = 1;
5286 /* stop a currently-running effect immediately */
5288 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5291 Edje_Signal_Cb end_cb_before = NULL;
5292 void *end_data_before = NULL;
5293 API_ENTRY EINA_FALSE;
5295 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5296 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5298 if (end_cb_before != end_cb) return EINA_TRUE;
5299 e_comp_object_effect_unclip(obj);
5300 if (cw->effect_clip)
5302 evas_object_clip_unset(cw->effect_obj);
5303 cw->effect_clip = 0;
5305 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5306 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5308 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5310 evas_object_data_del(cw->smart_obj, "effect_running");
5311 e_comp_visibility_calculation_set(EINA_TRUE);
5314 cw->effect_running = 0;
5315 ret = _e_comp_object_animating_end(cw);
5317 if ((ret) && (end_cb_before))
5319 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5320 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5327 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5329 return a->pri - b->pri;
5332 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5333 E_API E_Comp_Object_Mover *
5334 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5336 E_Comp_Object_Mover *prov;
5338 prov = E_NEW(E_Comp_Object_Mover, 1);
5339 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5340 prov->func = provider;
5341 prov->data = (void*)data;
5344 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5345 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5350 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5352 EINA_SAFETY_ON_NULL_RETURN(prov);
5353 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5358 e_comp_object_effect_object_get(Evas_Object *obj)
5362 return cw->effect_obj;
5366 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5368 API_ENTRY EINA_FALSE;
5369 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5370 if (!cw->effect_set) return EINA_FALSE;
5377 ////////////////////////////////////
5380 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5382 if (e_comp->autoclose.obj)
5384 e_comp_ungrab_input(0, 1);
5385 if (e_comp->autoclose.del_cb)
5386 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5387 else if (!already_del)
5389 evas_object_hide(e_comp->autoclose.obj);
5390 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5392 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5394 e_comp->autoclose.obj = NULL;
5395 e_comp->autoclose.data = NULL;
5396 e_comp->autoclose.del_cb = NULL;
5397 e_comp->autoclose.key_cb = NULL;
5398 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5402 _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)
5404 _e_comp_object_autoclose_cleanup(0);
5408 _e_comp_object_autoclose_setup(Evas_Object *obj)
5410 if (!e_comp->autoclose.rect)
5412 /* create rect just below autoclose object to catch mouse events */
5413 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5414 evas_object_move(e_comp->autoclose.rect, 0, 0);
5415 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5416 evas_object_show(e_comp->autoclose.rect);
5417 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5418 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5419 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5420 e_comp_grab_input(0, 1);
5422 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5423 evas_object_focus_set(obj, 1);
5427 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5429 _e_comp_object_autoclose_setup(obj);
5430 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5434 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5436 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5437 _e_comp_object_autoclose_cleanup(1);
5438 if (e_client_focused_get()) return;
5440 E_Zone *zone = e_zone_current_get();
5443 e_zone_focus_reset(zone);
5447 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5451 if (e_comp->autoclose.obj)
5453 if (e_comp->autoclose.obj == obj) return;
5454 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5455 e_comp->autoclose.obj = obj;
5456 e_comp->autoclose.del_cb = del_cb;
5457 e_comp->autoclose.key_cb = cb;
5458 e_comp->autoclose.data = (void*)data;
5459 if (evas_object_visible_get(obj))
5460 _e_comp_object_autoclose_setup(obj);
5462 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5463 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5466 e_comp->autoclose.obj = obj;
5467 e_comp->autoclose.del_cb = del_cb;
5468 e_comp->autoclose.key_cb = cb;
5469 e_comp->autoclose.data = (void*)data;
5470 if (evas_object_visible_get(obj))
5471 _e_comp_object_autoclose_setup(obj);
5473 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5474 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5478 e_comp_object_is_animating(Evas_Object *obj)
5482 return cw->animating;
5486 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5490 if ((cw->external_content) &&
5491 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5493 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5494 "But current external content is %d object for %p.",
5495 cw->content_type, cw->ec);
5499 cw->user_alpha_set = EINA_TRUE;
5500 cw->user_alpha = alpha;
5502 if (!cw->obj) return;
5504 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5506 evas_object_image_alpha_set(cw->obj, alpha);
5508 if ((!cw->native) && (!cw->external_content))
5509 evas_object_image_data_set(cw->obj, NULL);
5513 e_comp_object_alpha_get(Evas_Object *obj)
5515 API_ENTRY EINA_FALSE;
5517 return evas_object_image_alpha_get(cw->obj);
5521 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5523 Eina_Bool mask_set = EINA_FALSE;
5527 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5528 if (cw->ec->input_only) return;
5535 o = evas_object_rectangle_add(e_comp->evas);
5536 evas_object_color_set(o, 0, 0, 0, 0);
5537 evas_object_clip_set(o, cw->clip);
5538 evas_object_smart_member_add(o, obj);
5539 evas_object_move(o, 0, 0);
5540 evas_object_resize(o, cw->w, cw->h);
5541 /* save render op value to restore when clear a mask.
5543 * NOTE: DO NOT change the render op on ec->frame while mask object
5544 * is set. it will overwrite the changed op value. */
5545 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5546 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5547 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5548 if (cw->visible) evas_object_show(o);
5551 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5552 ELOGF("COMP", " |mask_obj", cw->ec);
5553 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5560 evas_object_smart_member_del(cw->mask.obj);
5561 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5563 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5564 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5570 e_comp_object_mask_has(Evas_Object *obj)
5572 API_ENTRY EINA_FALSE;
5574 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5578 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5583 if ((cw->external_content) &&
5584 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5586 WRN("Can set up size to ONLY evas \"image\" object. "
5587 "But current external content is %d object for %p.",
5588 cw->content_type, cw->ec);
5592 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5594 evas_object_image_size_set(cw->obj, tw, th);
5598 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5600 Eina_Bool transform_set = EINA_FALSE;
5602 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5603 if (cw->ec->input_only) return;
5605 transform_set = !!set;
5609 if (!cw->transform_bg_obj)
5611 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5612 evas_object_move(o, 0, 0);
5613 evas_object_resize(o, 1, 1);
5614 if (cw->transform_bg_color.a >= 255)
5615 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5617 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5618 evas_object_color_set(o,
5619 cw->transform_bg_color.r,
5620 cw->transform_bg_color.g,
5621 cw->transform_bg_color.b,
5622 cw->transform_bg_color.a);
5623 if (cw->visible) evas_object_show(o);
5625 cw->transform_bg_obj = o;
5626 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5628 _e_comp_object_transform_obj_stack_update(obj);
5632 if (cw->transform_bg_obj)
5634 evas_object_smart_member_del(cw->transform_bg_obj);
5635 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5641 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5645 cw->transform_bg_color.r = r;
5646 cw->transform_bg_color.g = g;
5647 cw->transform_bg_color.b = b;
5648 cw->transform_bg_color.a = a;
5650 if (cw->transform_bg_obj)
5652 evas_object_color_set(cw->transform_bg_obj,
5653 cw->transform_bg_color.r,
5654 cw->transform_bg_color.g,
5655 cw->transform_bg_color.b,
5656 cw->transform_bg_color.a);
5661 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5664 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5665 if (cw->ec->input_only) return;
5666 if (!cw->transform_bg_obj) return;
5668 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5672 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5675 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5676 if (cw->ec->input_only) return;
5677 if (!cw->transform_bg_obj) return;
5679 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5683 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5685 Eina_Bool transform_set = EINA_FALSE;
5687 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5688 if (cw->ec->input_only) return;
5690 transform_set = !!set;
5694 if (!cw->transform_tranp_obj)
5696 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5697 evas_object_move(o, 0, 0);
5698 evas_object_resize(o, 1, 1);
5699 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5700 evas_object_color_set(o, 0, 0, 0, 0);
5701 if (cw->visible) evas_object_show(o);
5703 cw->transform_tranp_obj = o;
5704 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5705 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5706 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5708 _e_comp_object_transform_obj_stack_update(obj);
5712 if (cw->transform_tranp_obj)
5714 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5715 evas_object_smart_member_del(cw->transform_tranp_obj);
5716 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5722 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5725 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5726 if (cw->ec->input_only) return;
5727 if (!cw->transform_tranp_obj) return;
5729 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5733 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5736 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5737 if (cw->ec->input_only) return;
5738 if (!cw->transform_tranp_obj) return;
5740 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5744 e_comp_object_layer_update(Evas_Object *obj,
5745 Evas_Object *above, Evas_Object *below)
5747 E_Comp_Object *cw2 = NULL;
5748 Evas_Object *o = NULL;
5753 if (cw->ec->layer_block) return;
5754 if ((above) && (below))
5756 ERR("Invalid layer update request! cw=%p", cw);
5764 layer = evas_object_layer_get(o);
5765 cw2 = evas_object_data_get(o, "comp_obj");
5768 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5770 o = evas_object_above_get(o);
5771 if ((!o) || (o == cw->smart_obj)) break;
5772 if (evas_object_layer_get(o) != layer)
5774 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5779 ec = e_client_top_get();
5780 if (ec) o = ec->frame;
5783 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5787 _e_comp_object_layers_remove(cw);
5790 if (cw2->layer > cw->layer)
5791 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5792 else if (cw2->layer == cw->layer)
5795 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5797 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5799 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5802 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5805 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5809 e_comp_object_layer_get(Evas_Object *obj)
5816 e_comp_object_content_set(Evas_Object *obj,
5817 Evas_Object *content,
5818 E_Comp_Object_Content_Type type)
5820 API_ENTRY EINA_FALSE;
5822 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5823 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5824 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5828 ERR("Can't set e.swallow.content to requested content. "
5829 "Previous comp object should not be changed at all.");
5833 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5835 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5836 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5838 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5839 type, content, cw->ec, cw->ec->pixmap);
5843 cw->external_content = EINA_TRUE;
5846 cw->content_type = type;
5847 e_util_size_debug_set(cw->obj, 1);
5848 evas_object_name_set(cw->obj, "cw->obj");
5849 _e_comp_object_alpha_set(cw);
5852 _e_comp_object_shadow_setup(cw);
5858 e_comp_object_content_unset(Evas_Object *obj)
5860 API_ENTRY EINA_FALSE;
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5863 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5865 if (!cw->obj && !cw->ec->visible)
5867 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5871 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5873 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5879 if (cw->frame_object)
5880 edje_object_part_unswallow(cw->frame_object, cw->obj);
5882 edje_object_part_unswallow(cw->shobj, cw->obj);
5884 evas_object_del(cw->obj);
5885 evas_object_hide(cw->obj);
5889 cw->external_content = EINA_FALSE;
5890 if (cw->ec->is_cursor)
5893 DBG("%p is cursor surface..", cw->ec);
5894 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5896 evas_object_resize(cw->ec->frame, pw, ph);
5897 evas_object_hide(cw->ec->frame);
5902 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5903 cw->obj = evas_object_image_filled_add(e_comp->evas);
5904 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5905 e_util_size_debug_set(cw->obj, 1);
5906 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5907 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5908 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5909 evas_object_name_set(cw->obj, "cw->obj");
5910 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5911 _e_comp_object_alpha_set(cw);
5914 _e_comp_object_shadow_setup(cw);
5919 _e_comp_intercept_show_helper(cw);
5923 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5924 e_comp_object_dirty(cw->smart_obj);
5925 e_comp_object_render(cw->smart_obj);
5926 e_comp_object_render_update_add(obj);
5931 EINTERN Evas_Object *
5932 e_comp_object_content_get(Evas_Object *obj)
5936 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5938 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5940 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5947 E_API E_Comp_Object_Content_Type
5948 e_comp_object_content_type_get(Evas_Object *obj)
5950 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5952 return cw->content_type;
5956 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5959 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5960 E_Comp_Config *conf = e_comp_config_get();
5961 if (cw->ec->input_only) return;
5962 if (!conf->dim_rect_enable) return;
5964 cw->dim.mask_set = mask_set;
5970 if (!cw->dim.enable) return;
5971 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5975 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5977 Eina_Bool mask_set = EINA_FALSE;
5981 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5982 E_Comp_Config *conf = e_comp_config_get();
5983 if (cw->ec->input_only) return;
5984 if (!conf->dim_rect_enable) return;
5990 if (cw->dim.mask_obj)
5992 evas_object_smart_member_del(cw->dim.mask_obj);
5993 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5996 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);
5997 o = evas_object_rectangle_add(e_comp->evas);
5998 evas_object_color_set(o, 0, 0, 0, 0);
5999 evas_object_smart_member_add(o, obj);
6000 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6001 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6003 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6004 if (cw->visible) evas_object_show(o);
6006 cw->dim.mask_obj = o;
6007 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6009 evas_object_layer_set(cw->dim.mask_obj, 9998);
6013 if (cw->dim.mask_obj)
6015 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6016 evas_object_smart_member_del(cw->dim.mask_obj);
6017 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6023 e_comp_object_dim_client_set(E_Client *ec)
6025 E_Comp_Config *conf = e_comp_config_get();
6027 if (!conf->dim_rect_enable) return ;
6028 if (dim_client == ec) return;
6030 Eina_Bool prev_dim = EINA_FALSE;
6031 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6033 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6034 prev_dim = EINA_TRUE;
6036 if (prev_dim && dim_client->visible && ec)
6038 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6039 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6043 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6044 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6050 e_comp_object_dim_client_get(void)
6052 E_Comp_Config *conf = e_comp_config_get();
6054 if (!conf->dim_rect_enable ) return NULL;
6060 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6063 char emit[32] = "\0";
6064 E_Comp_Config *conf = e_comp_config_get();
6067 if (!conf->dim_rect_enable) return;
6068 if (!cw->effect_obj) return;
6069 if (enable == cw->dim.enable) return;
6071 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6072 if (noeffect || !conf->dim_rect_effect)
6074 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6078 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6081 cw->dim.enable = enable;
6083 if (cw->dim.mask_set && !enable)
6085 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6086 edje_object_signal_emit(cw->effect_obj, emit, "e");
6088 else if (cw->dim.mask_set && enable)
6090 edje_object_signal_emit(cw->effect_obj, emit, "e");
6091 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6095 edje_object_signal_emit(cw->effect_obj, emit, "e");
6100 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6102 API_ENTRY EINA_FALSE;
6103 E_Comp_Config *conf = e_comp_config_get();
6105 if (!ec) return EINA_FALSE;
6106 if (!conf->dim_rect_enable) return EINA_FALSE;
6108 if (cw->dim.enable) return EINA_TRUE;
6114 _e_comp_object_dim_update(E_Comp_Object *cw)
6116 E_Comp_Config *conf = e_comp_config_get();
6119 if (!conf->dim_rect_enable) return;
6120 if (!cw->effect_obj) return;
6123 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6124 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6126 if (cw->dim.mask_set)
6128 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6134 e_comp_object_clear(Evas_Object *obj)
6138 _e_comp_object_clear(cw);
6142 e_comp_object_hwc_update_exists(Evas_Object *obj)
6144 API_ENTRY EINA_FALSE;
6145 return cw->hwc_need_update;
6150 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6153 cw->hwc_need_update = set;
6157 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6159 API_ENTRY EINA_FALSE;
6160 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6164 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6167 if (cw->indicator.obj != indicator)
6168 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6169 cw->indicator.obj = indicator;
6170 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6174 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6177 if (cw->indicator.obj != indicator) return;
6178 cw->indicator.obj = NULL;
6179 edje_object_part_unswallow(cw->shobj, indicator);
6183 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6186 Edje_Message_Int_Set *msg;
6188 if (!cw->indicator.obj) return;
6190 cw->indicator.w = w;
6191 cw->indicator.h = h;
6193 if (!cw->shobj) return;
6195 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6199 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6200 edje_object_message_signal_process(cw->shobj);
6203 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6205 e_comp_object_map_update(Evas_Object *obj)
6208 E_Client *ec = cw->ec;
6209 E_Comp_Wl_Client_Data *cdata;
6211 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6214 int l, remain = sizeof buffer;
6217 if (e_object_is_del(E_OBJECT(ec))) return;
6218 cdata = e_client_cdata_get(ec);
6221 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6222 * when new buffer is attached.
6224 if (!cdata->buffer_ref.buffer) return;
6226 if ((!cw->redirected) ||
6227 (e_client_video_hw_composition_check(ec)) ||
6228 (!e_comp_wl_output_buffer_transform_get(ec) &&
6229 cdata->scaler.buffer_viewport.buffer.scale == 1))
6231 if (evas_object_map_enable_get(cw->effect_obj))
6233 ELOGF("TRANSFORM", "map: disable", cw->ec);
6234 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6235 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6236 evas_object_resize(cw->effect_obj, tw, th);
6243 EINA_SAFETY_ON_NULL_RETURN(map);
6245 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6251 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6253 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6254 e_map_point_image_uv_set(map, 0, x, y);
6255 l = snprintf(p, remain, "%d,%d", x, y);
6256 p += l, remain -= l;
6258 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6259 e_map_point_image_uv_set(map, 1, x, y);
6260 l = snprintf(p, remain, " %d,%d", x, y);
6261 p += l, remain -= l;
6263 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6264 e_map_point_image_uv_set(map, 2, x, y);
6265 l = snprintf(p, remain, " %d,%d", x, y);
6266 p += l, remain -= l;
6268 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6269 e_map_point_image_uv_set(map, 3, x, y);
6270 l = snprintf(p, remain, " %d,%d", x, y);
6271 p += l, remain -= l;
6273 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6275 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6277 e_comp_object_map_set(cw->effect_obj, map);
6278 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6282 /* if there's screen rotation with comp mode, then ec->effect_obj and
6283 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6285 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6286 evas_object_resize(cw->effect_obj, tw, th);
6290 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6292 API_ENTRY EINA_FALSE;
6294 cw->render_trace = set;
6300 e_comp_object_native_usable_get(Evas_Object *obj)
6302 API_ENTRY EINA_FALSE;
6303 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6305 if (cw->ec->input_only) return EINA_FALSE;
6306 if (cw->external_content) return EINA_FALSE;
6307 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6309 /* just return true value, if it is normal case */
6310 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6313 Evas_Native_Surface *ns;
6314 ns = evas_object_image_native_surface_get(cw->obj);
6316 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6319 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6327 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6329 API_ENTRY EINA_FALSE;
6330 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6331 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6332 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6336 case E_COMP_IMAGE_FILTER_BLUR:
6337 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6339 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6340 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6342 case E_COMP_IMAGE_FILTER_INVERSE:
6343 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6345 case E_COMP_IMAGE_FILTER_NONE:
6347 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6351 cw->image_filter = filter;
6356 EINTERN E_Comp_Image_Filter
6357 e_comp_object_image_filter_get(Evas_Object *obj)
6359 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6360 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6361 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6362 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6364 return cw->image_filter;
6368 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6372 if (!_damage_trace) return;
6374 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6375 evas_object_del(obj);
6377 _damage_trace_post_objs = NULL;
6381 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6383 if (!_damage_trace) return;
6385 _damage_trace_post_objs = _damage_trace_objs;
6386 _damage_trace_objs = NULL;
6390 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6392 if (_damage_trace == onoff) return;
6396 evas_event_callback_add(e_comp->evas,
6397 EVAS_CALLBACK_RENDER_PRE,
6398 _e_comp_object_damage_trace_render_pre_cb,
6401 evas_event_callback_add(e_comp->evas,
6402 EVAS_CALLBACK_RENDER_POST,
6403 _e_comp_object_damage_trace_render_post_cb,
6410 EINA_LIST_FREE(_damage_trace_objs, obj)
6411 evas_object_del(obj);
6413 _damage_trace_objs = NULL;
6415 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6416 evas_object_del(obj);
6418 _damage_trace_post_objs = NULL;
6420 evas_event_callback_del(e_comp->evas,
6421 EVAS_CALLBACK_RENDER_PRE,
6422 _e_comp_object_damage_trace_render_pre_cb);
6424 evas_event_callback_del(e_comp->evas,
6425 EVAS_CALLBACK_RENDER_POST,
6426 _e_comp_object_damage_trace_render_post_cb);
6429 _damage_trace = onoff;
6433 e_comp_object_redirected_get(Evas_Object *obj)
6435 API_ENTRY EINA_FALSE;
6436 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6438 return cw->redirected;
6442 e_comp_object_color_visible_get(Evas_Object *obj)
6444 API_ENTRY EINA_FALSE;
6447 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6449 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6453 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6457 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6461 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6469 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6471 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6473 return e_map_set_to_comp_object(em, obj);
6477 e_comp_object_map_get(const Evas_Object *obj)
6479 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6481 return e_map_get_from_comp_object(obj);
6485 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6487 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6489 evas_object_map_enable_set(obj, enable);
6495 e_comp_object_render_update_lock(Evas_Object *obj)
6497 E_Comp_Wl_Buffer *buffer;
6498 struct wayland_tbm_client_queue *cqueue;
6500 API_ENTRY EINA_FALSE;
6502 if (cw->render_update_lock.lock == 0)
6504 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6506 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6507 if ((buffer) && (buffer->resource))
6509 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6511 wayland_tbm_server_client_queue_flush(cqueue);
6514 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6515 e_comp_object_render_update_del(obj);
6517 ELOGF("COMP", "Render update lock enabled", cw->ec);
6520 cw->render_update_lock.lock++;
6526 e_comp_object_render_update_unlock(Evas_Object *obj)
6530 if (cw->render_update_lock.lock == 0)
6533 cw->render_update_lock.lock--;
6535 if (cw->render_update_lock.lock == 0)
6538 if (cw->render_update_lock.pending_move_set)
6540 evas_object_move(obj,
6541 cw->render_update_lock.pending_move_x,
6542 cw->render_update_lock.pending_move_y);
6543 cw->render_update_lock.pending_move_x = 0;
6544 cw->render_update_lock.pending_move_y = 0;
6545 cw->render_update_lock.pending_move_set = EINA_FALSE;
6548 if (cw->render_update_lock.pending_resize_set)
6550 evas_object_resize(obj,
6551 cw->render_update_lock.pending_resize_w,
6552 cw->render_update_lock.pending_resize_h);
6553 cw->render_update_lock.pending_resize_w = 0;
6554 cw->render_update_lock.pending_resize_h = 0;
6555 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6558 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6560 if ((cw->ec->exp_iconify.buffer_flush) &&
6561 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6562 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6563 e_comp_object_clear(obj);
6565 e_comp_object_render_update_add(obj);
6567 ELOGF("COMP", "Render update lock disabled", cw->ec);
6572 e_comp_object_render_update_lock_get(Evas_Object *obj)
6574 API_ENTRY EINA_FALSE;
6576 if (cw->render_update_lock.lock > 0)
6583 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6587 if (cw->transparent.set)
6589 if (r) *r = cw->transparent.user_r;
6590 if (g) *g = cw->transparent.user_g;
6591 if (b) *b = cw->transparent.user_b;
6592 if (a) *a = cw->transparent.user_a;
6596 evas_object_color_get(obj, r, g, b, a);
6601 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6605 evas_object_render_op_set(cw->obj, op);
6608 EINTERN Evas_Render_Op
6609 e_comp_object_render_op_get(Evas_Object *obj)
6611 API_ENTRY EVAS_RENDER_BLEND;
6613 return evas_object_render_op_get(cw->obj);
6617 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6620 wl_signal_add(&cw->events.lower, listener);
6624 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6627 wl_signal_add(&cw->events.show, listener);
6631 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6634 wl_signal_add(&cw->events.hide, listener);