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;
189 typedef struct _E_Input_Rect_Data
195 typedef struct _E_Input_Rect_Smart_Data
197 Eina_List *input_rect_data_list;
199 } E_Input_Rect_Smart_Data;
201 struct E_Comp_Object_Mover
204 E_Comp_Object_Mover_Cb func;
210 static Eina_Inlist *_e_comp_object_movers = NULL;
211 static Evas_Smart *_e_comp_smart = NULL;
212 static Evas_Smart *_e_comp_input_obj_smart = NULL;
214 static int _e_comp_object_hooks_delete = 0;
215 static int _e_comp_object_hooks_walking = 0;
217 static Eina_Inlist *_e_comp_object_hooks[] =
219 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
220 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
221 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
222 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
223 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
225 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
226 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
229 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
230 static int _e_comp_object_intercept_hooks_delete = 0;
231 static int _e_comp_object_intercept_hooks_walking = 0;
233 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
235 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
236 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
240 static Eina_Bool _damage_trace = EINA_FALSE;
241 static Eina_List *_damage_trace_objs = NULL;
242 static Eina_List *_damage_trace_post_objs = NULL;
244 /* sekrit functionzzz */
245 EINTERN void e_client_focused_set(E_Client *ec);
247 /* emitted every time a new noteworthy comp object is added */
248 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
250 /* ecore event define */
251 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
252 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
253 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
255 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
256 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
257 static void _e_comp_object_dim_update(E_Comp_Object *cw);
258 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
259 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
261 static E_Client *dim_client = NULL;
264 _e_comp_object_hooks_clean(void)
267 E_Comp_Object_Hook *ch;
270 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
271 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
273 if (!ch->delete_me) continue;
274 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
280 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
282 E_Comp_Object_Hook *ch;
283 Eina_Bool ret = EINA_TRUE;
285 if (e_object_is_del(E_OBJECT(ec)))
287 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
288 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
289 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
290 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
294 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET))
299 e_object_ref(E_OBJECT(ec));
300 _e_comp_object_hooks_walking++;
301 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
303 if (ch->delete_me) continue;
304 if (!(ch->func(ch->data, ec)))
310 _e_comp_object_hooks_walking--;
311 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
312 _e_comp_object_hooks_clean();
314 e_object_unref(E_OBJECT(ec));
319 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
321 _e_comp_object_intercept_hooks_clean(void)
324 E_Comp_Object_Intercept_Hook *ch;
327 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
328 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
330 if (!ch->delete_me) continue;
331 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
337 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
339 E_Comp_Object_Intercept_Hook *ch;
340 Eina_Bool ret = EINA_TRUE;
342 if (e_object_is_del(E_OBJECT(ec))) return ret;
343 e_object_ref(E_OBJECT(ec));
344 _e_comp_object_intercept_hooks_walking++;
345 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
347 if (ch->delete_me) continue;
348 if (!(ch->func(ch->data, ec)))
354 _e_comp_object_intercept_hooks_walking--;
355 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
356 _e_comp_object_intercept_hooks_clean();
358 e_object_unref(E_OBJECT(ec));
365 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
367 E_Event_Comp_Object *ev = event;
370 ec = evas_object_data_get(ev->comp_object, "E_Client");
374 e_object_unref(E_OBJECT(ec));
376 evas_object_unref(ev->comp_object);
381 _e_comp_object_event_add(Evas_Object *obj)
383 E_Event_Comp_Object *ev;
386 if (stopping) return;
387 ev = E_NEW(E_Event_Comp_Object, 1);
388 EINA_SAFETY_ON_NULL_RETURN(ev);
390 evas_object_ref(obj);
391 ev->comp_object = obj;
392 ec = evas_object_data_get(ev->comp_object, "E_Client");
396 e_object_ref(E_OBJECT(ec));
398 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
402 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
404 E_Event_Comp_Object *ev = event;
407 ec = evas_object_data_get(ev->comp_object, "E_Client");
411 e_object_unref(E_OBJECT(ec));
413 evas_object_unref(ev->comp_object);
418 _e_comp_object_event_simple(Evas_Object *obj, int type)
420 E_Event_Comp_Object *ev;
423 ev = E_NEW(E_Event_Comp_Object, 1);
426 evas_object_ref(obj);
427 ev->comp_object = obj;
428 ec = evas_object_data_get(ev->comp_object, "E_Client");
432 e_object_ref(E_OBJECT(ec));
434 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
436 /////////////////////////////////////
439 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
441 E_Comp_Object *cw = data;
443 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
447 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
452 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
455 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
456 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
460 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
462 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
469 /////////////////////////////////////
472 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
477 if (cw->ec->input_only) return;
479 layer = evas_object_layer_get(obj);
481 if (cw->transform_bg_obj)
483 if (layer != evas_object_layer_get(cw->transform_bg_obj))
485 evas_object_layer_set(cw->transform_bg_obj, layer);
488 evas_object_stack_below(cw->transform_bg_obj, obj);
491 if (cw->transform_tranp_obj)
493 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
495 evas_object_layer_set(cw->transform_tranp_obj, layer);
498 evas_object_stack_below(cw->transform_tranp_obj, obj);
503 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
510 if (!map) return NULL;
512 e_map_util_points_populate_from_object_full(map, obj, 0);
513 e_map_util_points_color_set(map, 255, 255, 255, 255);
515 for (i = 0 ; i < 4 ; ++i)
520 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
521 e_map_point_coord_set(map, i, x, y, 1.0);
528 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
537 e_comp_object_map_set(obj, map);
538 e_comp_object_map_enable_set(obj, EINA_TRUE);
545 evas_object_map_enable_set(obj, EINA_FALSE);
550 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
561 e_comp_object_map_set(obj, map);
562 e_comp_object_map_enable_set(obj, EINA_TRUE);
569 evas_object_map_enable_set(obj, EINA_FALSE);
572 /////////////////////////////////////
574 static inline Eina_Bool
575 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
577 if (num > 1) return EINA_TRUE;
578 if ((rects[0].x == 0) && (rects[0].y == 0) &&
579 ((int)rects[0].w == w) && ((int)rects[0].h == h))
584 /////////////////////////////////////
586 /* add a client to the layer-client list */
588 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
590 E_Comp_Object *layer_cw = NULL;
592 /* try to get the internal data for the layer;
593 * will return NULL for fake layers (eg. wayland)
595 if (e_comp->layers[cw->layer].obj)
597 if (evas_object_smart_smart_get(e_comp->layers[cw->layer].obj))
598 layer_cw = evas_object_smart_data_get(e_comp->layers[cw->layer].obj);
600 if (layer_cw == cw) layer_cw = NULL;
602 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));
604 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));
605 if ((!above) && (!below))
608 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
610 e_comp->layers[cw->layer].clients = eina_inlist_prepend_relative(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(layer_cw->ec));
611 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
612 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
614 e_comp->layers[cw->layer].clients_count++;
615 #ifndef E_RELEASE_BUILD
618 E_Client *below_ec = e_client_below_get(cw->ec);
621 if (e_comp->layers[cw->layer].obj == below_ec->frame)
622 CRI("ACK! ec:%p", cw->ec);
629 _e_comp_object_layers_remove(E_Comp_Object *cw)
631 if (cw->ec && e_comp->layers[cw->layer].clients)
633 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
634 e_comp->layers[cw->layer].clients_count--;
637 e_comp->layers[cw->layer].objs = eina_inlist_remove(e_comp->layers[cw->layer].objs, EINA_INLIST_GET(cw));
638 e_comp->layers[cw->layer].objs_count--;
642 /////////////////////////////////////
644 _e_comp_object_alpha_set(E_Comp_Object *cw)
646 Eina_Bool alpha = cw->ec->argb;
648 if ((cw->external_content) &&
649 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
654 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
655 if (cw->user_alpha_set) alpha = cw->user_alpha;
657 evas_object_image_alpha_set(cw->obj, alpha);
661 _e_comp_object_shadow(E_Comp_Object *cw)
663 if (e_client_util_shadow_state_get(cw->ec))
664 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
666 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
667 if (cw->frame_object)
668 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
669 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
672 /* convert from the surface coordinates to the buffer coordinates */
674 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
676 E_Comp_Wl_Buffer_Viewport *vp;
677 E_Comp_Wl_Client_Data *cdata;
681 cdata = e_client_cdata_get(ec);
683 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
690 vp = &cdata->scaler.buffer_viewport;
691 transform = e_comp_wl_output_buffer_transform_get(ec);
693 e_pixmap_size_get(ec->pixmap, &bw, &bh);
695 /* for subsurface, it should be swap 90 and 270 */
696 if (e_comp_wl_subsurface_check(ec))
699 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
700 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
701 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
702 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
708 case WL_OUTPUT_TRANSFORM_NORMAL:
709 default: tx = sx, ty = sy; break;
710 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
711 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
712 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
713 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
714 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
715 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
716 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
719 tx *= vp->buffer.scale;
720 ty *= vp->buffer.scale;
727 _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)
735 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
736 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
743 if (dw) *dw = MAX(x1, x2) - mx;
744 if (dh) *dh = MAX(y1, y2) - my;
748 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
749 int *dx, int *dy, int *dw, int *dh)
751 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
752 E_Util_Transform_Rect_Vertex sv, dv;
756 e_pixmap_size_get(ec->pixmap, &bw, &bh);
758 sv = e_util_transform_rect_to_vertices(&rect);
760 for (i = 0; i < 4; i++)
762 double x = 0.0, y = 0.0;
764 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
766 /* if evas decide coordinate is outside of map, it returns (0, 0)
767 in this case, full damage is added.
769 if ((i != 0) && (x == 0.0) && (y == 0.0))
772 dv.vertices[i].vertex[0] = x;
773 dv.vertices[i].vertex[1] = y;
774 dv.vertices[i].vertex[2] = 1.0;
775 dv.vertices[i].vertex[3] = 1.0;
778 rect = e_util_transform_vertices_to_rect(&dv);
780 if (dx) *dx = rect.x;
781 if (dy) *dy = rect.y;
782 if (dw) *dw = rect.w;
783 if (dh) *dh = rect.h;
797 _e_comp_object_map_damage_transform_get(E_Client *ec)
804 if (!evas_object_map_enable_get(ec->frame))
807 m = e_client_map_get(ec);
811 e_pixmap_size_get(ec->pixmap, &bw, &bh);
812 if ((bw == 0) || (bh == 0))
825 e_map_point_coord_set(m2, 0, 0, 0, 0);
826 e_map_point_coord_set(m2, 1, bw, 0, 0);
827 e_map_point_coord_set(m2, 2, bw, bh, 0);
828 e_map_point_coord_set(m2, 3, 0, bh, 0);
830 for (i = 0; i < 4; i++)
834 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
835 e_map_point_image_uv_set(m2, i, map_x, map_y);
842 /////////////////////////////////////
844 /* handle evas mouse-in events on client object */
846 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
848 Evas_Event_Mouse_In *ev = event_info;
849 E_Comp_Object *cw = data;
851 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
854 /* handle evas mouse-out events on client object */
856 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
858 Evas_Event_Mouse_Out *ev = event_info;
859 E_Comp_Object *cw = data;
861 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
864 /* handle evas mouse wheel events on client object */
866 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
868 Evas_Event_Mouse_Wheel *ev = event_info;
869 E_Comp_Object *cw = data;
870 E_Binding_Event_Wheel ev2;
873 if (e_client_action_get()) return;
874 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
875 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
878 /* handle evas mouse down events on client object */
880 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
882 Evas_Event_Mouse_Down *ev = event_info;
883 E_Comp_Object *cw = data;
884 E_Binding_Event_Mouse_Button ev2;
887 if (e_client_action_get()) return;
888 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
889 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
892 /* handle evas mouse up events on client object */
894 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
896 Evas_Event_Mouse_Up *ev = event_info;
897 E_Comp_Object *cw = data;
898 E_Binding_Event_Mouse_Button ev2;
901 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
902 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
903 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
906 /* handle evas mouse movement events on client object */
908 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
910 Evas_Event_Mouse_Move *ev = event_info;
911 E_Comp_Object *cw = data;
914 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
915 e_client_mouse_move(cw->ec, &ev->cur.output);
917 /////////////////////////////////////
919 /* helper function for checking compositor themes based on user-defined matches */
921 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
923 if (((m->title) && (!ec->netwm.name)) ||
924 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
926 #if defined(__cplusplus) || defined(c_plusplus)
927 if (((m->clas) && (!ec->icccm.cpp_class)) ||
928 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
931 if (((m->clas) && (!ec->icccm.class)) ||
932 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
936 if (((m->role) && (!ec->icccm.window_role)) ||
937 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
943 if ((int)ec->netwm.type != m->primary_type)
946 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
949 if (m->borderless != 0)
953 if (e_client_util_borderless(ec))
955 if (!(((m->borderless == -1) && (!borderless)) ||
956 ((m->borderless == 1) && (borderless))))
963 if (((ec->icccm.transient_for != 0) ||
966 if (!(((m->dialog == -1) && (!dialog)) ||
967 ((m->dialog == 1) && (dialog))))
970 if (m->accepts_focus != 0)
972 int accepts_focus = 0;
974 if (ec->icccm.accepts_focus)
976 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
977 ((m->accepts_focus == 1) && (accepts_focus))))
986 if (!(((m->vkbd == -1) && (!vkbd)) ||
987 ((m->vkbd == 1) && (vkbd))))
992 if (!(((m->argb == -1) && (!ec->argb)) ||
993 ((m->argb == 1) && (ec->argb))))
996 if (m->fullscreen != 0)
998 int fullscreen = ec->fullscreen;
1000 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1001 ((m->fullscreen == 1) && (fullscreen))))
1008 if (ec->netwm.state.modal)
1010 if (!(((m->modal == -1) && (!modal)) ||
1011 ((m->modal == 1) && (modal))))
1017 /* function for setting up a client's compositor frame theme (cw->shobj) */
1019 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1023 Eina_List *list = NULL, *l;
1024 E_Input_Rect_Data *input_rect_data;
1025 E_Input_Rect_Smart_Data *input_rect_sd;
1027 Eina_Stringshare *reshadow_group = NULL;
1028 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1029 Eina_Stringshare *name, *title;
1030 E_Comp_Config *conf = e_comp_config_get();
1032 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1033 /* match correct client type */
1034 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1035 name = cw->ec->icccm.name;
1036 title = cw->ec->icccm.title;
1037 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1038 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1040 /* skipping here is mostly a hack for systray because I hate it */
1043 EINA_LIST_FOREACH(list, l, m)
1045 if (((m->name) && (!name)) ||
1046 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1048 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1052 no_shadow = m->no_shadow;
1053 if (m->shadow_style)
1055 /* fast effects are just themes with "/fast" appended and shorter effect times */
1058 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1059 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1061 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1063 /* default to non-fast style if fast not available */
1066 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1067 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1069 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1071 if (ok && m->visibility_effect)
1072 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1079 if (skip || (cw->ec->e.state.video))
1081 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1086 if (conf->shadow_style)
1090 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1091 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1093 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1097 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1098 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1107 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1109 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1120 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1125 if (cw->ec->override)
1127 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1128 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1130 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1131 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1137 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1138 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1141 _e_comp_object_shadow(cw);
1144 if (focus || cw->ec->focused || cw->ec->override)
1145 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1147 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1148 if (urgent || cw->ec->urgent)
1149 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1158 /* visibility must always be enabled for re_manage clients to prevent
1159 * pop-in animations every time the user sees a persistent client again;
1160 * applying visibility for iconic clients prevents the client from getting
1163 if (cw->visible || cw->ec->re_manage)
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1168 /* breaks animation counter */
1169 if (cw->frame_object)
1171 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1172 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1184 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1187 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1189 if (input_rect_data->obj)
1191 pass_event_flag = EINA_TRUE;
1197 if (cw->indicator.obj)
1199 Evas_Object *indicator;
1200 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1201 if (indicator != cw->indicator.obj)
1203 edje_object_part_unswallow(cw->shobj, indicator);
1204 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1205 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1209 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1210 evas_object_pass_events_set(cw->obj, pass_event_flag);
1215 /////////////////////////////////////////////
1218 _e_comp_object_animating_begin(E_Comp_Object *cw)
1221 if (cw->animating == 1)
1223 e_comp->animating++;
1225 e_object_ref(E_OBJECT(cw->ec));
1230 _e_comp_object_animating_end(E_Comp_Object *cw)
1239 if (cw->ec->launching)
1241 if (!cw->ec->extra_animating)
1243 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1244 cw->ec->launching = EINA_FALSE;
1245 if (cw->ec->first_mapped)
1247 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1248 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1251 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1255 e_comp->animating--;
1256 cw->showing = cw->hiding = 0;
1258 if (e_comp->animating == 0)
1259 e_comp_visibility_calculation_set(EINA_TRUE);
1260 /* remove ref from animation start, account for possibility of deletion from unref */
1261 return !!e_object_unref(E_OBJECT(cw->ec));
1267 /* handle the end of a compositor animation */
1269 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1271 E_Comp_Object *cw = data;
1273 /* visible clients which have never been sized are a bug */
1274 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1275 CRI("ACK! ec:%p", cw->ec);
1276 if (!_e_comp_object_animating_end(cw)) return;
1277 if (cw->animating) return;
1278 /* hide only after animation finishes to guarantee a full run of the animation */
1279 if (cw->defer_hide && ((!strcmp(emission, "e,action,hide,done")) || (!strcmp(emission, "e,action,done"))))
1280 evas_object_hide(cw->smart_obj);
1283 /* run a visibility compositor effect if available, return false if object is dead */
1285 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1291 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1292 if (!cw->effect_running)
1293 _e_comp_object_animating_begin(cw);
1294 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1295 return _e_comp_object_animating_end(cw);
1296 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1297 return _e_comp_object_animating_end(cw);
1299 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1302 zone = e_comp_zone_find_by_ec(cw->ec);
1304 zw = zone->w, zh = zone->h;
1309 zone = e_comp_object_util_zone_get(cw->smart_obj);
1310 if (!zone) zone = e_zone_current_get();
1317 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1318 cw->w, cw->h, zw, zh, x, y}, 8);
1319 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1320 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1323 /////////////////////////////////////////////
1325 /* create necessary objects for clients that e manages */
1327 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1329 if (cw->set_mouse_callbacks) return;
1330 if (!cw->smart_obj) return;
1332 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1336 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1337 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1339 cw->set_mouse_callbacks = EINA_TRUE;
1343 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1345 if (!cw->set_mouse_callbacks) return;
1346 if (!cw->smart_obj) return;
1348 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1352 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1353 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1355 cw->set_mouse_callbacks = EINA_FALSE;
1359 _e_comp_object_setup(E_Comp_Object *cw)
1361 cw->clip = evas_object_rectangle_add(e_comp->evas);
1362 evas_object_move(cw->clip, -9999, -9999);
1363 evas_object_resize(cw->clip, 999999, 999999);
1364 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1365 cw->effect_obj = edje_object_add(e_comp->evas);
1366 evas_object_move(cw->effect_obj, cw->x, cw->y);
1367 evas_object_clip_set(cw->effect_obj, cw->clip);
1368 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1369 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1370 cw->shobj = edje_object_add(e_comp->evas);
1371 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1372 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1373 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1375 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1376 if (cw->ec->override)
1378 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1379 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1380 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1382 else if (!cw->ec->input_only)
1384 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1385 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1386 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1388 cw->real_hid = !cw->ec->input_only;
1389 if (!cw->ec->input_only)
1391 e_util_size_debug_set(cw->effect_obj, 1);
1392 _e_comp_object_mouse_event_callback_set(cw);
1395 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1396 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1397 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1398 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1399 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1400 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1402 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1405 /////////////////////////////////////////////
1407 /* for fast path evas rendering; only called during render */
1409 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1411 E_Comp_Object *cw = data;
1412 E_Client *ec = cw->ec;
1414 int bx, by, bxx, byy;
1416 if (e_object_is_del(E_OBJECT(ec))) return;
1417 if (cw->external_content) return;
1418 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1419 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1422 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1423 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1425 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1427 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1428 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1432 bx = by = bxx = byy = 0;
1433 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1436 Edje_Message_Int_Set *msg;
1437 Edje_Message_Int msg2;
1438 Eina_Bool id = (bx || by || bxx || byy);
1440 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1446 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1448 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1452 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1453 e_comp_client_post_update_add(cw->ec);
1455 else if (e_comp_object_render(ec->frame))
1457 /* apply shape mask if necessary */
1458 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1459 e_comp_object_shape_apply(ec->frame);
1460 ec->shape_changed = 0;
1462 /* shaped clients get precise mouse events to handle transparent pixels */
1463 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1465 /* queue another render if client is still dirty; cannot refresh here. */
1466 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1467 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1469 if (cw->render_trace)
1471 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1477 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1479 E_Comp_Object *cw = data;
1480 E_Client *ec = cw->ec;
1482 if (e_object_is_del(E_OBJECT(ec))) return;
1483 if (cw->external_content) return;
1484 if (!e_comp->hwc) return;
1486 e_comp_client_render_list_add(cw->ec);
1488 if (!ec->hwc_window) return;
1490 e_hwc_windows_rendered_window_add(ec->hwc_window);
1493 /////////////////////////////////////////////
1496 _e_comp_object_client_pending_resize_add(E_Client *ec,
1499 unsigned int serial)
1501 E_Client_Pending_Resize *pnd;
1503 pnd = E_NEW(E_Client_Pending_Resize, 1);
1507 pnd->serial = serial;
1508 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1512 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1514 E_Comp_Object *cw = data;
1517 if (cw->render_update_lock.lock)
1519 cw->render_update_lock.pending_move_x = x;
1520 cw->render_update_lock.pending_move_y = y;
1521 cw->render_update_lock.pending_move_set = EINA_TRUE;
1525 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1526 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1527 (cw->external_content))
1529 /* delay to move until the external content is unset */
1530 cw->ec->changes.pos = 1;
1535 if (cw->ec->move_after_resize)
1537 if ((x != cw->ec->x) || (y != cw->ec->y))
1539 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1540 e_client_pos_set(cw->ec, x, y);
1541 cw->ec->changes.pos = 1;
1547 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1548 (cw->ec->manage_resize.resize_obj))
1550 e_client_pos_set(cw->ec, x, y);
1551 cw->ec->client.x = x + cw->client_inset.l;
1552 cw->ec->client.y = y + cw->client_inset.t;
1553 e_policy_visibility_client_defer_move(cw->ec);
1557 /* if frame_object does not exist, client_inset indicates CSD.
1558 * this means that ec->client matches cw->x/y, the opposite
1561 fx = (!cw->frame_object) * cw->client_inset.l;
1562 fy = (!cw->frame_object) * cw->client_inset.t;
1563 if ((cw->x == x + fx) && (cw->y == y + fy))
1565 if ((cw->ec->x != x) || (cw->ec->y != y))
1567 /* handle case where client tries to move to position and back very quickly */
1568 e_client_pos_set(cw->ec, x, y);
1569 cw->ec->client.x = x + cw->client_inset.l;
1570 cw->ec->client.y = y + cw->client_inset.t;
1574 if (!cw->ec->maximize_override)
1576 /* prevent moving in some directions while directionally maximized */
1577 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1579 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1582 ix = x + cw->client_inset.l;
1583 iy = y + cw->client_inset.t;
1584 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1585 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1586 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1588 /* prevent moving at all if move isn't allowed in current maximize state */
1589 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1590 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1591 if ((!cw->ec->shading) && (!cw->ec->shaded))
1594 zone = e_comp_zone_find_by_ec(cw->ec);
1597 cw->ec->changes.need_unmaximize = 1;
1598 cw->ec->saved.x = ix - zone->x;
1599 cw->ec->saved.y = iy - zone->y;
1600 cw->ec->saved.w = cw->ec->client.w;
1601 cw->ec->saved.h = cw->ec->client.h;
1607 /* only update during resize if triggered by resize */
1608 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1609 /* delay to move while surface waits paired commit serial*/
1610 if (e_client_pending_geometry_has(cw->ec))
1612 /* do nothing while waiting paired commit serial*/
1616 e_client_pos_set(cw->ec, x, y);
1617 if (cw->ec->new_client)
1619 /* don't actually do anything until first client idler loop */
1620 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1621 cw->ec->changes.pos = 1;
1626 /* only update xy position of client to avoid invalid
1627 * first damage region if it is not a new_client. */
1628 if (!cw->ec->shading)
1630 cw->ec->client.x = ix;
1631 cw->ec->client.y = iy;
1634 if (!cw->frame_object)
1636 evas_object_move(obj, x, y);
1641 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1643 E_Comp_Object *cw = data;
1644 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1647 if (cw->render_update_lock.lock)
1649 cw->render_update_lock.pending_resize_w = w;
1650 cw->render_update_lock.pending_resize_h = h;
1651 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1655 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1657 e_client_size_set(cw->ec, w, h);
1658 evas_object_resize(obj, w, h);
1662 /* if frame_object does not exist, client_inset indicates CSD.
1663 * this means that ec->client matches cw->w/h, the opposite
1666 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1667 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1668 if ((cw->w == w + fw) && (cw->h == h + fh))
1670 if (cw->ec->shading || cw->ec->shaded) return;
1671 if (((cw->ec->w != w) || (cw->ec->h != 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))
1675 /* handle case where client tries to resize itself and back very quickly */
1676 e_client_size_set(cw->ec, w, h);
1677 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1678 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1679 evas_object_smart_callback_call(obj, "client_resize", NULL);
1683 /* guarantee that fullscreen is fullscreen */
1684 zone = e_comp_zone_find_by_ec(cw->ec);
1686 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1688 /* calculate client size */
1689 iw = w - cw->client_inset.l - cw->client_inset.r;
1690 ih = h - cw->client_inset.t - cw->client_inset.b;
1691 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1693 /* prevent resizing while maximized depending on direction and config */
1694 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1695 if ((!cw->ec->shading) && (!cw->ec->shaded))
1697 Eina_Bool reject = EINA_FALSE;
1698 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1700 if (cw->ec->client.h != ih)
1702 cw->ec->saved.h = ih;
1703 cw->ec->saved.y = cw->ec->client.y - zone->y;
1704 reject = cw->ec->changes.need_unmaximize = 1;
1707 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1709 if (cw->ec->client.w != iw)
1711 cw->ec->saved.w = iw;
1712 cw->ec->saved.x = cw->ec->client.x - zone->x;
1713 reject = cw->ec->changes.need_unmaximize = 1;
1723 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1725 /* do nothing until client idler loops */
1726 if ((cw->ec->w != w) || (cw->ec->h != h))
1728 e_client_size_set(cw->ec, w, h);
1729 cw->ec->changes.size = 1;
1734 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1735 ((cw->ec->w != w) || (cw->ec->h != h)))
1738 /* netwm sync resizes queue themselves and then trigger later on */
1739 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1741 if (e_client_pending_geometry_has(cw->ec))
1743 /* do nothing while waiting paired commit serial*/
1747 e_client_size_set(cw->ec, w, h);
1748 if ((!cw->ec->shading) && (!cw->ec->shaded))
1750 /* client geom never changes when shading since the client is never altered */
1751 cw->ec->client.w = iw;
1752 cw->ec->client.h = ih;
1753 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1756 /* The size of non-compositing window can be changed, so there is a
1757 * need to check that cw is H/W composited if cw is not redirected.
1758 * And of course we have to change size of evas object of H/W composited cw,
1759 * otherwise cw can't receive input events even if it is shown on the screen.
1761 Eina_Bool redirected = cw->redirected;
1763 redirected = e_comp_is_on_overlay(cw->ec);
1765 if ((!cw->ec->input_only) && (redirected) &&
1766 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1767 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1768 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1769 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1772 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1773 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1775 prev_w = cw->w, prev_h = cw->h;
1776 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1777 /* check shading and clamp to pixmap size for regular clients */
1778 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1779 (((w - fw != pw) || (h - fh != ph))))
1781 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1782 evas_object_smart_callback_call(obj, "client_resize", NULL);
1784 if (cw->frame_object || cw->ec->input_only)
1785 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1788 if ((cw->w == w) && (cw->h == h))
1790 /* going to be a noop resize which won't trigger smart resize */
1791 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1792 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1794 evas_object_resize(obj, w, h);
1798 evas_object_smart_callback_call(obj, "client_resize", NULL);
1801 if ((!cw->frame_object) && (!cw->ec->input_only))
1803 /* "just do it" for overrides */
1804 evas_object_resize(obj, w, h);
1806 if (!cw->ec->override)
1808 /* shape probably changed for non-overrides */
1809 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1810 cw->ec->need_shape_export |= cw->ec->shaped;
1811 if (cw->ec->shaped || cw->ec->shaped_input)
1815 /* this fixes positioning jiggles when using a resize mode
1816 * which also changes the client's position
1819 if (cw->frame_object)
1820 x = cw->x, y = cw->y;
1822 x = cw->ec->x, y = cw->ec->y;
1823 switch (cw->ec->resize_mode)
1825 case E_POINTER_RESIZE_BL:
1826 case E_POINTER_RESIZE_L:
1827 evas_object_move(obj, x + prev_w - cw->w, y);
1829 case E_POINTER_RESIZE_TL:
1830 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1832 case E_POINTER_RESIZE_T:
1833 case E_POINTER_RESIZE_TR:
1834 evas_object_move(obj, x, y + prev_h - cw->h);
1843 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1845 E_Comp_Object *cw = data;
1846 E_Comp_Wl_Client_Data *child_cdata;
1847 unsigned int l = e_comp_canvas_layer_map(layer);
1850 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1852 /* doing a compositor effect, follow directions */
1853 _e_comp_object_layer_set(obj, layer);
1854 if (layer == cw->ec->layer) //trying to put layer back
1858 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1859 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1860 if (cw->layer != l) goto layer_set;
1864 e_comp_render_queue();
1866 ec = e_client_above_get(cw->ec);
1867 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1868 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1869 ec = e_client_above_get(ec);
1870 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1872 ec = e_client_below_get(cw->ec);
1873 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1874 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1875 ec = e_client_below_get(ec);
1876 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1878 evas_object_stack_above(obj, ec->frame);
1883 if (ec && (cw->ec->parent == ec))
1885 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1886 evas_object_stack_above(obj, ec->frame);
1888 evas_object_stack_below(obj, ec->frame);
1891 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1897 if (cw->layer == l) return;
1898 if (e_comp_canvas_client_layer_map(layer) == 9999)
1899 return; //invalid layer for clients not doing comp effects
1900 if (cw->ec->fullscreen)
1902 cw->ec->saved.layer = layer;
1905 oldraise = e_config->transient.raise;
1907 /* clamp to valid client layer */
1908 layer = e_comp_canvas_client_layer_map_nearest(layer);
1909 cw->ec->layer = layer;
1910 if (e_config->transient.layer)
1913 Eina_List *list = eina_list_clone(cw->ec->transients);
1915 /* We need to set raise to one, else the child wont
1916 * follow to the new layer. It should be like this,
1917 * even if the user usually doesn't want to raise
1920 e_config->transient.raise = 1;
1921 EINA_LIST_FREE(list, child)
1923 child_cdata = e_client_cdata_get(child);
1924 if (child_cdata && !child_cdata->mapped)
1926 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1929 e_client_layer_set(child, layer);
1933 e_config->transient.raise = oldraise;
1935 _e_comp_object_layers_remove(cw);
1936 cw->layer = e_comp_canvas_layer_map(layer);
1937 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1938 //if (cw->ec->new_client)
1939 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1940 _e_comp_object_layer_set(obj, layer);
1941 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1942 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1943 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1945 /* can't stack a client above its own layer marker */
1946 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1948 if (!cw->visible) return;
1949 e_comp_render_queue();
1950 _e_comp_object_transform_obj_stack_update(obj);
1953 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1956 _e_comp_object_raise(Evas_Object *obj)
1958 evas_object_raise(obj);
1960 if (evas_object_smart_smart_get(obj))
1962 E_Client *ec = e_comp_object_client_get(obj);
1964 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1969 _e_comp_object_lower(Evas_Object *obj)
1971 evas_object_lower(obj);
1973 if (evas_object_smart_smart_get(obj))
1975 E_Client *ec = e_comp_object_client_get(obj);
1977 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1982 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1984 evas_object_stack_above(obj, target);
1986 if (evas_object_smart_smart_get(obj))
1988 E_Client *ec = e_comp_object_client_get(obj);
1990 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1995 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1997 evas_object_stack_below(obj, target);
1999 if (evas_object_smart_smart_get(obj))
2001 E_Client *ec = e_comp_object_client_get(obj);
2003 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2008 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2010 evas_object_layer_set(obj, layer);
2012 if (evas_object_smart_smart_get(obj))
2014 E_Client *ec = e_comp_object_client_get(obj);
2016 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2021 _e_comp_object_is_pending(E_Client *ec)
2025 if (!ec) return EINA_FALSE;
2027 topmost = e_comp_wl_topmost_parent_get(ec);
2029 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2033 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2035 E_Comp_Object *cw2 = NULL;
2038 Evas_Object *o = stack;
2039 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2041 /* We should consider topmost's layer_pending for subsurface */
2042 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2044 if (_e_comp_object_is_pending(cw->ec))
2045 e_comp_object_layer_update(cw->smart_obj,
2046 raising? stack : NULL,
2047 raising? NULL : stack);
2049 /* obey compositor effects! */
2050 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2051 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2052 stack_cb(cw->smart_obj, stack);
2053 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2054 evas_object_data_del(cw->smart_obj, "client_restack");
2058 cw2 = evas_object_data_get(o, "comp_obj");
2060 /* assume someone knew what they were doing during client init */
2061 if (cw->ec->new_client)
2062 layer = cw->ec->layer;
2063 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2064 layer = cw2->ec->layer;
2066 layer = evas_object_layer_get(stack);
2067 ecstack = e_client_below_get(cw->ec);
2068 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2070 /* some FOOL is trying to restack a layer marker */
2071 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2072 evas_object_layer_set(cw->smart_obj, layer);
2073 /* we got our layer wrangled, return now! */
2074 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2077 /* check if we're stacking below another client */
2080 /* check for non-client layer object */
2081 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2083 /* find an existing client to use for layering
2084 * by walking up the object stack
2086 * this is guaranteed to be pretty quick since we'll either:
2087 * - run out of client layers
2088 * - find a stacking client
2090 o = evas_object_above_get(o);
2091 if ((!o) || (o == cw->smart_obj)) break;
2092 if (evas_object_layer_get(o) != layer)
2094 /* reached the top client layer somehow
2095 * use top client object
2097 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2100 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2101 * return here since the top client layer window
2106 ec = e_client_top_get();
2111 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2114 if (cw2 && cw->layer != cw2->layer)
2117 /* remove existing layers */
2118 _e_comp_object_layers_remove(cw);
2121 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2122 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2123 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2124 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2125 else //if no stacking objects found, either raise or lower
2126 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2129 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2131 /* find new object for stacking if cw2 is on state of layer_pending */
2132 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2134 E_Client *new_stack = NULL, *current_ec = NULL;
2135 current_ec = cw2->ec;
2138 while ((new_stack = e_client_below_get(current_ec)))
2140 current_ec = new_stack;
2141 if (new_stack == cw->ec) continue;
2142 if (new_stack->layer != cw2->ec->layer) break;
2143 if (!_e_comp_object_is_pending(new_stack)) break;
2145 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2146 stack = new_stack->frame;
2149 /* stack it above layer object */
2151 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2152 stack = e_comp->layers[below_layer].obj;
2157 while ((new_stack = e_client_above_get(current_ec)))
2159 current_ec = new_stack;
2160 if (new_stack == cw->ec) continue;
2161 if (new_stack->layer != cw2->ec->layer) break;
2162 if (!_e_comp_object_is_pending(new_stack)) break;
2164 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2165 stack = new_stack->frame;
2167 stack = e_comp->layers[cw2->layer].obj;
2171 /* set restack if stacking has changed */
2172 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2173 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2174 stack_cb(cw->smart_obj, stack);
2175 if (e_comp->layers[cw->layer].obj)
2176 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2178 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2180 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2181 evas_object_data_del(cw->smart_obj, "client_restack");
2182 if (!cw->visible) return;
2183 e_comp_render_queue();
2187 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2189 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2191 if (evas_object_below_get(obj) == above)
2193 e_comp_object_layer_update(obj, above, NULL);
2197 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2198 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2199 _e_comp_object_transform_obj_stack_update(obj);
2200 _e_comp_object_transform_obj_stack_update(above);
2205 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2207 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2208 if (evas_object_above_get(obj) == below)
2210 e_comp_object_layer_update(obj, NULL, below);
2214 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2215 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2216 if (evas_object_smart_smart_get(obj))
2217 _e_comp_object_transform_obj_stack_update(obj);
2218 if (evas_object_smart_smart_get(below))
2219 _e_comp_object_transform_obj_stack_update(below);
2224 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2226 E_Comp_Object *cw = data;
2229 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2231 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2233 if (cw->ec->layer_pending)
2234 e_comp_object_layer_update(obj, NULL, obj);
2236 _e_comp_object_lower(obj);
2239 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2240 o = evas_object_below_get(obj);
2241 _e_comp_object_layers_remove(cw);
2242 /* prepend to client list since this client should be the first item now */
2243 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2244 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2245 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2246 evas_object_data_set(obj, "client_restack", (void*)1);
2247 _e_comp_object_lower(obj);
2248 evas_object_data_del(obj, "client_restack");
2249 if (!cw->visible) goto end;
2250 e_comp_render_queue();
2251 _e_comp_object_transform_obj_stack_update(obj);
2254 if (!cw->ec->post_lower)
2255 e_client_focus_stack_lower(cw->ec);
2260 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2262 E_Comp_Object *cw = data;
2265 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2267 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2269 if (cw->ec->layer_pending)
2271 int obj_layer = evas_object_layer_get(obj);
2272 if (cw->ec->layer != obj_layer)
2273 e_comp_object_layer_update(obj, NULL, NULL);
2276 _e_comp_object_raise(obj);
2279 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2280 o = evas_object_above_get(obj);
2282 E_Client *ecabove = e_client_above_get(cw->ec);
2283 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2284 (ecabove->frame == o)) goto end; //highest below marker
2286 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2287 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2288 _e_comp_object_raise(obj);
2293 /* still stack below override below the layer marker */
2294 for (op = o = e_comp->layers[cw->layer].obj;
2295 o && o != e_comp->layers[cw->layer - 1].obj;
2296 op = o, o = evas_object_below_get(o))
2298 if (evas_object_smart_smart_get(o))
2302 ec = e_comp_object_client_get(o);
2303 if (ec && (!ec->override)) break;
2306 _e_comp_object_stack_below(obj, op);
2307 e_client_focus_defer_set(cw->ec);
2309 if (!cw->visible) goto end;
2310 e_comp_render_queue();
2311 _e_comp_object_transform_obj_stack_update(obj);
2318 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2320 E_Comp_Object *cw = data;
2322 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2323 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2325 ELOGF("COMP", "Hide. intercepted", cw->ec);
2330 if (cw->ec->launching == EINA_TRUE)
2332 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2333 cw->ec->launching = EINA_FALSE;
2338 /* hidden flag = just do it */
2339 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2340 evas_object_hide(obj);
2344 if (cw->ec->input_only)
2346 /* input_only = who cares */
2347 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2348 evas_object_hide(obj);
2351 /* already hidden or currently animating */
2352 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2354 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2358 /* don't try hiding during shutdown */
2359 cw->defer_hide |= stopping;
2360 if (!cw->defer_hide)
2362 if ((!cw->ec->iconic) && (!cw->ec->override))
2363 /* unset delete requested so the client doesn't break */
2364 cw->ec->delete_requested = 0;
2365 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2367 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2368 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2371 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2374 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2376 _e_comp_object_animating_begin(cw);
2377 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2379 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2380 cw->defer_hide = !!cw->animating;
2382 e_comp_object_effect_set(obj, NULL);
2385 if (cw->animating) return;
2386 /* if we have no animations running, go ahead and hide */
2388 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2389 evas_object_hide(obj);
2393 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2395 E_Client *ec = cw->ec;
2398 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2400 if (ec->show_pending.count > 0)
2402 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2403 ec->show_pending.running = EINA_TRUE;
2407 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2408 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2410 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2415 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,
2416 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2417 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2420 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2423 if (ec->iconic && cw->animating)
2425 /* triggered during iconify animation */
2426 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2429 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2432 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2433 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2435 evas_object_move(cw->smart_obj, ec->x, ec->y);
2436 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2437 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2439 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2440 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2443 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2444 evas_object_show(cw->smart_obj);
2447 e_client_focus_defer_set(ec);
2451 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2455 pw = ec->client.w, ph = ec->client.h;
2457 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2459 ec->changes.visible = !ec->hidden;
2462 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2466 cw->updates = eina_tiler_new(pw, ph);
2469 ec->changes.visible = !ec->hidden;
2472 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2477 eina_tiler_tile_size_set(cw->updates, 1, 1);
2480 /* ignore until client idler first run */
2481 ec->changes.visible = !ec->hidden;
2484 ELOGF("COMP", "show_helper. return. new_client", ec);
2491 evas_object_move(cw->smart_obj, ec->x, ec->y);
2492 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2493 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2494 evas_object_show(cw->smart_obj);
2497 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2499 /* start_drag not received */
2500 ec->changes.visible = 1;
2503 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2506 /* re-set geometry */
2507 evas_object_move(cw->smart_obj, ec->x, ec->y);
2508 /* force resize in case it hasn't happened yet, or just to update size */
2509 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2510 if ((cw->w < 1) || (cw->h < 1))
2512 /* if resize didn't go through, try again */
2513 ec->visible = ec->changes.visible = 1;
2515 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2518 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2519 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2520 e_pixmap_clear(ec->pixmap);
2522 if (cw->real_hid && w && h)
2525 /* force comp theming in case it didn't happen already */
2526 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2527 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2528 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2531 /* only do the show if show is allowed */
2534 if (ec->internal) //internal clients render when they feel like it
2535 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2537 if (!e_client_is_iconified_by_client(ec)||
2538 e_policy_visibility_client_is_uniconic(ec))
2540 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2541 evas_object_show(cw->smart_obj);
2543 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2544 it is rendered in idle callback without native surface and
2545 compositor shows an empty frame if other objects aren't shown
2546 because job callback of e_comp called at the next loop.
2547 it causes a visual defect when windows are switched.
2551 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2552 e_comp_object_dirty(cw->smart_obj);
2553 e_comp_object_render(cw->smart_obj);
2557 e_policy_visibility_client_is_uniconic(ec))
2559 if (ec->exp_iconify.not_raise &&
2560 e_client_check_above_focused(ec))
2561 e_client_focus_stack_append_current_focused(ec);
2563 e_client_focus_defer_set(ec);
2570 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2572 E_Comp_Object *cw = data;
2573 E_Client *ec = cw->ec;
2575 E_Input_Rect_Data *input_rect_data;
2576 E_Input_Rect_Smart_Data *input_rect_sd;
2579 if (ec->ignored) return;
2583 //INF("SHOW2 %p", ec);
2584 _e_comp_intercept_show_helper(cw);
2587 //INF("SHOW %p", ec);
2590 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2591 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2592 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2593 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2597 if ((!cw->obj) && (cw->external_content))
2599 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2603 _e_comp_object_setup(cw);
2606 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2607 cw->obj = evas_object_image_filled_add(e_comp->evas);
2608 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2609 e_util_size_debug_set(cw->obj, 1);
2610 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2611 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2612 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2613 evas_object_name_set(cw->obj, "cw->obj");
2614 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2616 _e_comp_object_alpha_set(cw);
2619 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2622 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2623 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2626 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2629 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2631 if (input_rect_data->obj)
2633 evas_object_geometry_set(input_rect_data->obj,
2634 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2635 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2636 input_rect_data->rect.w, input_rect_data->rect.h);
2643 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2645 _e_comp_intercept_show_helper(cw);
2649 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2651 E_Comp_Object *cw = data;
2655 /* note: this is here as it seems there are enough apps that do not even
2656 * expect us to emulate a look of focus but not actually set x input
2657 * focus as we do - so simply abort any focus set on such windows */
2658 /* be strict about accepting focus hint */
2659 /* be strict about accepting focus hint */
2660 if ((!ec->icccm.accepts_focus) &&
2661 (!ec->icccm.take_focus))
2665 if (e_client_focused_get() == ec)
2666 e_client_focused_set(NULL);
2668 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2669 evas_object_focus_set(obj, focus);
2673 if (focus && ec->lock_focus_out) return;
2674 if (e_object_is_del(E_OBJECT(ec)) && focus)
2675 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2677 /* filter focus setting based on current state */
2682 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2683 evas_object_focus_set(obj, focus);
2686 if ((ec->iconic) && (!ec->deskshow))
2688 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2690 /* don't focus an iconified window. that's silly! */
2691 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2692 e_client_uniconify(ec);
2693 if (e_client_focus_track_enabled())
2694 e_client_focus_latest_set(ec);
2702 if ((!ec->sticky) && (ec->desk) && (!ec->desk->visible))
2704 if (ec->desk->animate_count) return;
2705 e_desk_show(ec->desk);
2706 if (!ec->desk->visible) return;
2714 /* not yet visible, wait till the next time... */
2715 ec->want_focus = !ec->hidden;
2720 e_client_focused_set(ec);
2724 if (e_client_focused_get() == ec)
2725 e_client_focused_set(NULL);
2729 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2731 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2733 evas_object_focus_set(obj, focus);
2737 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2739 E_Comp_Object *cw = data;
2741 if (cw->transparent.set)
2743 cw->transparent.user_r = r;
2744 cw->transparent.user_g = g;
2745 cw->transparent.user_b = b;
2746 cw->transparent.user_a = a;
2748 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2750 cw->transparent.user_r,
2751 cw->transparent.user_g,
2752 cw->transparent.user_b,
2753 cw->transparent.user_a);
2757 evas_object_color_set(obj, r, g, b, a);
2760 ////////////////////////////////////////////////////
2763 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2765 int w, h, ox, oy, ow, oh;
2767 Eina_Bool pass_event_flag = EINA_FALSE;
2768 E_Input_Rect_Data *input_rect_data;
2769 E_Input_Rect_Smart_Data *input_rect_sd;
2771 if (cw->frame_object)
2773 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2774 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2775 /* set a fixed size, force edje calc, check size difference */
2776 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2777 edje_object_message_signal_process(cw->frame_object);
2778 edje_object_calc_force(cw->frame_object);
2779 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2780 cw->client_inset.l = ox;
2781 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2782 cw->client_inset.t = oy;
2783 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2784 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2785 evas_object_resize(cw->frame_object, w, h);
2789 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2792 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2794 if (input_rect_data->obj)
2796 pass_event_flag = EINA_TRUE;
2802 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2803 evas_object_pass_events_set(cw->obj, pass_event_flag);
2807 cw->client_inset.l = 0;
2808 cw->client_inset.r = 0;
2809 cw->client_inset.t = 0;
2810 cw->client_inset.b = 0;
2812 cw->client_inset.calc = !!cw->frame_object;
2816 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2818 E_Comp_Object *cw = data;
2822 /* - get current size
2824 * - readjust for new frame size
2827 w = cw->ec->w, h = cw->ec->h;
2828 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2830 _e_comp_object_frame_recalc(cw);
2832 if (!cw->ec->fullscreen)
2833 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2835 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2836 if (cw->ec->shading || cw->ec->shaded) return;
2837 if (cw->ec->fullscreen)
2839 zone = e_comp_zone_find_by_ec(cw->ec);
2841 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2843 else if (cw->ec->new_client)
2845 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2846 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2847 evas_object_resize(cw->ec->frame, w, h);
2849 else if ((w != cw->ec->w) || (h != cw->ec->h))
2850 evas_object_resize(cw->ec->frame, w, h);
2854 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2856 E_Comp_Object *cw = data;
2858 if (!cw->ec) return; //NYI
2859 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2861 cw->shade.x = cw->x;
2862 cw->shade.y = cw->y;
2863 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2867 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2869 E_Comp_Object *cw = data;
2871 if (!cw->ec) return; //NYI
2872 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2874 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2878 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2880 E_Comp_Object *cw = data;
2882 if (!cw->ec) return; //NYI
2883 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2885 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2889 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2891 E_Comp_Object *cw = data;
2893 if (!cw->ec) return; //NYI
2894 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2896 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2900 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2902 E_Comp_Object *cw = data;
2904 _e_comp_object_shadow_setup(cw);
2905 if (cw->frame_object)
2907 _e_comp_object_shadow(cw);
2908 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2909 _e_comp_object_frame_recalc(cw);
2910 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2915 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2917 E_Comp_Object *cw = data;
2919 if (_e_comp_object_shadow_setup(cw))
2920 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2921 if (cw->frame_object)
2923 _e_comp_object_shadow(cw);
2924 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2925 _e_comp_object_frame_recalc(cw);
2926 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2931 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2933 E_Comp_Object *cw = data;
2935 if (cw->frame_object)
2937 _e_comp_object_shadow(cw);
2938 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2939 _e_comp_object_frame_recalc(cw);
2940 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2945 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2947 E_Comp_Object *cw = data;
2949 if (_e_comp_object_shadow_setup(cw))
2952 cw->ec->changes.size = 1;
2954 if (cw->frame_object)
2956 _e_comp_object_shadow(cw);
2957 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2958 _e_comp_object_frame_recalc(cw);
2959 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2964 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2966 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2970 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2972 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2976 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2978 E_Comp_Object *cw = data;
2980 if (!cw->ec) return; //NYI
2981 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2985 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2987 E_Comp_Object *cw = data;
2989 if (!cw->ec) return; //NYI
2990 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2994 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2996 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3000 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3002 E_Comp_Object *cw = data;
3004 if (!e_object_is_del(E_OBJECT(cw->ec)))
3005 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3009 _e_comp_input_obj_smart_add(Evas_Object *obj)
3011 E_Input_Rect_Smart_Data *input_rect_sd;
3012 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3014 if (!input_rect_sd) return;
3015 evas_object_smart_data_set(obj, input_rect_sd);
3019 _e_comp_input_obj_smart_del(Evas_Object *obj)
3021 E_Input_Rect_Smart_Data *input_rect_sd;
3022 E_Input_Rect_Data *input_rect_data;
3024 input_rect_sd = evas_object_smart_data_get(obj);
3025 if (!input_rect_sd) return;
3027 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3029 if (input_rect_data->obj)
3031 evas_object_smart_member_del(input_rect_data->obj);
3032 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3034 E_FREE(input_rect_data);
3036 E_FREE(input_rect_sd);
3040 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3042 E_Input_Rect_Smart_Data *input_rect_sd;
3043 E_Input_Rect_Data *input_rect_data;
3047 input_rect_sd = evas_object_smart_data_get(obj);
3048 if (!input_rect_sd) return;
3050 cw = input_rect_sd->cw;
3051 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3053 if (input_rect_data->obj)
3055 evas_object_geometry_set(input_rect_data->obj,
3056 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3057 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3058 input_rect_data->rect.w, input_rect_data->rect.h);
3064 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3066 E_Input_Rect_Smart_Data *input_rect_sd;
3067 E_Input_Rect_Data *input_rect_data;
3071 input_rect_sd = evas_object_smart_data_get(obj);
3072 if (!input_rect_sd) return;
3074 cw = input_rect_sd->cw;
3075 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3077 if (input_rect_data->obj)
3079 evas_object_geometry_set(input_rect_data->obj,
3080 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3081 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3082 input_rect_data->rect.w, input_rect_data->rect.h);
3088 _e_comp_input_obj_smart_show(Evas_Object *obj)
3090 E_Input_Rect_Smart_Data *input_rect_sd;
3091 E_Input_Rect_Data *input_rect_data;
3094 input_rect_sd = evas_object_smart_data_get(obj);
3095 if (!input_rect_sd) return;
3097 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3099 if (input_rect_data->obj)
3101 evas_object_show(input_rect_data->obj);
3107 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3109 E_Input_Rect_Smart_Data *input_rect_sd;
3110 E_Input_Rect_Data *input_rect_data;
3113 input_rect_sd = evas_object_smart_data_get(obj);
3114 if (!input_rect_sd) return;
3116 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3118 if (input_rect_data->obj)
3120 evas_object_hide(input_rect_data->obj);
3126 _e_comp_input_obj_smart_init(void)
3128 if (_e_comp_input_obj_smart) return;
3130 static const Evas_Smart_Class sc =
3132 INPUT_OBJ_SMART_NAME,
3133 EVAS_SMART_CLASS_VERSION,
3134 _e_comp_input_obj_smart_add,
3135 _e_comp_input_obj_smart_del,
3136 _e_comp_input_obj_smart_move,
3137 _e_comp_input_obj_smart_resize,
3138 _e_comp_input_obj_smart_show,
3139 _e_comp_input_obj_smart_hide,
3152 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3158 _e_comp_smart_add(Evas_Object *obj)
3162 cw = E_NEW(E_Comp_Object, 1);
3163 EINA_SAFETY_ON_NULL_RETURN(cw);
3165 cw->smart_obj = obj;
3166 cw->x = cw->y = cw->w = cw->h = -1;
3167 evas_object_smart_data_set(obj, cw);
3168 cw->opacity = 255.0;
3169 cw->external_content = 0;
3170 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3171 cw->transform_bg_color.r = 0;
3172 cw->transform_bg_color.g = 0;
3173 cw->transform_bg_color.b = 0;
3174 cw->transform_bg_color.a = 255;
3175 evas_object_data_set(obj, "comp_obj", cw);
3176 evas_object_move(obj, -1, -1);
3177 /* intercept ALL the callbacks! */
3178 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3179 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3180 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3181 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3182 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3183 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3184 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3185 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3186 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3187 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3188 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3190 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3191 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3192 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3193 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3195 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3196 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3197 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3198 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3200 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3201 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3203 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3204 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3206 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3208 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3209 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3213 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3216 evas_object_color_set(cw->clip, r, g, b, a);
3217 evas_object_smart_callback_call(obj, "color_set", NULL);
3222 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3225 evas_object_clip_set(cw->clip, clip);
3229 _e_comp_smart_clip_unset(Evas_Object *obj)
3232 evas_object_clip_unset(cw->clip);
3236 _e_comp_smart_hide(Evas_Object *obj)
3238 TRACE_DS_BEGIN(COMP:SMART HIDE);
3243 evas_object_hide(cw->clip);
3244 if (cw->input_obj) evas_object_hide(cw->input_obj);
3245 evas_object_hide(cw->effect_obj);
3246 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3247 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3248 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3255 /* unset native surface if current displaying buffer was destroied */
3256 if (!cw->buffer_destroy_listener.notify)
3258 Evas_Native_Surface *ns;
3259 ns = evas_object_image_native_surface_get(cw->obj);
3260 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3261 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3264 if (!cw->ec->input_only)
3266 edje_object_freeze(cw->effect_obj);
3267 edje_object_freeze(cw->shobj);
3268 edje_object_play_set(cw->shobj, 0);
3269 if (cw->frame_object)
3270 edje_object_play_set(cw->frame_object, 0);
3272 /* ensure focus-out */
3273 if (cw->ec->focused &&
3274 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3276 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3277 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3278 e_client_focus_defer_unset(cw->ec);
3280 e_comp_render_queue(); //force nocomp recheck
3286 _e_comp_smart_show(Evas_Object *obj)
3294 if ((cw->w < 0) || (cw->h < 0))
3295 CRI("ACK! ec:%p", cw->ec);
3297 TRACE_DS_BEGIN(COMP:SMART SHOW);
3299 e_comp_object_map_update(obj);
3301 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3302 evas_object_show(tmp->frame);
3304 evas_object_show(cw->clip);
3305 if (cw->input_obj) evas_object_show(cw->input_obj);
3306 if (!cw->ec->input_only)
3308 edje_object_thaw(cw->effect_obj);
3309 edje_object_thaw(cw->shobj);
3310 edje_object_play_set(cw->shobj, 1);
3311 if (cw->frame_object)
3312 edje_object_play_set(cw->frame_object, 1);
3314 evas_object_show(cw->effect_obj);
3315 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3316 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3317 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3318 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3319 e_comp_render_queue();
3320 if (cw->ec->input_only)
3325 if (cw->ec->iconic && (!cw->ec->new_client))
3327 if (e_client_is_iconified_by_client(cw->ec))
3329 ELOGF("COMP", "Set launching flag..", cw->ec);
3330 cw->ec->launching = EINA_TRUE;
3333 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3335 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3338 ELOGF("COMP", "Set launching flag..", cw->ec);
3339 cw->ec->launching = EINA_TRUE;
3341 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3342 _e_comp_object_animating_begin(cw);
3343 if (!_e_comp_object_effect_visibility_start(cw, 1))
3349 /* ensure some random effect doesn't lock the client offscreen */
3353 e_comp_object_effect_set(obj, NULL);
3356 _e_comp_object_dim_update(cw);
3362 _e_comp_smart_del(Evas_Object *obj)
3368 if (cw->buffer_destroy_listener.notify)
3370 wl_list_remove(&cw->buffer_destroy_listener.link);
3371 cw->buffer_destroy_listener.notify = NULL;
3374 if (cw->tbm_surface)
3376 tbm_surface_internal_unref(cw->tbm_surface);
3377 cw->tbm_surface = NULL;
3380 if (cw->render_update_lock.buffer_ref.buffer)
3382 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3383 cw->ec, cw->render_update_lock.lock);
3384 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3387 e_comp_object_render_update_del(cw->smart_obj);
3388 E_FREE_FUNC(cw->updates, eina_tiler_free);
3389 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3396 EINA_LIST_FREE(cw->obj_mirror, o)
3398 evas_object_image_data_set(o, NULL);
3399 evas_object_freeze_events_set(o, 1);
3400 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3404 _e_comp_object_layers_remove(cw);
3405 l = evas_object_data_get(obj, "comp_object-to_del");
3406 E_FREE_LIST(l, evas_object_del);
3407 _e_comp_object_mouse_event_callback_unset(cw);
3408 evas_object_del(cw->clip);
3409 evas_object_del(cw->effect_obj);
3410 evas_object_del(cw->shobj);
3411 evas_object_del(cw->frame_object);
3412 evas_object_del(cw->input_obj);
3413 evas_object_del(cw->obj);
3414 evas_object_del(cw->mask.obj);
3415 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3416 evas_object_del(cw->transform_bg_obj);
3417 evas_object_del(cw->transform_tranp_obj);
3418 evas_object_del(cw->default_input_obj);
3419 eina_stringshare_del(cw->frame_theme);
3420 eina_stringshare_del(cw->frame_name);
3424 e_comp->animating--;
3426 e_object_unref(E_OBJECT(cw->ec));
3428 cw->ec->frame = NULL;
3433 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3437 cw->x = x, cw->y = y;
3438 evas_object_move(cw->effect_obj, x, y);
3439 evas_object_move(cw->default_input_obj, x, y);
3440 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3442 e_comp_object_map_update(obj);
3446 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3448 Eina_Bool first = EINA_FALSE;
3453 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3455 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3457 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3459 if (cw->w != w || cw->h != h)
3460 e_comp_object_map_update(obj);
3462 first = ((cw->w < 1) || (cw->h < 1));
3463 cw->w = w, cw->h = h;
3464 if ((!cw->ec->shading) && (!cw->ec->shaded))
3468 if (cw->frame_object)
3469 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3472 /* verify pixmap:object size */
3473 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3475 if ((ww != pw) || (hh != ph))
3476 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3478 evas_object_resize(cw->effect_obj, tw, th);
3479 evas_object_resize(cw->default_input_obj, w, h);
3481 evas_object_resize(cw->input_obj, w, h);
3483 evas_object_resize(cw->mask.obj, w, h);
3484 /* resize render update tiler */
3487 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3488 cw->updates_full = 0;
3489 if (cw->updates) eina_tiler_clear(cw->updates);
3493 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3494 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3499 evas_object_resize(cw->effect_obj, tw, th);
3500 evas_object_resize(cw->default_input_obj, w, h);
3507 e_comp_render_queue();
3513 _e_comp_smart_init(void)
3515 if (_e_comp_smart) return;
3517 static const Evas_Smart_Class sc =
3520 EVAS_SMART_CLASS_VERSION,
3524 _e_comp_smart_resize,
3527 _e_comp_smart_color_set,
3528 _e_comp_smart_clip_set,
3529 _e_comp_smart_clip_unset,
3539 _e_comp_smart = evas_smart_class_new(&sc);
3544 e_comp_object_init(void)
3546 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3547 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3548 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3549 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3553 e_comp_object_shutdown(void)
3559 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3561 API_ENTRY EINA_FALSE;
3562 return !!cw->force_visible;
3564 /////////////////////////////////////////////////////////
3567 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3570 Eina_Bool comp_object;
3572 comp_object = !!evas_object_data_get(obj, "comp_object");
3577 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3579 e_comp_render_queue();
3581 l = evas_object_data_get(obj, "comp_object-to_del");
3582 E_FREE_LIST(l, evas_object_del);
3586 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3588 if (e_comp_util_object_is_above_nocomp(obj) &&
3589 (!evas_object_data_get(obj, "comp_override")))
3591 evas_object_data_set(obj, "comp_override", (void*)1);
3592 e_comp_override_add();
3597 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3599 Eina_Bool ref = EINA_TRUE;
3600 if (evas_object_visible_get(obj))
3604 d = evas_object_data_del(obj, "comp_hiding");
3606 /* currently trying to hide */
3609 /* already visible */
3613 evas_object_show(obj);
3616 evas_object_ref(obj);
3617 evas_object_data_set(obj, "comp_ref", (void*)1);
3619 edje_object_signal_emit(obj, "e,state,visible", "e");
3620 evas_object_data_set(obj, "comp_showing", (void*)1);
3621 if (e_comp_util_object_is_above_nocomp(obj))
3623 evas_object_data_set(obj, "comp_override", (void*)1);
3624 e_comp_override_add();
3629 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3631 if (!evas_object_visible_get(obj)) return;
3632 /* already hiding */
3633 if (evas_object_data_get(obj, "comp_hiding")) return;
3634 if (!evas_object_data_del(obj, "comp_showing"))
3636 evas_object_ref(obj);
3637 evas_object_data_set(obj, "comp_ref", (void*)1);
3639 edje_object_signal_emit(obj, "e,state,hidden", "e");
3640 evas_object_data_set(obj, "comp_hiding", (void*)1);
3642 if (evas_object_data_del(obj, "comp_override"))
3643 e_comp_override_timed_pop();
3647 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3649 if (!e_util_strcmp(emission, "e,action,hide,done"))
3651 if (!evas_object_data_del(obj, "comp_hiding")) return;
3652 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3653 evas_object_hide(obj);
3654 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3657 evas_object_data_del(obj, "comp_showing");
3658 if (evas_object_data_del(obj, "comp_ref"))
3659 evas_object_unref(obj);
3663 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3669 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3673 E_API E_Comp_Object_Hook *
3674 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3676 E_Comp_Object_Hook *ch;
3678 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3679 ch = E_NEW(E_Comp_Object_Hook, 1);
3680 if (!ch) return NULL;
3681 ch->hookpoint = hookpoint;
3683 ch->data = (void*)data;
3684 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3689 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3692 if (_e_comp_object_hooks_walking == 0)
3694 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3698 _e_comp_object_hooks_delete++;
3701 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3702 E_API E_Comp_Object_Intercept_Hook *
3703 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3705 E_Comp_Object_Intercept_Hook *ch;
3707 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3708 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3709 if (!ch) return NULL;
3710 ch->hookpoint = hookpoint;
3712 ch->data = (void*)data;
3713 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3718 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3721 if (_e_comp_object_intercept_hooks_walking == 0)
3723 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3727 _e_comp_object_intercept_hooks_delete++;
3732 e_comp_object_util_add(Evas_Object *obj)
3736 E_Comp_Config *conf = e_comp_config_get();
3737 Eina_Bool skip = EINA_FALSE;
3743 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3745 name = evas_object_name_get(obj);
3746 vis = evas_object_visible_get(obj);
3747 o = edje_object_add(e_comp->evas);
3748 evas_object_data_set(o, "comp_object", (void*)1);
3750 skip = (!strncmp(name, "noshadow", 8));
3752 evas_object_data_set(o, "comp_object_skip", (void*)1);
3754 if (conf->shadow_style)
3756 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3757 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3760 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3761 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3762 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3764 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3766 evas_object_geometry_get(obj, &x, &y, &w, &h);
3767 evas_object_geometry_set(o, x, y, w, h);
3768 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3770 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3772 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3773 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3774 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3775 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3776 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3777 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3779 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3781 edje_object_part_swallow(o, "e.swallow.content", obj);
3783 _e_comp_object_event_add(o);
3786 evas_object_show(o);
3791 /* utility functions for deleting objects when their "owner" is deleted */
3793 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3798 EINA_SAFETY_ON_NULL_RETURN(to_del);
3799 l = evas_object_data_get(obj, "comp_object-to_del");
3800 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3801 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3802 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3806 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3811 EINA_SAFETY_ON_NULL_RETURN(to_del);
3812 l = evas_object_data_get(obj, "comp_object-to_del");
3814 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3817 /////////////////////////////////////////////////////////
3819 EINTERN Evas_Object *
3820 e_comp_object_client_add(E_Client *ec)
3825 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3826 if (ec->frame) return NULL;
3827 _e_comp_smart_init();
3828 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3829 cw = evas_object_smart_data_get(o);
3830 if (!cw) return NULL;
3831 evas_object_data_set(o, "E_Client", ec);
3834 evas_object_data_set(o, "comp_object", (void*)1);
3836 _e_comp_object_event_add(o);
3841 /* utility functions for getting client inset */
3843 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3846 if (!cw->client_inset.calc)
3852 if (ax) *ax = x - cw->client_inset.l;
3853 if (ay) *ay = y - cw->client_inset.t;
3857 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3860 if (!cw->client_inset.calc)
3866 if (ax) *ax = x + cw->client_inset.l;
3867 if (ay) *ay = y + cw->client_inset.t;
3871 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3874 if (!cw->client_inset.calc)
3880 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3881 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3885 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3888 if (!cw->client_inset.calc)
3894 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3895 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3899 e_comp_object_client_get(Evas_Object *obj)
3904 /* FIXME: remove this when eo is used */
3905 o = evas_object_data_get(obj, "comp_smart_obj");
3907 return e_comp_object_client_get(o);
3908 return cw ? cw->ec : NULL;
3912 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3915 if (cw->frame_extends)
3916 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3921 if (w) *w = cw->ec->w;
3922 if (h) *h = cw->ec->h;
3927 e_comp_object_util_zone_get(Evas_Object *obj)
3929 E_Zone *zone = NULL;
3933 zone = e_comp_zone_find_by_ec(cw->ec);
3938 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3939 zone = e_comp_zone_xy_get(x, y);
3945 e_comp_object_util_center(Evas_Object *obj)
3947 int x, y, w, h, ow, oh;
3952 zone = e_comp_object_util_zone_get(obj);
3953 EINA_SAFETY_ON_NULL_RETURN(zone);
3954 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3955 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3956 ow = cw->ec->w, oh = cw->ec->h;
3958 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3959 x = x + (w - ow) / 2;
3960 y = y + (h - oh) / 2;
3961 evas_object_move(obj, x, y);
3965 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3967 int x, y, w, h, ow, oh;
3970 EINA_SAFETY_ON_NULL_RETURN(on);
3971 evas_object_geometry_get(on, &x, &y, &w, &h);
3972 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3973 ow = cw->ec->w, oh = cw->ec->h;
3975 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3976 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3980 e_comp_object_util_fullscreen(Evas_Object *obj)
3985 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3988 evas_object_move(obj, 0, 0);
3989 evas_object_resize(obj, e_comp->w, e_comp->h);
3994 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4002 ow = cw->w, oh = cw->h;
4004 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4005 zone = e_comp_object_util_zone_get(obj);
4006 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4007 if (x) *x = zx + (zw - ow) / 2;
4008 if (y) *y = zy + (zh - oh) / 2;
4012 e_comp_object_input_objs_del(Evas_Object *obj)
4015 E_Input_Rect_Data *input_rect_data;
4016 E_Input_Rect_Smart_Data *input_rect_sd;
4021 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4022 if (!input_rect_sd) return;
4024 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4026 if (input_rect_data->obj)
4028 evas_object_smart_member_del(input_rect_data->obj);
4029 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4031 E_FREE(input_rect_data);
4036 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4039 E_Input_Rect_Data *input_rect_data = NULL;
4040 E_Input_Rect_Smart_Data *input_rect_sd;
4041 int client_w, client_h;
4043 if (cw->ec->client.w)
4044 client_w = cw->ec->client.w;
4046 client_w = cw->ec->w;
4048 if (cw->ec->client.h)
4049 client_h = cw->ec->client.h;
4051 client_h = cw->ec->h;
4053 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4057 _e_comp_input_obj_smart_init();
4058 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4059 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4060 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4063 input_rect_sd->cw = cw;
4066 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4069 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4070 if (input_rect_data)
4072 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4073 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4077 if ((input_rect_data) &&
4078 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4080 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4081 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4082 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4083 evas_object_clip_set(input_rect_data->obj, cw->clip);
4084 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4085 evas_object_geometry_set(input_rect_data->obj,
4086 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4087 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4088 evas_object_pass_events_set(cw->default_input_obj, 1);
4089 evas_object_pass_events_set(cw->obj, 1);
4092 evas_object_show(input_rect_data->obj);
4093 evas_object_show(cw->input_obj);
4098 evas_object_smart_member_del(cw->input_obj);
4099 E_FREE_FUNC(cw->input_obj, evas_object_del);
4100 evas_object_pass_events_set(cw->default_input_obj, 0);
4101 evas_object_pass_events_set(cw->obj, 0);
4106 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4109 E_Input_Rect_Smart_Data *input_rect_sd;
4110 E_Input_Rect_Data *input_rect_data;
4113 if (!cw->input_obj) return;
4115 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4118 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4120 *list = eina_list_append(*list, &input_rect_data->rect);
4126 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4129 if (l) *l = cw->client_inset.l;
4130 if (r) *r = cw->client_inset.r;
4131 if (t) *t = cw->client_inset.t;
4132 if (b) *b = cw->client_inset.b;
4135 /* set geometry for CSD */
4137 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4143 if (cw->frame_object)
4144 CRI("ACK! ec:%p", cw->ec);
4145 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4146 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4147 calc = cw->client_inset.calc;
4148 cw->client_inset.calc = l || r || t || b;
4149 eina_stringshare_replace(&cw->frame_theme, "borderless");
4150 if (cw->client_inset.calc)
4152 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4153 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4154 e_client_size_set(cw->ec, tw, th);
4156 else if (cw->ec->maximized || cw->ec->fullscreen)
4158 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4159 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4161 if (!cw->ec->new_client)
4163 if (calc && cw->client_inset.calc)
4165 tx = cw->ec->x - (l - cw->client_inset.l);
4166 ty = cw->ec->y - (t - cw->client_inset.t);
4167 e_client_pos_set(cw->ec, tx, ty);
4169 cw->ec->changes.pos = cw->ec->changes.size = 1;
4172 cw->client_inset.l = l;
4173 cw->client_inset.r = r;
4174 cw->client_inset.t = t;
4175 cw->client_inset.b = b;
4179 e_comp_object_frame_allowed(Evas_Object *obj)
4181 API_ENTRY EINA_FALSE;
4182 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4186 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4188 API_ENTRY EINA_FALSE;
4189 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4190 eina_stringshare_replace(&cw->frame_name, name);
4191 if (cw->frame_object)
4192 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4197 e_comp_object_frame_exists(Evas_Object *obj)
4199 API_ENTRY EINA_FALSE;
4200 return !!cw->frame_object;
4204 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4206 Evas_Object *o, *pbg;
4209 Eina_Stringshare *theme;
4211 API_ENTRY EINA_FALSE;
4213 if (!e_util_strcmp(cw->frame_theme, name))
4214 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4215 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4216 return _e_comp_object_shadow_setup(cw);
4217 pbg = cw->frame_object;
4218 theme = eina_stringshare_add(name);
4220 if (cw->frame_object)
4224 w = cw->ec->w, h = cw->ec->h;
4225 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4226 if ((cw->ec->w != w) || (cw->ec->h != h))
4228 cw->ec->changes.size = 1;
4231 E_FREE_FUNC(cw->frame_object, evas_object_del);
4232 if (!name) goto reshadow;
4234 o = edje_object_add(e_comp->evas);
4235 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4236 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4237 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4239 cw->frame_object = NULL;
4241 eina_stringshare_del(cw->frame_theme);
4242 cw->frame_theme = theme;
4247 if (theme != e_config->theme_default_border_style)
4249 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4250 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4254 ok = e_theme_edje_object_set(o, "base/theme/border",
4255 "e/widgets/border/default/border");
4256 if (ok && (theme == e_config->theme_default_border_style))
4258 /* Reset default border style to default */
4259 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4260 e_config_save_queue();
4267 cw->frame_object = o;
4268 eina_stringshare_del(cw->frame_theme);
4269 cw->frame_theme = theme;
4270 evas_object_name_set(o, "cw->frame_object");
4273 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4277 cw->ec->changes.icon = 1;
4283 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4288 _e_comp_object_shadow_setup(cw);
4291 int old_x, old_y, new_x = 0, new_y = 0;
4293 old_x = cw->x, old_y = cw->y;
4295 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4297 new_x = cw->ec->x, new_y = cw->ec->y;
4298 else if (cw->ec->placed || (!cw->ec->new_client))
4300 /* if no previous frame:
4301 * - reapply client_inset
4306 if (cw->ec->changes.size)
4314 zone = e_comp_zone_find_by_ec(cw->ec);
4317 x = cw->ec->client.x, y = cw->ec->client.y;
4318 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4319 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4321 new_x = x, new_y = y;
4324 if (old_x != new_x || old_y != new_y)
4326 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4327 cw->y = cw->x = -99999;
4328 evas_object_move(obj, new_x, new_y);
4332 if (cw->ec->maximized)
4334 cw->ec->changes.need_maximize = 1;
4337 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4338 if (cw->frame_object)
4340 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4343 cw->frame_extends = 0;
4344 evas_object_del(pbg);
4349 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4351 E_Comp_Object_Mover *prov;
4354 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4355 edje_object_signal_emit(cw->shobj, sig, src);
4356 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4357 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4358 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4360 /* start with highest priority callback first */
4361 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4363 if (!e_util_glob_match(sig, prov->sig)) continue;
4364 if (prov->func(prov->data, obj, sig)) break;
4369 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4371 /* FIXME: at some point I guess this should use eo to inherit
4372 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4373 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4376 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4380 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4383 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4387 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4390 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4394 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4397 Eina_Rectangle rect;
4400 if (cw->ec->input_only || (!cw->updates)) return;
4401 if (cw->nocomp) return;
4402 rect.x = x, rect.y = y;
4403 rect.w = w, rect.h = h;
4404 evas_object_smart_callback_call(obj, "damage", &rect);
4406 if (e_comp_is_on_overlay(cw->ec))
4408 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4409 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4410 * E module attempts to block screen update due to the particular policy.
4412 if (e_pixmap_resource_get(cw->ec->pixmap))
4413 cw->hwc_need_update = EINA_TRUE;
4416 /* ignore overdraw */
4417 if (cw->updates_full)
4419 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4420 e_comp_object_render_update_add(obj);
4422 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4423 evas_object_show(cw->smart_obj);
4427 /* clip rect to client surface */
4428 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4429 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4430 /* if rect is the total size of the client after clip, clear the updates
4431 * since this is guaranteed to be the whole region anyway
4433 eina_tiler_area_size_get(cw->updates, &tw, &th);
4434 if ((w > tw) || (h > th))
4436 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4437 eina_tiler_clear(cw->updates);
4438 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4440 tw = cw->ec->client.w, th = cw->ec->client.h;
4442 if ((!x) && (!y) && (w == tw) && (h == th))
4444 eina_tiler_clear(cw->updates);
4445 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4446 cw->updates_full = 1;
4447 cw->update_count = 0;
4450 if (cw->update_count > UPDATE_MAX)
4452 /* this is going to get really dumb, so just update the whole thing */
4453 eina_tiler_clear(cw->updates);
4454 cw->update_count = cw->updates_full = 1;
4455 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4456 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4460 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4461 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4463 cw->updates_exist = 1;
4464 e_comp_object_render_update_add(obj);
4466 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4467 evas_object_show(cw->smart_obj);
4471 e_comp_object_damage_exists(Evas_Object *obj)
4473 API_ENTRY EINA_FALSE;
4474 return cw->updates_exist;
4478 e_comp_object_render_update_add(Evas_Object *obj)
4482 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4483 if (cw->render_update_lock.lock) return;
4484 if (e_object_is_del(E_OBJECT(cw->ec)))
4485 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4486 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4490 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4492 e_comp_render_queue();
4496 e_comp_object_render_update_del(Evas_Object *obj)
4500 if (cw->ec->input_only || (!cw->updates)) return;
4501 if (!cw->update) return;
4503 /* this gets called during comp animating to clear the update flag */
4504 if (e_comp->grabbed) return;
4505 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4506 if (!e_comp->updates)
4508 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4509 if (e_comp->render_animator)
4510 ecore_animator_freeze(e_comp->render_animator);
4515 e_comp_object_shape_apply(Evas_Object *obj)
4519 unsigned int i, *pix, *p;
4523 if (!cw->ec) return; //NYI
4524 if (cw->external_content) return;
4527 if ((cw->ec->shape_rects_num >= 1) &&
4528 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4533 ERR("BUGGER: shape with native surface? cw=%p", cw);
4536 evas_object_image_size_get(cw->obj, &w, &h);
4537 if ((w < 1) || (h < 1)) return;
4540 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4541 _e_comp_object_alpha_set(cw);
4542 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4543 evas_object_image_alpha_set(o, 1);
4545 p = pix = evas_object_image_data_get(cw->obj, 1);
4548 evas_object_image_data_set(cw->obj, pix);
4553 unsigned char *spix, *sp;
4555 spix = calloc(w * h, sizeof(unsigned char));
4557 for (i = 0; i < cw->ec->shape_rects_num; i++)
4561 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4562 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4563 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4564 sp = spix + (w * ry) + rx;
4565 for (py = 0; py < rh; py++)
4567 for (px = 0; px < rw; px++)
4575 for (py = 0; py < h; py++)
4577 for (px = 0; px < w; px++)
4579 unsigned int mask, imask;
4581 mask = ((unsigned int)(*sp)) << 24;
4583 imask |= imask >> 8;
4584 imask |= imask >> 8;
4585 *p = mask | (*p & imask);
4586 //if (*sp) *p = 0xff000000 | *p;
4587 //else *p = 0x00000000;
4596 for (py = 0; py < h; py++)
4598 for (px = 0; px < w; px++)
4602 evas_object_image_data_set(cw->obj, pix);
4603 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4604 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4606 evas_object_image_data_set(o, pix);
4607 evas_object_image_data_update_add(o, 0, 0, w, h);
4609 // don't need to fix alpha chanel as blending
4610 // should be totally off here regardless of
4611 // alpha channel content
4615 _e_comp_object_clear(E_Comp_Object *cw)
4620 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4622 if (cw->render_update_lock.lock) return;
4625 e_pixmap_clear(cw->ec->pixmap);
4627 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4628 evas_object_image_size_set(cw->obj, 1, 1);
4629 evas_object_image_data_set(cw->obj, NULL);
4630 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4632 evas_object_image_size_set(o, 1, 1);
4633 evas_object_image_data_set(o, NULL);
4636 e_comp_object_render_update_del(cw->smart_obj);
4640 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4644 API_ENTRY EINA_FALSE;
4646 if (cw->transparent.set == set)
4651 evas_object_color_get(obj, &r, &g, &b, &a);
4652 evas_object_color_set(obj, 0, 0, 0, 0);
4654 cw->transparent.user_r = r;
4655 cw->transparent.user_g = g;
4656 cw->transparent.user_b = b;
4657 cw->transparent.user_a = a;
4659 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4661 cw->transparent.user_r,
4662 cw->transparent.user_g,
4663 cw->transparent.user_b,
4664 cw->transparent.user_a);
4666 cw->transparent.set = EINA_TRUE;
4670 cw->transparent.set = EINA_FALSE;
4672 evas_object_color_set(obj,
4673 cw->transparent.user_r,
4674 cw->transparent.user_g,
4675 cw->transparent.user_b,
4676 cw->transparent.user_a);
4678 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4680 cw->transparent.user_r,
4681 cw->transparent.user_g,
4682 cw->transparent.user_b,
4683 cw->transparent.user_a);
4689 /* helper function to simplify toggling of redirection for display servers which support it */
4691 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4696 if (cw->redirected == set) return;
4697 cw->redirected = set;
4698 if (cw->external_content) return;
4700 e_comp_object_map_update(obj);
4704 if (cw->updates_exist)
4705 e_comp_object_render_update_add(obj);
4707 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4709 _e_comp_object_transparent_set(obj, EINA_FALSE);
4710 evas_object_smart_callback_call(obj, "redirected", NULL);
4714 _e_comp_object_clear(cw);
4715 _e_comp_object_transparent_set(obj, EINA_TRUE);
4716 evas_object_smart_callback_call(obj, "unredirected", NULL);
4721 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4724 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4726 if (cw->buffer_destroy_listener.notify)
4728 cw->buffer_destroy_listener.notify = NULL;
4729 wl_list_remove(&cw->buffer_destroy_listener.link);
4732 if (e_object_is_del(E_OBJECT(cw->ec)))
4734 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4739 /* if it's current displaying buffer, do not remove its content */
4740 if (!evas_object_visible_get(cw->ec->frame))
4741 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4746 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4751 if (cw->buffer_destroy_listener.notify)
4753 wl_list_remove(&cw->buffer_destroy_listener.link);
4754 cw->buffer_destroy_listener.notify = NULL;
4757 if (cw->tbm_surface)
4759 tbm_surface_internal_unref(cw->tbm_surface);
4760 cw->tbm_surface = NULL;
4765 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4767 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4768 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4770 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4772 tbm_surface_internal_ref(ns->data.tbm.buffer);
4773 cw->tbm_surface = ns->data.tbm.buffer;
4777 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4778 evas_object_image_native_surface_set(cw->obj, ns);
4782 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4784 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4785 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4786 evas_object_image_native_surface_set(o, ns);
4793 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4795 Evas_Native_Surface ns;
4798 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4799 if (cw->ec->input_only) return;
4800 if (cw->external_content) return;
4801 if (cw->render_update_lock.lock) return;
4804 memset(&ns, 0, sizeof(Evas_Native_Surface));
4808 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4809 set = (!cw->ec->shaped);
4811 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4815 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4819 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4822 if (cw->ec->input_only) return;
4825 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4826 _e_comp_object_alpha_set(cw);
4828 e_comp_object_native_surface_set(obj, cw->native);
4829 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4833 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4839 if (cw->blanked == set) return;
4841 _e_comp_object_alpha_set(cw);
4844 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4845 evas_object_image_data_set(cw->obj, NULL);
4849 e_comp_object_native_surface_set(obj, 1);
4850 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4854 _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)
4859 if (!_damage_trace) return;
4863 if (!evas_object_visible_get(cw->obj)) return;
4865 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4867 o = evas_object_rectangle_add(e_comp->evas);
4868 evas_object_layer_set(o, E_LAYER_MAX);
4869 evas_object_name_set(o, "damage_trace");
4870 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4871 evas_object_resize(o, dmg_w, dmg_h);
4872 evas_object_color_set(o, 0, 128, 0, 128);
4873 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4874 evas_object_pass_events_set(o, EINA_TRUE);
4875 evas_object_show(o);
4877 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4879 dmg_w, dmg_h, dmg_x, dmg_y,
4880 origin->w, origin->h, origin->x, origin->y);
4882 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4885 /* mark an object as dirty and setup damages */
4887 e_comp_object_dirty(Evas_Object *obj)
4890 Eina_Rectangle *rect;
4894 Eina_Bool dirty, visible;
4898 if (cw->external_content) return;
4899 if (!cw->redirected) return;
4900 if (cw->render_update_lock.lock)
4902 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4905 /* only actually dirty if pixmap is available */
4906 if (!e_pixmap_resource_get(cw->ec->pixmap))
4908 // e_pixmap_size_get returns last attached buffer size
4909 // eventhough it is destroyed
4910 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4913 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4914 visible = cw->visible;
4915 if (!dirty) w = h = 1;
4916 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4918 evas_object_image_data_set(cw->obj, NULL);
4919 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4920 evas_object_image_size_set(cw->obj, tw, th);
4921 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4922 if (cw->pending_updates)
4923 eina_tiler_area_size_set(cw->pending_updates, w, h);
4924 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4926 evas_object_image_pixels_dirty_set(o, dirty);
4928 evas_object_image_data_set(o, NULL);
4929 evas_object_image_size_set(o, tw, th);
4930 visible |= evas_object_visible_get(o);
4934 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4938 e_comp_object_native_surface_set(obj, 1);
4940 m = _e_comp_object_map_damage_transform_get(cw->ec);
4941 it = eina_tiler_iterator_new(cw->updates);
4942 EINA_ITERATOR_FOREACH(it, rect)
4944 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4945 * of evas engine and doesn't convert damage according to evas_map.
4946 * so damage of evas_object_image use surface coordinate.
4950 int damage_x, damage_y, damage_w, damage_h;
4952 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4953 &damage_x, &damage_y, &damage_w, &damage_h);
4954 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4955 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4959 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4960 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4963 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4964 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4965 if (cw->pending_updates)
4966 eina_tiler_rect_add(cw->pending_updates, rect);
4968 eina_iterator_free(it);
4969 if (m) e_map_free(m);
4970 if (cw->pending_updates)
4971 eina_tiler_clear(cw->updates);
4974 cw->pending_updates = cw->updates;
4975 cw->updates = eina_tiler_new(w, h);
4976 eina_tiler_tile_size_set(cw->updates, 1, 1);
4978 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4979 evas_object_smart_callback_call(obj, "dirty", NULL);
4980 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4981 /* force render if main object is hidden but mirrors are visible */
4982 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4983 e_comp_object_render(obj);
4987 e_comp_object_render(Evas_Object *obj)
4994 API_ENTRY EINA_FALSE;
4996 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4997 if (cw->ec->input_only) return EINA_TRUE;
4998 if (cw->external_content) return EINA_TRUE;
4999 if (cw->native) return EINA_FALSE;
5000 /* if comp object is not redirected state, comp object should not be set by newly committed data
5001 because image size of comp object is 1x1 and it should not be shown on canvas */
5002 if (!cw->redirected) return EINA_TRUE;
5003 if (cw->render_update_lock.lock)
5005 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5008 e_comp_object_render_update_del(obj);
5009 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5011 if (!cw->pending_updates)
5013 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5014 evas_object_image_data_set(cw->obj, NULL);
5015 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5016 evas_object_image_data_set(o, NULL);
5020 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5022 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5024 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5027 e_pixmap_image_refresh(cw->ec->pixmap);
5028 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5031 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5032 e_pixmap_image_data_ref(cw->ec->pixmap);
5034 /* set pixel data */
5035 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5036 _e_comp_object_alpha_set(cw);
5037 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5039 evas_object_image_data_set(o, pix);
5040 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5041 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5044 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5046 e_comp_client_post_update_add(cw->ec);
5051 /* create a duplicate of an evas object */
5053 e_comp_object_util_mirror_add(Evas_Object *obj)
5057 unsigned int *pix = NULL;
5058 Eina_Bool argb = EINA_FALSE;
5063 cw = evas_object_data_get(obj, "comp_mirror");
5066 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5067 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5068 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5069 evas_object_image_alpha_set(o, 1);
5070 evas_object_image_source_set(o, obj);
5073 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5074 if (cw->external_content)
5076 ERR("%p of client %p is external content.", obj, cw->ec);
5079 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5080 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5081 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5082 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5083 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5084 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5085 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5086 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5087 evas_object_data_set(o, "comp_mirror", cw);
5089 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5090 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5092 evas_object_image_size_set(o, tw, th);
5095 pix = evas_object_image_data_get(cw->obj, 0);
5101 evas_object_image_native_surface_set(o, cw->ns);
5104 Evas_Native_Surface ns;
5105 memset(&ns, 0, sizeof(Evas_Native_Surface));
5106 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5107 evas_object_image_native_surface_set(o, &ns);
5112 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5113 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5115 (e_pixmap_image_exists(cw->ec->pixmap)))
5116 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5118 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5125 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5126 evas_object_image_pixels_dirty_set(o, dirty);
5127 evas_object_image_data_set(o, pix);
5128 evas_object_image_data_set(cw->obj, pix);
5130 evas_object_image_data_update_add(o, 0, 0, tw, th);
5135 //////////////////////////////////////////////////////
5138 e_comp_object_effect_allowed_get(Evas_Object *obj)
5140 API_ENTRY EINA_FALSE;
5142 if (!cw->shobj) return EINA_FALSE;
5143 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5144 return !e_comp_config_get()->match.disable_borders;
5147 /* setup an api effect for a client */
5149 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5152 Eina_Stringshare *grp;
5153 E_Comp_Config *config;
5154 Eina_Bool loaded = EINA_FALSE;
5156 API_ENTRY EINA_FALSE;
5157 if (!cw->shobj) return EINA_FALSE; //input window
5159 if (!effect) effect = "none";
5160 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5162 config = e_comp_config_get();
5163 if ((config) && (config->effect_file))
5165 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5167 cw->effect_set = EINA_TRUE;
5174 edje_object_file_get(cw->effect_obj, NULL, &grp);
5175 cw->effect_set = !eina_streq(effect, "none");
5176 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5177 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5179 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5180 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5181 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5183 if (cw->effect_running)
5185 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5188 cw->effect_set = EINA_FALSE;
5189 return cw->effect_set;
5193 if (cw->effect_running)
5195 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5198 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5199 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5200 if (cw->effect_clip)
5202 evas_object_clip_unset(cw->clip);
5203 cw->effect_clip = 0;
5205 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5207 _e_comp_object_dim_update(cw);
5209 return cw->effect_set;
5212 /* set params for embryo scripts in effect */
5214 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5216 Edje_Message_Int_Set *msg;
5220 EINA_SAFETY_ON_NULL_RETURN(params);
5221 EINA_SAFETY_ON_FALSE_RETURN(count);
5222 if (!cw->effect_set) return;
5224 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5225 msg->count = (int)count;
5226 for (x = 0; x < count; x++)
5227 msg->val[x] = params[x];
5228 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5229 edje_object_message_signal_process(cw->effect_obj);
5233 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5235 Edje_Signal_Cb end_cb;
5237 E_Comp_Object *cw = data;
5239 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5240 cw->effect_running = 0;
5241 if (!_e_comp_object_animating_end(cw)) return;
5243 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5245 evas_object_data_del(cw->smart_obj, "effect_running");
5246 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5247 e_comp_visibility_calculation_set(EINA_TRUE);
5250 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5251 if (!end_cb) return;
5252 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5253 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5254 end_cb(end_data, cw->smart_obj, emission, source);
5257 /* clip effect to client's zone */
5259 e_comp_object_effect_clip(Evas_Object *obj)
5263 zone = e_comp_zone_find_by_ec(cw->ec);
5265 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5266 if (!cw->effect_clip_able) return;
5267 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5268 cw->effect_clip = 1;
5271 /* unclip effect from client's zone */
5273 e_comp_object_effect_unclip(Evas_Object *obj)
5276 if (!cw->effect_clip) return;
5277 evas_object_clip_unset(cw->smart_obj);
5278 cw->effect_clip = 0;
5281 /* start effect, running end_cb after */
5283 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5285 API_ENTRY EINA_FALSE;
5286 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5287 if (!cw->effect_set) return EINA_FALSE;
5289 if (cw->effect_running)
5291 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5294 e_comp_object_effect_clip(obj);
5295 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5297 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5298 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5299 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5300 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5302 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5303 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5305 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5306 _e_comp_object_animating_begin(cw);
5307 cw->effect_running = 1;
5311 /* stop a currently-running effect immediately */
5313 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5316 Edje_Signal_Cb end_cb_before = NULL;
5317 void *end_data_before = NULL;
5318 API_ENTRY EINA_FALSE;
5320 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5321 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5323 if (end_cb_before != end_cb) return EINA_TRUE;
5324 e_comp_object_effect_unclip(obj);
5325 if (cw->effect_clip)
5327 evas_object_clip_unset(cw->effect_obj);
5328 cw->effect_clip = 0;
5330 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5331 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5333 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5335 evas_object_data_del(cw->smart_obj, "effect_running");
5336 e_comp_visibility_calculation_set(EINA_TRUE);
5339 cw->effect_running = 0;
5340 ret = _e_comp_object_animating_end(cw);
5342 if ((ret) && (end_cb_before))
5344 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5345 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5352 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5354 return a->pri - b->pri;
5357 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5358 E_API E_Comp_Object_Mover *
5359 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5361 E_Comp_Object_Mover *prov;
5363 prov = E_NEW(E_Comp_Object_Mover, 1);
5364 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5365 prov->func = provider;
5366 prov->data = (void*)data;
5369 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5370 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5375 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5377 EINA_SAFETY_ON_NULL_RETURN(prov);
5378 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5383 e_comp_object_effect_object_get(Evas_Object *obj)
5387 return cw->effect_obj;
5391 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5393 API_ENTRY EINA_FALSE;
5394 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5395 if (!cw->effect_set) return EINA_FALSE;
5402 ////////////////////////////////////
5405 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5407 if (e_comp->autoclose.obj)
5409 e_comp_ungrab_input(0, 1);
5410 if (e_comp->autoclose.del_cb)
5411 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5412 else if (!already_del)
5414 evas_object_hide(e_comp->autoclose.obj);
5415 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5417 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5419 e_comp->autoclose.obj = NULL;
5420 e_comp->autoclose.data = NULL;
5421 e_comp->autoclose.del_cb = NULL;
5422 e_comp->autoclose.key_cb = NULL;
5423 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5427 _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)
5429 _e_comp_object_autoclose_cleanup(0);
5433 _e_comp_object_autoclose_setup(Evas_Object *obj)
5435 if (!e_comp->autoclose.rect)
5437 /* create rect just below autoclose object to catch mouse events */
5438 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5439 evas_object_move(e_comp->autoclose.rect, 0, 0);
5440 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5441 evas_object_show(e_comp->autoclose.rect);
5442 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5443 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5444 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5445 e_comp_grab_input(0, 1);
5447 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5448 evas_object_focus_set(obj, 1);
5452 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5454 _e_comp_object_autoclose_setup(obj);
5455 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5459 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5461 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5462 _e_comp_object_autoclose_cleanup(1);
5463 if (e_client_focused_get()) return;
5464 if (e_config->focus_policy != E_FOCUS_MOUSE)
5469 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5473 if (e_comp->autoclose.obj)
5475 if (e_comp->autoclose.obj == obj) return;
5476 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5477 e_comp->autoclose.obj = obj;
5478 e_comp->autoclose.del_cb = del_cb;
5479 e_comp->autoclose.key_cb = cb;
5480 e_comp->autoclose.data = (void*)data;
5481 if (evas_object_visible_get(obj))
5482 _e_comp_object_autoclose_setup(obj);
5484 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5485 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5488 e_comp->autoclose.obj = obj;
5489 e_comp->autoclose.del_cb = del_cb;
5490 e_comp->autoclose.key_cb = cb;
5491 e_comp->autoclose.data = (void*)data;
5492 if (evas_object_visible_get(obj))
5493 _e_comp_object_autoclose_setup(obj);
5495 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5496 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5500 e_comp_object_is_animating(Evas_Object *obj)
5504 return cw->animating;
5508 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5512 if ((cw->external_content) &&
5513 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5515 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5516 "But current external content is %d object for %p.",
5517 cw->content_type, cw->ec);
5521 cw->user_alpha_set = EINA_TRUE;
5522 cw->user_alpha = alpha;
5524 if (!cw->obj) return;
5526 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5528 evas_object_image_alpha_set(cw->obj, alpha);
5530 if ((!cw->native) && (!cw->external_content))
5531 evas_object_image_data_set(cw->obj, NULL);
5535 e_comp_object_alpha_get(Evas_Object *obj)
5537 API_ENTRY EINA_FALSE;
5539 return evas_object_image_alpha_get(cw->obj);
5543 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5545 Eina_Bool mask_set = EINA_FALSE;
5549 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5550 if (cw->ec->input_only) return;
5557 o = evas_object_rectangle_add(e_comp->evas);
5558 evas_object_color_set(o, 0, 0, 0, 0);
5559 evas_object_clip_set(o, cw->clip);
5560 evas_object_smart_member_add(o, obj);
5561 evas_object_move(o, 0, 0);
5562 evas_object_resize(o, cw->w, cw->h);
5563 /* save render op value to restore when clear a mask.
5565 * NOTE: DO NOT change the render op on ec->frame while mask object
5566 * is set. it will overwrite the changed op value. */
5567 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5568 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5569 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5570 if (cw->visible) evas_object_show(o);
5573 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5574 ELOGF("COMP", " |mask_obj", cw->ec);
5575 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5582 evas_object_smart_member_del(cw->mask.obj);
5583 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5585 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5586 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5592 e_comp_object_mask_has(Evas_Object *obj)
5594 API_ENTRY EINA_FALSE;
5596 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5600 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5605 if ((cw->external_content) &&
5606 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5608 WRN("Can set up size to ONLY evas \"image\" object. "
5609 "But current external content is %d object for %p.",
5610 cw->content_type, cw->ec);
5614 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5616 evas_object_image_size_set(cw->obj, tw, th);
5620 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5622 Eina_Bool transform_set = EINA_FALSE;
5624 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5625 if (cw->ec->input_only) return;
5627 transform_set = !!set;
5631 if (!cw->transform_bg_obj)
5633 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5634 evas_object_move(o, 0, 0);
5635 evas_object_resize(o, 1, 1);
5636 if (cw->transform_bg_color.a >= 255)
5637 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5639 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5640 evas_object_color_set(o,
5641 cw->transform_bg_color.r,
5642 cw->transform_bg_color.g,
5643 cw->transform_bg_color.b,
5644 cw->transform_bg_color.a);
5645 if (cw->visible) evas_object_show(o);
5647 cw->transform_bg_obj = o;
5648 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5650 _e_comp_object_transform_obj_stack_update(obj);
5654 if (cw->transform_bg_obj)
5656 evas_object_smart_member_del(cw->transform_bg_obj);
5657 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5663 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5667 cw->transform_bg_color.r = r;
5668 cw->transform_bg_color.g = g;
5669 cw->transform_bg_color.b = b;
5670 cw->transform_bg_color.a = a;
5672 if (cw->transform_bg_obj)
5674 evas_object_color_set(cw->transform_bg_obj,
5675 cw->transform_bg_color.r,
5676 cw->transform_bg_color.g,
5677 cw->transform_bg_color.b,
5678 cw->transform_bg_color.a);
5683 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5686 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5687 if (cw->ec->input_only) return;
5688 if (!cw->transform_bg_obj) return;
5690 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5694 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5697 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5698 if (cw->ec->input_only) return;
5699 if (!cw->transform_bg_obj) return;
5701 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5705 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5707 Eina_Bool transform_set = EINA_FALSE;
5709 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5710 if (cw->ec->input_only) return;
5712 transform_set = !!set;
5716 if (!cw->transform_tranp_obj)
5718 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5719 evas_object_move(o, 0, 0);
5720 evas_object_resize(o, 1, 1);
5721 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5722 evas_object_color_set(o, 0, 0, 0, 0);
5723 if (cw->visible) evas_object_show(o);
5725 cw->transform_tranp_obj = o;
5726 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5728 _e_comp_object_transform_obj_stack_update(obj);
5732 if (cw->transform_tranp_obj)
5734 evas_object_smart_member_del(cw->transform_tranp_obj);
5735 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5741 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5744 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5745 if (cw->ec->input_only) return;
5746 if (!cw->transform_tranp_obj) return;
5748 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5752 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5755 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5756 if (cw->ec->input_only) return;
5757 if (!cw->transform_tranp_obj) return;
5759 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5763 e_comp_object_layer_update(Evas_Object *obj,
5764 Evas_Object *above, Evas_Object *below)
5766 E_Comp_Object *cw2 = NULL;
5767 Evas_Object *o = NULL;
5772 if (cw->ec->layer_block) return;
5773 if ((above) && (below))
5775 ERR("Invalid layer update request! cw=%p", cw);
5783 layer = evas_object_layer_get(o);
5784 cw2 = evas_object_data_get(o, "comp_obj");
5787 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5789 o = evas_object_above_get(o);
5790 if ((!o) || (o == cw->smart_obj)) break;
5791 if (evas_object_layer_get(o) != layer)
5793 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5798 ec = e_client_top_get();
5799 if (ec) o = ec->frame;
5802 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5806 _e_comp_object_layers_remove(cw);
5809 if (cw2->layer > cw->layer)
5810 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5811 else if (cw2->layer == cw->layer)
5814 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5816 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5818 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5821 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5824 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5828 e_comp_object_layer_get(Evas_Object *obj)
5835 e_comp_object_content_set(Evas_Object *obj,
5836 Evas_Object *content,
5837 E_Comp_Object_Content_Type type)
5839 API_ENTRY EINA_FALSE;
5841 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5842 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5843 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5847 ERR("Can't set e.swallow.content to requested content. "
5848 "Previous comp object should not be changed at all.");
5852 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5854 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5855 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5857 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5858 type, content, cw->ec, cw->ec->pixmap);
5862 cw->external_content = EINA_TRUE;
5865 cw->content_type = type;
5866 e_util_size_debug_set(cw->obj, 1);
5867 evas_object_name_set(cw->obj, "cw->obj");
5868 _e_comp_object_alpha_set(cw);
5871 _e_comp_object_shadow_setup(cw);
5877 e_comp_object_content_unset(Evas_Object *obj)
5879 API_ENTRY EINA_FALSE;
5881 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5882 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5884 if (!cw->obj && !cw->ec->visible)
5886 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5890 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5892 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5898 if (cw->frame_object)
5899 edje_object_part_unswallow(cw->frame_object, cw->obj);
5901 edje_object_part_unswallow(cw->shobj, cw->obj);
5903 evas_object_del(cw->obj);
5904 evas_object_hide(cw->obj);
5908 cw->external_content = EINA_FALSE;
5909 if (cw->ec->is_cursor)
5912 DBG("%p is cursor surface..", cw->ec);
5913 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5915 evas_object_resize(cw->ec->frame, pw, ph);
5916 evas_object_hide(cw->ec->frame);
5921 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5922 cw->obj = evas_object_image_filled_add(e_comp->evas);
5923 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5924 e_util_size_debug_set(cw->obj, 1);
5925 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5926 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5927 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5928 evas_object_name_set(cw->obj, "cw->obj");
5929 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5930 _e_comp_object_alpha_set(cw);
5933 _e_comp_object_shadow_setup(cw);
5938 _e_comp_intercept_show_helper(cw);
5942 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5943 e_comp_object_dirty(cw->smart_obj);
5944 e_comp_object_render(cw->smart_obj);
5945 e_comp_object_render_update_add(obj);
5950 EINTERN Evas_Object *
5951 e_comp_object_content_get(Evas_Object *obj)
5955 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5957 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5959 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5966 E_API E_Comp_Object_Content_Type
5967 e_comp_object_content_type_get(Evas_Object *obj)
5969 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5971 return cw->content_type;
5975 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5978 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5979 E_Comp_Config *conf = e_comp_config_get();
5980 if (cw->ec->input_only) return;
5981 if (!conf->dim_rect_enable) return;
5983 cw->dim.mask_set = mask_set;
5989 if (!cw->dim.enable) return;
5990 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5994 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5996 Eina_Bool mask_set = EINA_FALSE;
6000 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6001 E_Comp_Config *conf = e_comp_config_get();
6002 if (cw->ec->input_only) return;
6003 if (!conf->dim_rect_enable) return;
6009 if (cw->dim.mask_obj)
6011 evas_object_smart_member_del(cw->dim.mask_obj);
6012 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6015 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);
6016 o = evas_object_rectangle_add(e_comp->evas);
6017 evas_object_color_set(o, 0, 0, 0, 0);
6018 evas_object_smart_member_add(o, obj);
6019 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6020 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6022 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6023 if (cw->visible) evas_object_show(o);
6025 cw->dim.mask_obj = o;
6026 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6028 evas_object_layer_set(cw->dim.mask_obj, 9998);
6032 if (cw->dim.mask_obj)
6034 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6035 evas_object_smart_member_del(cw->dim.mask_obj);
6036 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6042 e_comp_object_dim_client_set(E_Client *ec)
6044 E_Comp_Config *conf = e_comp_config_get();
6046 if (!conf->dim_rect_enable) return ;
6047 if (dim_client == ec) return;
6049 Eina_Bool prev_dim = EINA_FALSE;
6050 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6052 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6053 prev_dim = EINA_TRUE;
6055 if (prev_dim && dim_client->visible && ec)
6057 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6058 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6062 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6063 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6069 e_comp_object_dim_client_get(void)
6071 E_Comp_Config *conf = e_comp_config_get();
6073 if (!conf->dim_rect_enable ) return NULL;
6079 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6082 char emit[32] = "\0";
6083 E_Comp_Config *conf = e_comp_config_get();
6086 if (!conf->dim_rect_enable) return;
6087 if (!cw->effect_obj) return;
6088 if (enable == cw->dim.enable) return;
6090 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6091 if (noeffect || !conf->dim_rect_effect)
6093 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6097 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6100 cw->dim.enable = enable;
6102 if (cw->dim.mask_set && !enable)
6104 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6105 edje_object_signal_emit(cw->effect_obj, emit, "e");
6107 else if (cw->dim.mask_set && enable)
6109 edje_object_signal_emit(cw->effect_obj, emit, "e");
6110 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6114 edje_object_signal_emit(cw->effect_obj, emit, "e");
6119 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6121 API_ENTRY EINA_FALSE;
6122 E_Comp_Config *conf = e_comp_config_get();
6124 if (!ec) return EINA_FALSE;
6125 if (!conf->dim_rect_enable) return EINA_FALSE;
6127 if (cw->dim.enable) return EINA_TRUE;
6133 _e_comp_object_dim_update(E_Comp_Object *cw)
6135 E_Comp_Config *conf = e_comp_config_get();
6138 if (!conf->dim_rect_enable) return;
6139 if (!cw->effect_obj) return;
6142 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6143 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6145 if (cw->dim.mask_set)
6147 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6153 e_comp_object_clear(Evas_Object *obj)
6157 _e_comp_object_clear(cw);
6161 e_comp_object_hwc_update_exists(Evas_Object *obj)
6163 API_ENTRY EINA_FALSE;
6164 return cw->hwc_need_update;
6169 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6172 cw->hwc_need_update = set;
6176 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6178 API_ENTRY EINA_FALSE;
6179 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6183 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6186 if (cw->indicator.obj != indicator)
6187 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6188 cw->indicator.obj = indicator;
6189 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6193 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6196 if (cw->indicator.obj != indicator) return;
6197 cw->indicator.obj = NULL;
6198 edje_object_part_unswallow(cw->shobj, indicator);
6202 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6205 Edje_Message_Int_Set *msg;
6207 if (!cw->indicator.obj) return;
6209 cw->indicator.w = w;
6210 cw->indicator.h = h;
6212 if (!cw->shobj) return;
6214 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6218 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6219 edje_object_message_signal_process(cw->shobj);
6222 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6224 e_comp_object_map_update(Evas_Object *obj)
6227 E_Client *ec = cw->ec;
6228 E_Comp_Wl_Client_Data *cdata;
6230 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6233 int l, remain = sizeof buffer;
6236 if (e_object_is_del(E_OBJECT(ec))) return;
6237 cdata = e_client_cdata_get(ec);
6240 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6241 * when new buffer is attached.
6243 if (!cdata->buffer_ref.buffer) return;
6245 if ((!cw->redirected) ||
6246 (e_client_video_hw_composition_check(ec)) ||
6247 (!e_comp_wl_output_buffer_transform_get(ec) &&
6248 cdata->scaler.buffer_viewport.buffer.scale == 1))
6250 if (evas_object_map_enable_get(cw->effect_obj))
6252 ELOGF("TRANSFORM", "map: disable", cw->ec);
6253 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6254 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6255 evas_object_resize(cw->effect_obj, tw, th);
6262 EINA_SAFETY_ON_NULL_RETURN(map);
6264 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6270 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6272 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6273 e_map_point_image_uv_set(map, 0, x, y);
6274 l = snprintf(p, remain, "%d,%d", x, y);
6275 p += l, remain -= l;
6277 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6278 e_map_point_image_uv_set(map, 1, x, y);
6279 l = snprintf(p, remain, " %d,%d", x, y);
6280 p += l, remain -= l;
6282 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6283 e_map_point_image_uv_set(map, 2, x, y);
6284 l = snprintf(p, remain, " %d,%d", x, y);
6285 p += l, remain -= l;
6287 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6288 e_map_point_image_uv_set(map, 3, x, y);
6289 l = snprintf(p, remain, " %d,%d", x, y);
6290 p += l, remain -= l;
6292 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6294 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6296 e_comp_object_map_set(cw->effect_obj, map);
6297 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6301 /* if there's screen rotation with comp mode, then ec->effect_obj and
6302 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6304 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6305 evas_object_resize(cw->effect_obj, tw, th);
6309 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6311 API_ENTRY EINA_FALSE;
6313 cw->render_trace = set;
6319 e_comp_object_native_usable_get(Evas_Object *obj)
6321 API_ENTRY EINA_FALSE;
6322 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6324 if (cw->ec->input_only) return EINA_FALSE;
6325 if (cw->external_content) return EINA_FALSE;
6326 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6328 /* just return true value, if it is normal case */
6329 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6332 Evas_Native_Surface *ns;
6333 ns = evas_object_image_native_surface_get(cw->obj);
6335 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6338 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6346 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6348 API_ENTRY EINA_FALSE;
6349 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6350 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6351 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6355 case E_COMP_IMAGE_FILTER_BLUR:
6356 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6358 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6359 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6361 case E_COMP_IMAGE_FILTER_INVERSE:
6362 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6364 case E_COMP_IMAGE_FILTER_NONE:
6366 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6370 cw->image_filter = filter;
6375 EINTERN E_Comp_Image_Filter
6376 e_comp_object_image_filter_get(Evas_Object *obj)
6378 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6379 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6380 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6381 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6383 return cw->image_filter;
6387 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6391 if (!_damage_trace) return;
6393 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6394 evas_object_del(obj);
6396 _damage_trace_post_objs = NULL;
6400 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6402 if (!_damage_trace) return;
6404 _damage_trace_post_objs = _damage_trace_objs;
6405 _damage_trace_objs = NULL;
6409 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6411 if (_damage_trace == onoff) return;
6415 evas_event_callback_add(e_comp->evas,
6416 EVAS_CALLBACK_RENDER_PRE,
6417 _e_comp_object_damage_trace_render_pre_cb,
6420 evas_event_callback_add(e_comp->evas,
6421 EVAS_CALLBACK_RENDER_POST,
6422 _e_comp_object_damage_trace_render_post_cb,
6429 EINA_LIST_FREE(_damage_trace_objs, obj)
6430 evas_object_del(obj);
6432 _damage_trace_objs = NULL;
6434 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6435 evas_object_del(obj);
6437 _damage_trace_post_objs = NULL;
6439 evas_event_callback_del(e_comp->evas,
6440 EVAS_CALLBACK_RENDER_PRE,
6441 _e_comp_object_damage_trace_render_pre_cb);
6443 evas_event_callback_del(e_comp->evas,
6444 EVAS_CALLBACK_RENDER_POST,
6445 _e_comp_object_damage_trace_render_post_cb);
6448 _damage_trace = onoff;
6452 e_comp_object_redirected_get(Evas_Object *obj)
6454 API_ENTRY EINA_FALSE;
6455 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6457 return cw->redirected;
6461 e_comp_object_color_visible_get(Evas_Object *obj)
6463 API_ENTRY EINA_FALSE;
6466 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6468 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6472 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6476 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6480 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6488 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6490 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6492 return e_map_set_to_comp_object(em, obj);
6496 e_comp_object_map_get(const Evas_Object *obj)
6498 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6500 return e_map_get_from_comp_object(obj);
6504 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6506 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6508 evas_object_map_enable_set(obj, enable);
6514 e_comp_object_render_update_lock(Evas_Object *obj)
6516 E_Comp_Wl_Buffer *buffer;
6517 struct wayland_tbm_client_queue *cqueue;
6519 API_ENTRY EINA_FALSE;
6521 if (cw->render_update_lock.lock == 0)
6523 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6525 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6526 if ((buffer) && (buffer->resource))
6528 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6530 wayland_tbm_server_client_queue_flush(cqueue);
6533 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6534 e_comp_object_render_update_del(obj);
6536 ELOGF("COMP", "Render update lock enabled", cw->ec);
6539 cw->render_update_lock.lock++;
6545 e_comp_object_render_update_unlock(Evas_Object *obj)
6549 if (cw->render_update_lock.lock == 0)
6552 cw->render_update_lock.lock--;
6554 if (cw->render_update_lock.lock == 0)
6557 if (cw->render_update_lock.pending_move_set)
6559 evas_object_move(obj,
6560 cw->render_update_lock.pending_move_x,
6561 cw->render_update_lock.pending_move_y);
6562 cw->render_update_lock.pending_move_x = 0;
6563 cw->render_update_lock.pending_move_y = 0;
6564 cw->render_update_lock.pending_move_set = EINA_FALSE;
6567 if (cw->render_update_lock.pending_resize_set)
6569 evas_object_resize(obj,
6570 cw->render_update_lock.pending_resize_w,
6571 cw->render_update_lock.pending_resize_h);
6572 cw->render_update_lock.pending_resize_w = 0;
6573 cw->render_update_lock.pending_resize_h = 0;
6574 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6577 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6579 if ((cw->ec->exp_iconify.buffer_flush) &&
6580 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6581 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6582 e_comp_object_clear(obj);
6584 e_comp_object_render_update_add(obj);
6586 ELOGF("COMP", "Render update lock disabled", cw->ec);
6591 e_comp_object_render_update_lock_get(Evas_Object *obj)
6593 API_ENTRY EINA_FALSE;
6595 if (cw->render_update_lock.lock > 0)
6602 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6606 if (cw->transparent.set)
6608 if (r) *r = cw->transparent.user_r;
6609 if (g) *g = cw->transparent.user_g;
6610 if (b) *b = cw->transparent.user_b;
6611 if (a) *a = cw->transparent.user_a;
6615 evas_object_color_get(obj, r, g, b, a);