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_client_visibility_calculate();
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)
1290 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1291 if (!cw->effect_running)
1292 _e_comp_object_animating_begin(cw);
1293 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1294 return _e_comp_object_animating_end(cw);
1295 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1296 return _e_comp_object_animating_end(cw);
1298 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1302 zw = cw->ec->zone->w, zh = cw->ec->zone->h;
1307 zone = e_comp_object_util_zone_get(cw->smart_obj);
1308 if (!zone) zone = e_zone_current_get();
1315 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1316 cw->w, cw->h, zw, zh, x, y}, 8);
1317 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1318 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1321 /////////////////////////////////////////////
1323 /* create necessary objects for clients that e manages */
1325 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1327 if (cw->set_mouse_callbacks) return;
1328 if (!cw->smart_obj) return;
1330 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1331 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1332 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1337 cw->set_mouse_callbacks = EINA_TRUE;
1341 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1343 if (!cw->set_mouse_callbacks) return;
1344 if (!cw->smart_obj) return;
1346 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1347 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1348 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1353 cw->set_mouse_callbacks = EINA_FALSE;
1357 _e_comp_object_setup(E_Comp_Object *cw)
1359 cw->clip = evas_object_rectangle_add(e_comp->evas);
1360 evas_object_move(cw->clip, -9999, -9999);
1361 evas_object_resize(cw->clip, 999999, 999999);
1362 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1363 cw->effect_obj = edje_object_add(e_comp->evas);
1364 evas_object_move(cw->effect_obj, cw->x, cw->y);
1365 evas_object_clip_set(cw->effect_obj, cw->clip);
1366 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1367 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1368 cw->shobj = edje_object_add(e_comp->evas);
1369 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1370 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1371 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1373 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1374 if (cw->ec->override)
1376 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1377 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1378 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1380 else if (!cw->ec->input_only)
1382 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1383 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1384 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1386 cw->real_hid = !cw->ec->input_only;
1387 if (!cw->ec->input_only)
1389 e_util_size_debug_set(cw->effect_obj, 1);
1390 _e_comp_object_mouse_event_callback_set(cw);
1393 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1394 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1395 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1396 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1397 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1398 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1400 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1403 /////////////////////////////////////////////
1405 /* for fast path evas rendering; only called during render */
1407 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1409 E_Comp_Object *cw = data;
1410 E_Client *ec = cw->ec;
1412 int bx, by, bxx, byy;
1414 if (e_object_is_del(E_OBJECT(ec))) return;
1415 if (cw->external_content) return;
1416 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1417 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1420 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1421 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1423 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1425 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1426 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1430 bx = by = bxx = byy = 0;
1431 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1434 Edje_Message_Int_Set *msg;
1435 Edje_Message_Int msg2;
1436 Eina_Bool id = (bx || by || bxx || byy);
1438 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1444 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1446 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1450 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1451 e_comp_client_post_update_add(cw->ec);
1453 else if (e_comp_object_render(ec->frame))
1455 /* apply shape mask if necessary */
1456 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1457 e_comp_object_shape_apply(ec->frame);
1458 ec->shape_changed = 0;
1460 /* shaped clients get precise mouse events to handle transparent pixels */
1461 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1463 /* queue another render if client is still dirty; cannot refresh here. */
1464 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1465 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1467 if (cw->render_trace)
1469 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1475 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1477 E_Comp_Object *cw = data;
1478 E_Client *ec = cw->ec;
1480 if (e_object_is_del(E_OBJECT(ec))) return;
1481 if (cw->external_content) return;
1482 if (!e_comp->hwc) return;
1484 e_comp_client_render_list_add(cw->ec);
1486 if (!ec->hwc_window) return;
1488 e_hwc_windows_rendered_window_add(ec->hwc_window);
1491 /////////////////////////////////////////////
1494 _e_comp_object_client_pending_resize_add(E_Client *ec,
1497 unsigned int serial)
1499 E_Client_Pending_Resize *pnd;
1501 pnd = E_NEW(E_Client_Pending_Resize, 1);
1505 pnd->serial = serial;
1506 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1510 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1512 E_Comp_Object *cw = data;
1515 if (cw->render_update_lock.lock)
1517 cw->render_update_lock.pending_move_x = x;
1518 cw->render_update_lock.pending_move_y = y;
1519 cw->render_update_lock.pending_move_set = EINA_TRUE;
1523 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1524 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1525 (cw->external_content))
1527 /* delay to move until the external content is unset */
1528 cw->ec->changes.pos = 1;
1533 if (cw->ec->move_after_resize)
1535 if ((x != cw->ec->x) || (y != cw->ec->y))
1537 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1538 e_client_pos_set(cw->ec, x, y);
1539 cw->ec->changes.pos = 1;
1545 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1546 (cw->ec->manage_resize.resize_obj))
1548 e_client_pos_set(cw->ec, x, y);
1549 cw->ec->client.x = x + cw->client_inset.l;
1550 cw->ec->client.y = y + cw->client_inset.t;
1551 e_policy_visibility_client_defer_move(cw->ec);
1555 /* if frame_object does not exist, client_inset indicates CSD.
1556 * this means that ec->client matches cw->x/y, the opposite
1559 fx = (!cw->frame_object) * cw->client_inset.l;
1560 fy = (!cw->frame_object) * cw->client_inset.t;
1561 if ((cw->x == x + fx) && (cw->y == y + fy))
1563 if ((cw->ec->x != x) || (cw->ec->y != y))
1565 /* handle case where client tries to move to position and back very quickly */
1566 e_client_pos_set(cw->ec, x, y);
1567 cw->ec->client.x = x + cw->client_inset.l;
1568 cw->ec->client.y = y + cw->client_inset.t;
1572 if (!cw->ec->maximize_override)
1574 /* prevent moving in some directions while directionally maximized */
1575 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1577 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1580 ix = x + cw->client_inset.l;
1581 iy = y + cw->client_inset.t;
1582 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1583 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1584 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1586 /* prevent moving at all if move isn't allowed in current maximize state */
1587 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1588 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1589 if ((!cw->ec->shading) && (!cw->ec->shaded))
1591 cw->ec->changes.need_unmaximize = 1;
1592 cw->ec->saved.x = ix - cw->ec->zone->x;
1593 cw->ec->saved.y = iy - cw->ec->zone->y;
1594 cw->ec->saved.w = cw->ec->client.w;
1595 cw->ec->saved.h = cw->ec->client.h;
1601 /* only update during resize if triggered by resize */
1602 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1603 /* delay to move while surface waits paired commit serial*/
1604 if (e_client_pending_geometry_has(cw->ec))
1606 /* do nothing while waiting paired commit serial*/
1610 e_client_pos_set(cw->ec, x, y);
1611 if (cw->ec->new_client)
1613 /* don't actually do anything until first client idler loop */
1614 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1615 cw->ec->changes.pos = 1;
1620 /* only update xy position of client to avoid invalid
1621 * first damage region if it is not a new_client. */
1622 if (!cw->ec->shading)
1624 cw->ec->client.x = ix;
1625 cw->ec->client.y = iy;
1628 if (!cw->frame_object)
1630 evas_object_move(obj, x, y);
1635 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1637 E_Comp_Object *cw = data;
1638 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1640 if (cw->render_update_lock.lock)
1642 cw->render_update_lock.pending_resize_w = w;
1643 cw->render_update_lock.pending_resize_h = h;
1644 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1648 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1650 e_client_size_set(cw->ec, w, h);
1651 evas_object_resize(obj, w, h);
1655 /* if frame_object does not exist, client_inset indicates CSD.
1656 * this means that ec->client matches cw->w/h, the opposite
1659 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1660 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1661 if ((cw->w == w + fw) && (cw->h == h + fh))
1663 if (cw->ec->shading || cw->ec->shaded) return;
1664 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1665 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1666 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1668 /* handle case where client tries to resize itself and back very quickly */
1669 e_client_size_set(cw->ec, w, h);
1670 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1671 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1672 evas_object_smart_callback_call(obj, "client_resize", NULL);
1676 /* guarantee that fullscreen is fullscreen */
1677 if (cw->ec->fullscreen && ((w != cw->ec->zone->w) || (h != cw->ec->zone->h)))
1679 /* calculate client size */
1680 iw = w - cw->client_inset.l - cw->client_inset.r;
1681 ih = h - cw->client_inset.t - cw->client_inset.b;
1682 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1684 /* prevent resizing while maximized depending on direction and config */
1685 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1686 if ((!cw->ec->shading) && (!cw->ec->shaded))
1688 Eina_Bool reject = EINA_FALSE;
1689 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1691 if (cw->ec->client.h != ih)
1693 cw->ec->saved.h = ih;
1694 cw->ec->saved.y = cw->ec->client.y - cw->ec->zone->y;
1695 reject = cw->ec->changes.need_unmaximize = 1;
1698 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1700 if (cw->ec->client.w != iw)
1702 cw->ec->saved.w = iw;
1703 cw->ec->saved.x = cw->ec->client.x - cw->ec->zone->x;
1704 reject = cw->ec->changes.need_unmaximize = 1;
1714 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1716 /* do nothing until client idler loops */
1717 if ((cw->ec->w != w) || (cw->ec->h != h))
1719 e_client_size_set(cw->ec, w, h);
1720 cw->ec->changes.size = 1;
1725 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1726 ((cw->ec->w != w) || (cw->ec->h != h)))
1729 /* netwm sync resizes queue themselves and then trigger later on */
1730 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1732 if (e_client_pending_geometry_has(cw->ec))
1734 /* do nothing while waiting paired commit serial*/
1738 e_client_size_set(cw->ec, w, h);
1739 if ((!cw->ec->shading) && (!cw->ec->shaded))
1741 /* client geom never changes when shading since the client is never altered */
1742 cw->ec->client.w = iw;
1743 cw->ec->client.h = ih;
1744 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1747 /* The size of non-compositing window can be changed, so there is a
1748 * need to check that cw is H/W composited if cw is not redirected.
1749 * And of course we have to change size of evas object of H/W composited cw,
1750 * otherwise cw can't receive input events even if it is shown on the screen.
1752 Eina_Bool redirected = cw->redirected;
1754 redirected = e_comp_is_on_overlay(cw->ec);
1756 if ((!cw->ec->input_only) && (redirected) &&
1757 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1758 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1759 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1760 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1763 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1764 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1766 prev_w = cw->w, prev_h = cw->h;
1767 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1768 /* check shading and clamp to pixmap size for regular clients */
1769 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1770 (((w - fw != pw) || (h - fh != ph))))
1772 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1773 evas_object_smart_callback_call(obj, "client_resize", NULL);
1775 if (cw->frame_object || cw->ec->input_only)
1776 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1779 if ((cw->w == w) && (cw->h == h))
1781 /* going to be a noop resize which won't trigger smart resize */
1782 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1783 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1785 evas_object_resize(obj, w, h);
1789 evas_object_smart_callback_call(obj, "client_resize", NULL);
1792 if ((!cw->frame_object) && (!cw->ec->input_only))
1794 /* "just do it" for overrides */
1795 evas_object_resize(obj, w, h);
1797 if (!cw->ec->override)
1799 /* shape probably changed for non-overrides */
1800 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1801 cw->ec->need_shape_export |= cw->ec->shaped;
1802 if (cw->ec->shaped || cw->ec->shaped_input)
1806 /* this fixes positioning jiggles when using a resize mode
1807 * which also changes the client's position
1810 if (cw->frame_object)
1811 x = cw->x, y = cw->y;
1813 x = cw->ec->x, y = cw->ec->y;
1814 switch (cw->ec->resize_mode)
1816 case E_POINTER_RESIZE_BL:
1817 case E_POINTER_RESIZE_L:
1818 evas_object_move(obj, x + prev_w - cw->w, y);
1820 case E_POINTER_RESIZE_TL:
1821 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1823 case E_POINTER_RESIZE_T:
1824 case E_POINTER_RESIZE_TR:
1825 evas_object_move(obj, x, y + prev_h - cw->h);
1834 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1836 E_Comp_Object *cw = data;
1837 E_Comp_Wl_Client_Data *child_cdata;
1838 unsigned int l = e_comp_canvas_layer_map(layer);
1841 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1843 /* doing a compositor effect, follow directions */
1844 _e_comp_object_layer_set(obj, layer);
1845 if (layer == cw->ec->layer) //trying to put layer back
1849 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1850 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1851 if (cw->layer != l) goto layer_set;
1855 e_comp_render_queue();
1857 ec = e_client_above_get(cw->ec);
1858 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1859 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1860 ec = e_client_above_get(ec);
1861 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1863 ec = e_client_below_get(cw->ec);
1864 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1865 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1866 ec = e_client_below_get(ec);
1867 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1869 evas_object_stack_above(obj, ec->frame);
1874 if (ec && (cw->ec->parent == ec))
1876 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1877 evas_object_stack_above(obj, ec->frame);
1879 evas_object_stack_below(obj, ec->frame);
1882 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1888 if (cw->layer == l) return;
1889 if (e_comp_canvas_client_layer_map(layer) == 9999)
1890 return; //invalid layer for clients not doing comp effects
1891 if (cw->ec->fullscreen)
1893 cw->ec->saved.layer = layer;
1896 oldraise = e_config->transient.raise;
1898 /* clamp to valid client layer */
1899 layer = e_comp_canvas_client_layer_map_nearest(layer);
1900 cw->ec->layer = layer;
1901 if (e_config->transient.layer)
1904 Eina_List *list = eina_list_clone(cw->ec->transients);
1906 /* We need to set raise to one, else the child wont
1907 * follow to the new layer. It should be like this,
1908 * even if the user usually doesn't want to raise
1911 e_config->transient.raise = 1;
1912 EINA_LIST_FREE(list, child)
1914 child_cdata = e_client_cdata_get(child);
1915 if (child_cdata && !child_cdata->mapped)
1917 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1920 e_client_layer_set(child, layer);
1924 e_config->transient.raise = oldraise;
1926 _e_comp_object_layers_remove(cw);
1927 cw->layer = e_comp_canvas_layer_map(layer);
1928 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1929 //if (cw->ec->new_client)
1930 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1931 _e_comp_object_layer_set(obj, layer);
1932 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1933 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1934 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1936 /* can't stack a client above its own layer marker */
1937 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1939 if (!cw->visible) return;
1940 e_comp_render_queue();
1941 _e_comp_object_transform_obj_stack_update(obj);
1944 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1947 _e_comp_object_raise(Evas_Object *obj)
1949 evas_object_raise(obj);
1951 if (evas_object_smart_smart_get(obj))
1953 E_Client *ec = e_comp_object_client_get(obj);
1955 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1960 _e_comp_object_lower(Evas_Object *obj)
1962 evas_object_lower(obj);
1964 if (evas_object_smart_smart_get(obj))
1966 E_Client *ec = e_comp_object_client_get(obj);
1968 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1973 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1975 evas_object_stack_above(obj, target);
1977 if (evas_object_smart_smart_get(obj))
1979 E_Client *ec = e_comp_object_client_get(obj);
1981 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1986 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1988 evas_object_stack_below(obj, target);
1990 if (evas_object_smart_smart_get(obj))
1992 E_Client *ec = e_comp_object_client_get(obj);
1994 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1999 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2001 evas_object_layer_set(obj, layer);
2003 if (evas_object_smart_smart_get(obj))
2005 E_Client *ec = e_comp_object_client_get(obj);
2007 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2012 _e_comp_object_is_pending(E_Client *ec)
2016 if (!ec) return EINA_FALSE;
2018 topmost = e_comp_wl_topmost_parent_get(ec);
2020 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2024 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2026 E_Comp_Object *cw2 = NULL;
2029 Evas_Object *o = stack;
2030 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2032 /* We should consider topmost's layer_pending for subsurface */
2033 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2035 if (_e_comp_object_is_pending(cw->ec))
2036 e_comp_object_layer_update(cw->smart_obj,
2037 raising? stack : NULL,
2038 raising? NULL : stack);
2040 /* obey compositor effects! */
2041 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2042 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2043 stack_cb(cw->smart_obj, stack);
2044 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2045 evas_object_data_del(cw->smart_obj, "client_restack");
2049 cw2 = evas_object_data_get(o, "comp_obj");
2051 /* assume someone knew what they were doing during client init */
2052 if (cw->ec->new_client)
2053 layer = cw->ec->layer;
2054 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2055 layer = cw2->ec->layer;
2057 layer = evas_object_layer_get(stack);
2058 ecstack = e_client_below_get(cw->ec);
2059 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2061 /* some FOOL is trying to restack a layer marker */
2062 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2063 evas_object_layer_set(cw->smart_obj, layer);
2064 /* we got our layer wrangled, return now! */
2065 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2068 /* check if we're stacking below another client */
2071 /* check for non-client layer object */
2072 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2074 /* find an existing client to use for layering
2075 * by walking up the object stack
2077 * this is guaranteed to be pretty quick since we'll either:
2078 * - run out of client layers
2079 * - find a stacking client
2081 o = evas_object_above_get(o);
2082 if ((!o) || (o == cw->smart_obj)) break;
2083 if (evas_object_layer_get(o) != layer)
2085 /* reached the top client layer somehow
2086 * use top client object
2088 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2091 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2092 * return here since the top client layer window
2097 ec = e_client_top_get();
2102 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2105 if (cw2 && cw->layer != cw2->layer)
2108 /* remove existing layers */
2109 _e_comp_object_layers_remove(cw);
2112 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2113 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2114 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2115 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2116 else //if no stacking objects found, either raise or lower
2117 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2120 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2122 /* find new object for stacking if cw2 is on state of layer_pending */
2123 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2125 E_Client *new_stack = NULL, *current_ec = NULL;
2126 current_ec = cw2->ec;
2129 while ((new_stack = e_client_below_get(current_ec)))
2131 current_ec = new_stack;
2132 if (new_stack == cw->ec) continue;
2133 if (new_stack->layer != cw2->ec->layer) break;
2134 if (!_e_comp_object_is_pending(new_stack)) break;
2136 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2137 stack = new_stack->frame;
2140 /* stack it above layer object */
2142 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2143 stack = e_comp->layers[below_layer].obj;
2148 while ((new_stack = e_client_above_get(current_ec)))
2150 current_ec = new_stack;
2151 if (new_stack == cw->ec) continue;
2152 if (new_stack->layer != cw2->ec->layer) break;
2153 if (!_e_comp_object_is_pending(new_stack)) break;
2155 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2156 stack = new_stack->frame;
2158 stack = e_comp->layers[cw2->layer].obj;
2162 /* set restack if stacking has changed */
2163 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2164 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2165 stack_cb(cw->smart_obj, stack);
2166 if (e_comp->layers[cw->layer].obj)
2167 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2169 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2171 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2172 evas_object_data_del(cw->smart_obj, "client_restack");
2173 if (!cw->visible) return;
2174 e_comp_render_queue();
2178 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2180 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2182 if (evas_object_below_get(obj) == above)
2184 e_comp_object_layer_update(obj, above, NULL);
2188 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2189 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2190 _e_comp_object_transform_obj_stack_update(obj);
2191 _e_comp_object_transform_obj_stack_update(above);
2196 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2198 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2199 if (evas_object_above_get(obj) == below)
2201 e_comp_object_layer_update(obj, NULL, below);
2205 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2206 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2207 if (evas_object_smart_smart_get(obj))
2208 _e_comp_object_transform_obj_stack_update(obj);
2209 if (evas_object_smart_smart_get(below))
2210 _e_comp_object_transform_obj_stack_update(below);
2215 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2217 E_Comp_Object *cw = data;
2220 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2222 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2224 if (cw->ec->layer_pending)
2225 e_comp_object_layer_update(obj, NULL, obj);
2227 _e_comp_object_lower(obj);
2230 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2231 o = evas_object_below_get(obj);
2232 _e_comp_object_layers_remove(cw);
2233 /* prepend to client list since this client should be the first item now */
2234 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2235 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2236 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2237 evas_object_data_set(obj, "client_restack", (void*)1);
2238 _e_comp_object_lower(obj);
2239 evas_object_data_del(obj, "client_restack");
2240 if (!cw->visible) goto end;
2241 e_comp_render_queue();
2242 _e_comp_object_transform_obj_stack_update(obj);
2245 if (!cw->ec->post_lower)
2246 e_client_focus_stack_lower(cw->ec);
2251 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2253 E_Comp_Object *cw = data;
2256 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2258 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2260 if (cw->ec->layer_pending)
2262 int obj_layer = evas_object_layer_get(obj);
2263 if (cw->ec->layer != obj_layer)
2264 e_comp_object_layer_update(obj, NULL, NULL);
2267 _e_comp_object_raise(obj);
2270 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2271 o = evas_object_above_get(obj);
2273 E_Client *ecabove = e_client_above_get(cw->ec);
2274 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2275 (ecabove->frame == o)) goto end; //highest below marker
2277 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2278 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2279 _e_comp_object_raise(obj);
2284 /* still stack below override below the layer marker */
2285 for (op = o = e_comp->layers[cw->layer].obj;
2286 o && o != e_comp->layers[cw->layer - 1].obj;
2287 op = o, o = evas_object_below_get(o))
2289 if (evas_object_smart_smart_get(o))
2293 ec = e_comp_object_client_get(o);
2294 if (ec && (!ec->override)) break;
2297 _e_comp_object_stack_below(obj, op);
2298 e_client_focus_defer_set(cw->ec);
2300 if (!cw->visible) goto end;
2301 e_comp_render_queue();
2302 _e_comp_object_transform_obj_stack_update(obj);
2309 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2311 E_Comp_Object *cw = data;
2313 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2314 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2316 ELOGF("COMP", "Hide. intercepted", cw->ec);
2321 if (cw->ec->launching == EINA_TRUE)
2323 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2324 cw->ec->launching = EINA_FALSE;
2329 /* hidden flag = just do it */
2330 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2331 evas_object_hide(obj);
2335 if (cw->ec->input_only)
2337 /* input_only = who cares */
2338 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2339 evas_object_hide(obj);
2342 /* already hidden or currently animating */
2343 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2345 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2349 /* don't try hiding during shutdown */
2350 cw->defer_hide |= stopping;
2351 if (!cw->defer_hide)
2353 if ((!cw->ec->iconic) && (!cw->ec->override))
2354 /* unset delete requested so the client doesn't break */
2355 cw->ec->delete_requested = 0;
2356 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2358 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2359 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2362 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2365 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2367 _e_comp_object_animating_begin(cw);
2368 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2370 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2371 cw->defer_hide = !!cw->animating;
2373 e_comp_object_effect_set(obj, NULL);
2376 if (cw->animating) return;
2377 /* if we have no animations running, go ahead and hide */
2379 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2380 evas_object_hide(obj);
2384 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2386 E_Client *ec = cw->ec;
2389 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2391 if (ec->show_pending.count > 0)
2393 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2394 ec->show_pending.running = EINA_TRUE;
2398 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2399 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2401 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2406 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,
2407 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2408 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2411 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2414 if (ec->iconic && cw->animating)
2416 /* triggered during iconify animation */
2417 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2420 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2423 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2424 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2426 evas_object_move(cw->smart_obj, ec->x, ec->y);
2427 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2428 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2430 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2431 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2434 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2435 evas_object_show(cw->smart_obj);
2438 e_client_focus_defer_set(ec);
2442 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2446 pw = ec->client.w, ph = ec->client.h;
2448 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2450 ec->changes.visible = !ec->hidden;
2453 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2457 cw->updates = eina_tiler_new(pw, ph);
2460 ec->changes.visible = !ec->hidden;
2463 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2468 eina_tiler_tile_size_set(cw->updates, 1, 1);
2471 /* ignore until client idler first run */
2472 ec->changes.visible = !ec->hidden;
2475 ELOGF("COMP", "show_helper. return. new_client", ec);
2482 evas_object_move(cw->smart_obj, ec->x, ec->y);
2483 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2484 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2485 evas_object_show(cw->smart_obj);
2488 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2490 /* start_drag not received */
2491 ec->changes.visible = 1;
2494 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2497 /* re-set geometry */
2498 evas_object_move(cw->smart_obj, ec->x, ec->y);
2499 /* force resize in case it hasn't happened yet, or just to update size */
2500 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2501 if ((cw->w < 1) || (cw->h < 1))
2503 /* if resize didn't go through, try again */
2504 ec->visible = ec->changes.visible = 1;
2506 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2509 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2510 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2511 e_pixmap_clear(ec->pixmap);
2513 if (cw->real_hid && w && h)
2516 /* force comp theming in case it didn't happen already */
2517 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2518 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2519 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2522 /* only do the show if show is allowed */
2525 if (ec->internal) //internal clients render when they feel like it
2526 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2528 if (!e_client_is_iconified_by_client(ec)||
2529 e_policy_visibility_client_is_uniconic(ec))
2531 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2532 evas_object_show(cw->smart_obj);
2534 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2535 it is rendered in idle callback without native surface and
2536 compositor shows an empty frame if other objects aren't shown
2537 because job callback of e_comp called at the next loop.
2538 it causes a visual defect when windows are switched.
2542 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2543 e_comp_object_dirty(cw->smart_obj);
2544 e_comp_object_render(cw->smart_obj);
2548 e_policy_visibility_client_is_uniconic(ec))
2550 if (ec->exp_iconify.not_raise &&
2551 e_client_check_above_focused(ec))
2552 e_client_focus_stack_append_current_focused(ec);
2554 e_client_focus_defer_set(ec);
2561 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2563 E_Comp_Object *cw = data;
2564 E_Client *ec = cw->ec;
2566 E_Input_Rect_Data *input_rect_data;
2567 E_Input_Rect_Smart_Data *input_rect_sd;
2570 if (ec->ignored) return;
2574 //INF("SHOW2 %p", ec);
2575 _e_comp_intercept_show_helper(cw);
2578 //INF("SHOW %p", ec);
2581 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2582 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2583 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2584 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2588 if ((!cw->obj) && (cw->external_content))
2590 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2594 _e_comp_object_setup(cw);
2597 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2598 cw->obj = evas_object_image_filled_add(e_comp->evas);
2599 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2600 e_util_size_debug_set(cw->obj, 1);
2601 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2602 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2603 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2604 evas_object_name_set(cw->obj, "cw->obj");
2605 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2607 _e_comp_object_alpha_set(cw);
2610 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2613 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2614 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2617 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2620 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2622 if (input_rect_data->obj)
2624 evas_object_geometry_set(input_rect_data->obj,
2625 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2626 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2627 input_rect_data->rect.w, input_rect_data->rect.h);
2634 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2636 _e_comp_intercept_show_helper(cw);
2640 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2642 E_Comp_Object *cw = data;
2646 /* note: this is here as it seems there are enough apps that do not even
2647 * expect us to emulate a look of focus but not actually set x input
2648 * focus as we do - so simply abort any focus set on such windows */
2649 /* be strict about accepting focus hint */
2650 /* be strict about accepting focus hint */
2651 if ((!ec->icccm.accepts_focus) &&
2652 (!ec->icccm.take_focus))
2656 if (e_client_focused_get() == ec)
2657 e_client_focused_set(NULL);
2659 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2660 evas_object_focus_set(obj, focus);
2664 if (focus && ec->lock_focus_out) return;
2665 if (e_object_is_del(E_OBJECT(ec)) && focus)
2666 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2668 /* filter focus setting based on current state */
2673 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2674 evas_object_focus_set(obj, focus);
2677 if ((ec->iconic) && (!ec->deskshow))
2679 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2681 /* don't focus an iconified window. that's silly! */
2682 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2683 e_client_uniconify(ec);
2684 if (e_client_focus_track_enabled())
2685 e_client_focus_latest_set(ec);
2693 if ((!ec->sticky) && (ec->desk) && (!ec->desk->visible))
2695 if (ec->desk->animate_count) return;
2696 e_desk_show(ec->desk);
2697 if (!ec->desk->visible) return;
2705 /* not yet visible, wait till the next time... */
2706 ec->want_focus = !ec->hidden;
2711 e_client_focused_set(ec);
2715 if (e_client_focused_get() == ec)
2716 e_client_focused_set(NULL);
2720 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2722 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2724 evas_object_focus_set(obj, focus);
2728 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2730 E_Comp_Object *cw = data;
2732 if (cw->transparent.set)
2734 cw->transparent.user_r = r;
2735 cw->transparent.user_g = g;
2736 cw->transparent.user_b = b;
2737 cw->transparent.user_a = a;
2739 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2741 cw->transparent.user_r,
2742 cw->transparent.user_g,
2743 cw->transparent.user_b,
2744 cw->transparent.user_a);
2748 evas_object_color_set(obj, r, g, b, a);
2751 ////////////////////////////////////////////////////
2754 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2756 int w, h, ox, oy, ow, oh;
2758 Eina_Bool pass_event_flag = EINA_FALSE;
2759 E_Input_Rect_Data *input_rect_data;
2760 E_Input_Rect_Smart_Data *input_rect_sd;
2762 if (cw->frame_object)
2764 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2765 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2766 /* set a fixed size, force edje calc, check size difference */
2767 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2768 edje_object_message_signal_process(cw->frame_object);
2769 edje_object_calc_force(cw->frame_object);
2770 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2771 cw->client_inset.l = ox;
2772 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2773 cw->client_inset.t = oy;
2774 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2775 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2776 evas_object_resize(cw->frame_object, w, h);
2780 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2783 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2785 if (input_rect_data->obj)
2787 pass_event_flag = EINA_TRUE;
2793 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2794 evas_object_pass_events_set(cw->obj, pass_event_flag);
2798 cw->client_inset.l = 0;
2799 cw->client_inset.r = 0;
2800 cw->client_inset.t = 0;
2801 cw->client_inset.b = 0;
2803 cw->client_inset.calc = !!cw->frame_object;
2807 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2809 E_Comp_Object *cw = data;
2812 /* - get current size
2814 * - readjust for new frame size
2817 w = cw->ec->w, h = cw->ec->h;
2818 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2820 _e_comp_object_frame_recalc(cw);
2822 if (!cw->ec->fullscreen)
2823 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2825 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2826 if (cw->ec->shading || cw->ec->shaded) return;
2827 if (cw->ec->fullscreen)
2828 evas_object_resize(cw->ec->frame, cw->ec->zone->w, cw->ec->zone->h);
2829 else if (cw->ec->new_client)
2831 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2832 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2833 evas_object_resize(cw->ec->frame, w, h);
2835 else if ((w != cw->ec->w) || (h != cw->ec->h))
2836 evas_object_resize(cw->ec->frame, w, h);
2840 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2842 E_Comp_Object *cw = data;
2844 if (!cw->ec) return; //NYI
2845 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2847 cw->shade.x = cw->x;
2848 cw->shade.y = cw->y;
2849 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2853 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2855 E_Comp_Object *cw = data;
2857 if (!cw->ec) return; //NYI
2858 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2860 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2864 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2866 E_Comp_Object *cw = data;
2868 if (!cw->ec) return; //NYI
2869 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2871 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2875 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2877 E_Comp_Object *cw = data;
2879 if (!cw->ec) return; //NYI
2880 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2882 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2886 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2888 E_Comp_Object *cw = data;
2890 _e_comp_object_shadow_setup(cw);
2891 if (cw->frame_object)
2893 _e_comp_object_shadow(cw);
2894 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2895 _e_comp_object_frame_recalc(cw);
2896 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2901 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2903 E_Comp_Object *cw = data;
2905 if (_e_comp_object_shadow_setup(cw))
2906 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2907 if (cw->frame_object)
2909 _e_comp_object_shadow(cw);
2910 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2911 _e_comp_object_frame_recalc(cw);
2912 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2917 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2919 E_Comp_Object *cw = data;
2921 if (cw->frame_object)
2923 _e_comp_object_shadow(cw);
2924 e_comp_object_signal_emit(obj, "e,action,unmaximize", "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_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2933 E_Comp_Object *cw = data;
2935 if (_e_comp_object_shadow_setup(cw))
2938 cw->ec->changes.size = 1;
2940 if (cw->frame_object)
2942 _e_comp_object_shadow(cw);
2943 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2944 _e_comp_object_frame_recalc(cw);
2945 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2950 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2952 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2956 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2958 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2962 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2964 E_Comp_Object *cw = data;
2966 if (!cw->ec) return; //NYI
2967 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2971 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2973 E_Comp_Object *cw = data;
2975 if (!cw->ec) return; //NYI
2976 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2980 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2982 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2986 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2988 E_Comp_Object *cw = data;
2990 if (!e_object_is_del(E_OBJECT(cw->ec)))
2991 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2995 _e_comp_input_obj_smart_add(Evas_Object *obj)
2997 E_Input_Rect_Smart_Data *input_rect_sd;
2998 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3000 if (!input_rect_sd) return;
3001 evas_object_smart_data_set(obj, input_rect_sd);
3005 _e_comp_input_obj_smart_del(Evas_Object *obj)
3007 E_Input_Rect_Smart_Data *input_rect_sd;
3008 E_Input_Rect_Data *input_rect_data;
3010 input_rect_sd = evas_object_smart_data_get(obj);
3011 if (!input_rect_sd) return;
3013 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3015 if (input_rect_data->obj)
3017 evas_object_smart_member_del(input_rect_data->obj);
3018 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3020 E_FREE(input_rect_data);
3022 E_FREE(input_rect_sd);
3026 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3028 E_Input_Rect_Smart_Data *input_rect_sd;
3029 E_Input_Rect_Data *input_rect_data;
3033 input_rect_sd = evas_object_smart_data_get(obj);
3034 if (!input_rect_sd) return;
3036 cw = input_rect_sd->cw;
3037 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3039 if (input_rect_data->obj)
3041 evas_object_geometry_set(input_rect_data->obj,
3042 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3043 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3044 input_rect_data->rect.w, input_rect_data->rect.h);
3050 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3052 E_Input_Rect_Smart_Data *input_rect_sd;
3053 E_Input_Rect_Data *input_rect_data;
3057 input_rect_sd = evas_object_smart_data_get(obj);
3058 if (!input_rect_sd) return;
3060 cw = input_rect_sd->cw;
3061 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3063 if (input_rect_data->obj)
3065 evas_object_geometry_set(input_rect_data->obj,
3066 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3067 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3068 input_rect_data->rect.w, input_rect_data->rect.h);
3074 _e_comp_input_obj_smart_show(Evas_Object *obj)
3076 E_Input_Rect_Smart_Data *input_rect_sd;
3077 E_Input_Rect_Data *input_rect_data;
3080 input_rect_sd = evas_object_smart_data_get(obj);
3081 if (!input_rect_sd) return;
3083 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3085 if (input_rect_data->obj)
3087 evas_object_show(input_rect_data->obj);
3093 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3095 E_Input_Rect_Smart_Data *input_rect_sd;
3096 E_Input_Rect_Data *input_rect_data;
3099 input_rect_sd = evas_object_smart_data_get(obj);
3100 if (!input_rect_sd) return;
3102 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3104 if (input_rect_data->obj)
3106 evas_object_hide(input_rect_data->obj);
3112 _e_comp_input_obj_smart_init(void)
3114 if (_e_comp_input_obj_smart) return;
3116 static const Evas_Smart_Class sc =
3118 INPUT_OBJ_SMART_NAME,
3119 EVAS_SMART_CLASS_VERSION,
3120 _e_comp_input_obj_smart_add,
3121 _e_comp_input_obj_smart_del,
3122 _e_comp_input_obj_smart_move,
3123 _e_comp_input_obj_smart_resize,
3124 _e_comp_input_obj_smart_show,
3125 _e_comp_input_obj_smart_hide,
3138 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3144 _e_comp_smart_add(Evas_Object *obj)
3148 cw = E_NEW(E_Comp_Object, 1);
3149 EINA_SAFETY_ON_NULL_RETURN(cw);
3151 cw->smart_obj = obj;
3152 cw->x = cw->y = cw->w = cw->h = -1;
3153 evas_object_smart_data_set(obj, cw);
3154 cw->opacity = 255.0;
3155 cw->external_content = 0;
3156 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3157 cw->transform_bg_color.r = 0;
3158 cw->transform_bg_color.g = 0;
3159 cw->transform_bg_color.b = 0;
3160 cw->transform_bg_color.a = 255;
3161 evas_object_data_set(obj, "comp_obj", cw);
3162 evas_object_move(obj, -1, -1);
3163 /* intercept ALL the callbacks! */
3164 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3165 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3166 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3167 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3168 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3169 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3170 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3171 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3172 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3173 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3174 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3176 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3177 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3178 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3179 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3181 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3182 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3183 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3184 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3186 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3187 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3189 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3190 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3192 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3194 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3195 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3199 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3202 evas_object_color_set(cw->clip, r, g, b, a);
3203 evas_object_smart_callback_call(obj, "color_set", NULL);
3208 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3211 evas_object_clip_set(cw->clip, clip);
3215 _e_comp_smart_clip_unset(Evas_Object *obj)
3218 evas_object_clip_unset(cw->clip);
3222 _e_comp_smart_hide(Evas_Object *obj)
3224 TRACE_DS_BEGIN(COMP:SMART HIDE);
3229 evas_object_hide(cw->clip);
3230 if (cw->input_obj) evas_object_hide(cw->input_obj);
3231 evas_object_hide(cw->effect_obj);
3232 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3233 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3234 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3241 /* unset native surface if current displaying buffer was destroied */
3242 if (!cw->buffer_destroy_listener.notify)
3244 Evas_Native_Surface *ns;
3245 ns = evas_object_image_native_surface_get(cw->obj);
3246 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3247 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3250 if (!cw->ec->input_only)
3252 edje_object_freeze(cw->effect_obj);
3253 edje_object_freeze(cw->shobj);
3254 edje_object_play_set(cw->shobj, 0);
3255 if (cw->frame_object)
3256 edje_object_play_set(cw->frame_object, 0);
3258 /* ensure focus-out */
3259 if (cw->ec->focused &&
3260 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3262 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3263 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3264 e_client_focus_defer_unset(cw->ec);
3266 e_comp_render_queue(); //force nocomp recheck
3272 _e_comp_smart_show(Evas_Object *obj)
3280 if ((cw->w < 0) || (cw->h < 0))
3281 CRI("ACK! ec:%p", cw->ec);
3283 TRACE_DS_BEGIN(COMP:SMART SHOW);
3285 e_comp_object_map_update(obj);
3287 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3288 evas_object_show(tmp->frame);
3290 evas_object_show(cw->clip);
3291 if (cw->input_obj) evas_object_show(cw->input_obj);
3292 if (!cw->ec->input_only)
3294 edje_object_thaw(cw->effect_obj);
3295 edje_object_thaw(cw->shobj);
3296 edje_object_play_set(cw->shobj, 1);
3297 if (cw->frame_object)
3298 edje_object_play_set(cw->frame_object, 1);
3300 evas_object_show(cw->effect_obj);
3301 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3302 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3303 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3304 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3305 e_comp_render_queue();
3306 if (cw->ec->input_only)
3311 if (cw->ec->iconic && (!cw->ec->new_client))
3313 if (e_client_is_iconified_by_client(cw->ec))
3315 ELOGF("COMP", "Set launching flag..", cw->ec);
3316 cw->ec->launching = EINA_TRUE;
3319 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3321 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3324 ELOGF("COMP", "Set launching flag..", cw->ec);
3325 cw->ec->launching = EINA_TRUE;
3327 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3328 _e_comp_object_animating_begin(cw);
3329 if (!_e_comp_object_effect_visibility_start(cw, 1))
3335 /* ensure some random effect doesn't lock the client offscreen */
3339 e_comp_object_effect_set(obj, NULL);
3342 _e_comp_object_dim_update(cw);
3348 _e_comp_smart_del(Evas_Object *obj)
3354 if (cw->buffer_destroy_listener.notify)
3356 wl_list_remove(&cw->buffer_destroy_listener.link);
3357 cw->buffer_destroy_listener.notify = NULL;
3360 if (cw->tbm_surface)
3362 tbm_surface_internal_unref(cw->tbm_surface);
3363 cw->tbm_surface = NULL;
3366 if (cw->render_update_lock.buffer_ref.buffer)
3368 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3369 cw->ec, cw->render_update_lock.lock);
3370 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3373 e_comp_object_render_update_del(cw->smart_obj);
3374 E_FREE_FUNC(cw->updates, eina_tiler_free);
3375 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3382 EINA_LIST_FREE(cw->obj_mirror, o)
3384 evas_object_image_data_set(o, NULL);
3385 evas_object_freeze_events_set(o, 1);
3386 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3390 _e_comp_object_layers_remove(cw);
3391 l = evas_object_data_get(obj, "comp_object-to_del");
3392 E_FREE_LIST(l, evas_object_del);
3393 _e_comp_object_mouse_event_callback_unset(cw);
3394 evas_object_del(cw->clip);
3395 evas_object_del(cw->effect_obj);
3396 evas_object_del(cw->shobj);
3397 evas_object_del(cw->frame_object);
3398 evas_object_del(cw->input_obj);
3399 evas_object_del(cw->obj);
3400 evas_object_del(cw->mask.obj);
3401 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3402 evas_object_del(cw->transform_bg_obj);
3403 evas_object_del(cw->transform_tranp_obj);
3404 evas_object_del(cw->default_input_obj);
3405 eina_stringshare_del(cw->frame_theme);
3406 eina_stringshare_del(cw->frame_name);
3410 e_comp->animating--;
3412 e_object_unref(E_OBJECT(cw->ec));
3414 cw->ec->frame = NULL;
3419 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3423 cw->x = x, cw->y = y;
3424 evas_object_move(cw->effect_obj, x, y);
3425 evas_object_move(cw->default_input_obj, x, y);
3426 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3428 e_comp_object_map_update(obj);
3432 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3434 Eina_Bool first = EINA_FALSE;
3439 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3441 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3443 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3445 if (cw->w != w || cw->h != h)
3446 e_comp_object_map_update(obj);
3448 first = ((cw->w < 1) || (cw->h < 1));
3449 cw->w = w, cw->h = h;
3450 if ((!cw->ec->shading) && (!cw->ec->shaded))
3454 if (cw->frame_object)
3455 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3458 /* verify pixmap:object size */
3459 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3461 if ((ww != pw) || (hh != ph))
3462 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3464 evas_object_resize(cw->effect_obj, tw, th);
3465 evas_object_resize(cw->default_input_obj, w, h);
3467 evas_object_resize(cw->input_obj, w, h);
3469 evas_object_resize(cw->mask.obj, w, h);
3470 /* resize render update tiler */
3473 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3474 cw->updates_full = 0;
3475 if (cw->updates) eina_tiler_clear(cw->updates);
3479 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3480 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3485 evas_object_resize(cw->effect_obj, tw, th);
3486 evas_object_resize(cw->default_input_obj, w, h);
3493 e_comp_render_queue();
3499 _e_comp_smart_init(void)
3501 if (_e_comp_smart) return;
3503 static const Evas_Smart_Class sc =
3506 EVAS_SMART_CLASS_VERSION,
3510 _e_comp_smart_resize,
3513 _e_comp_smart_color_set,
3514 _e_comp_smart_clip_set,
3515 _e_comp_smart_clip_unset,
3525 _e_comp_smart = evas_smart_class_new(&sc);
3530 e_comp_object_init(void)
3532 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3533 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3534 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3535 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3539 e_comp_object_shutdown(void)
3545 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3547 API_ENTRY EINA_FALSE;
3548 return !!cw->force_visible;
3550 /////////////////////////////////////////////////////////
3553 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3556 Eina_Bool comp_object;
3558 comp_object = !!evas_object_data_get(obj, "comp_object");
3563 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3565 e_comp_render_queue();
3567 l = evas_object_data_get(obj, "comp_object-to_del");
3568 E_FREE_LIST(l, evas_object_del);
3572 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3574 if (e_comp_util_object_is_above_nocomp(obj) &&
3575 (!evas_object_data_get(obj, "comp_override")))
3577 evas_object_data_set(obj, "comp_override", (void*)1);
3578 e_comp_override_add();
3583 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3585 Eina_Bool ref = EINA_TRUE;
3586 if (evas_object_visible_get(obj))
3590 d = evas_object_data_del(obj, "comp_hiding");
3592 /* currently trying to hide */
3595 /* already visible */
3599 evas_object_show(obj);
3602 evas_object_ref(obj);
3603 evas_object_data_set(obj, "comp_ref", (void*)1);
3605 edje_object_signal_emit(obj, "e,state,visible", "e");
3606 evas_object_data_set(obj, "comp_showing", (void*)1);
3607 if (e_comp_util_object_is_above_nocomp(obj))
3609 evas_object_data_set(obj, "comp_override", (void*)1);
3610 e_comp_override_add();
3615 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3617 if (!evas_object_visible_get(obj)) return;
3618 /* already hiding */
3619 if (evas_object_data_get(obj, "comp_hiding")) return;
3620 if (!evas_object_data_del(obj, "comp_showing"))
3622 evas_object_ref(obj);
3623 evas_object_data_set(obj, "comp_ref", (void*)1);
3625 edje_object_signal_emit(obj, "e,state,hidden", "e");
3626 evas_object_data_set(obj, "comp_hiding", (void*)1);
3628 if (evas_object_data_del(obj, "comp_override"))
3629 e_comp_override_timed_pop();
3633 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3635 if (!e_util_strcmp(emission, "e,action,hide,done"))
3637 if (!evas_object_data_del(obj, "comp_hiding")) return;
3638 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3639 evas_object_hide(obj);
3640 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3643 evas_object_data_del(obj, "comp_showing");
3644 if (evas_object_data_del(obj, "comp_ref"))
3645 evas_object_unref(obj);
3649 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3655 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3659 E_API E_Comp_Object_Hook *
3660 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3662 E_Comp_Object_Hook *ch;
3664 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3665 ch = E_NEW(E_Comp_Object_Hook, 1);
3666 if (!ch) return NULL;
3667 ch->hookpoint = hookpoint;
3669 ch->data = (void*)data;
3670 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3675 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3678 if (_e_comp_object_hooks_walking == 0)
3680 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3684 _e_comp_object_hooks_delete++;
3687 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3688 E_API E_Comp_Object_Intercept_Hook *
3689 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3691 E_Comp_Object_Intercept_Hook *ch;
3693 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3694 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3695 if (!ch) return NULL;
3696 ch->hookpoint = hookpoint;
3698 ch->data = (void*)data;
3699 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3704 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3707 if (_e_comp_object_intercept_hooks_walking == 0)
3709 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3713 _e_comp_object_intercept_hooks_delete++;
3718 e_comp_object_util_add(Evas_Object *obj)
3720 Evas_Object *o, *z = NULL;
3722 E_Comp_Config *conf = e_comp_config_get();
3723 Eina_Bool skip = EINA_FALSE;
3729 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3731 name = evas_object_name_get(obj);
3732 vis = evas_object_visible_get(obj);
3733 o = edje_object_add(e_comp->evas);
3734 evas_object_data_set(o, "comp_object", (void*)1);
3736 skip = (!strncmp(name, "noshadow", 8));
3738 evas_object_data_set(o, "comp_object_skip", (void*)1);
3740 if (conf->shadow_style)
3742 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3743 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3746 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3747 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3748 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3750 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3752 evas_object_geometry_get(obj, &x, &y, &w, &h);
3753 evas_object_geometry_set(o, x, y, w, h);
3754 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3756 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3758 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3759 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3760 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3761 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3762 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3763 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3765 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3767 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3769 _e_comp_object_event_add(o);
3772 evas_object_show(o);
3777 /* utility functions for deleting objects when their "owner" is deleted */
3779 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3784 EINA_SAFETY_ON_NULL_RETURN(to_del);
3785 l = evas_object_data_get(obj, "comp_object-to_del");
3786 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3787 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3788 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3792 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3797 EINA_SAFETY_ON_NULL_RETURN(to_del);
3798 l = evas_object_data_get(obj, "comp_object-to_del");
3800 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3803 /////////////////////////////////////////////////////////
3805 EINTERN Evas_Object *
3806 e_comp_object_client_add(E_Client *ec)
3811 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3812 if (ec->frame) return NULL;
3813 _e_comp_smart_init();
3814 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3815 cw = evas_object_smart_data_get(o);
3816 if (!cw) return NULL;
3817 evas_object_data_set(o, "E_Client", ec);
3820 evas_object_data_set(o, "comp_object", (void*)1);
3822 _e_comp_object_event_add(o);
3827 /* utility functions for getting client inset */
3829 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3832 if (!cw->client_inset.calc)
3838 if (ax) *ax = x - cw->client_inset.l;
3839 if (ay) *ay = y - cw->client_inset.t;
3843 e_comp_object_frame_xy_unadjust(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_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3860 if (!cw->client_inset.calc)
3866 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3867 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3871 e_comp_object_frame_wh_unadjust(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_client_get(Evas_Object *obj)
3890 /* FIXME: remove this when eo is used */
3891 o = evas_object_data_get(obj, "comp_smart_obj");
3893 return e_comp_object_client_get(o);
3894 return cw ? cw->ec : NULL;
3898 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3901 if (cw->frame_extends)
3902 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3907 if (w) *w = cw->ec->w;
3908 if (h) *h = cw->ec->h;
3913 e_comp_object_util_zone_get(Evas_Object *obj)
3915 E_Zone *zone = NULL;
3919 zone = cw->ec->zone;
3924 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3925 zone = e_comp_zone_xy_get(x, y);
3931 e_comp_object_util_center(Evas_Object *obj)
3933 int x, y, w, h, ow, oh;
3938 zone = e_comp_object_util_zone_get(obj);
3939 EINA_SAFETY_ON_NULL_RETURN(zone);
3940 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3941 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3942 ow = cw->ec->w, oh = cw->ec->h;
3944 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3945 x = x + (w - ow) / 2;
3946 y = y + (h - oh) / 2;
3947 evas_object_move(obj, x, y);
3951 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3953 int x, y, w, h, ow, oh;
3956 EINA_SAFETY_ON_NULL_RETURN(on);
3957 evas_object_geometry_get(on, &x, &y, &w, &h);
3958 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3959 ow = cw->ec->w, oh = cw->ec->h;
3961 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3962 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3966 e_comp_object_util_fullscreen(Evas_Object *obj)
3971 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3974 evas_object_move(obj, 0, 0);
3975 evas_object_resize(obj, e_comp->w, e_comp->h);
3980 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3988 ow = cw->w, oh = cw->h;
3990 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3991 zone = e_comp_object_util_zone_get(obj);
3992 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3993 if (x) *x = zx + (zw - ow) / 2;
3994 if (y) *y = zy + (zh - oh) / 2;
3998 e_comp_object_input_objs_del(Evas_Object *obj)
4001 E_Input_Rect_Data *input_rect_data;
4002 E_Input_Rect_Smart_Data *input_rect_sd;
4007 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4008 if (!input_rect_sd) return;
4010 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4012 if (input_rect_data->obj)
4014 evas_object_smart_member_del(input_rect_data->obj);
4015 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4017 E_FREE(input_rect_data);
4022 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4025 E_Input_Rect_Data *input_rect_data = NULL;
4026 E_Input_Rect_Smart_Data *input_rect_sd;
4027 int client_w, client_h;
4029 if (cw->ec->client.w)
4030 client_w = cw->ec->client.w;
4032 client_w = cw->ec->w;
4034 if (cw->ec->client.h)
4035 client_h = cw->ec->client.h;
4037 client_h = cw->ec->h;
4039 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4043 _e_comp_input_obj_smart_init();
4044 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4045 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4046 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4049 input_rect_sd->cw = cw;
4052 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4055 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4056 if (input_rect_data)
4058 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4059 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4063 if ((input_rect_data) &&
4064 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4066 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4067 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4068 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4069 evas_object_clip_set(input_rect_data->obj, cw->clip);
4070 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4071 evas_object_geometry_set(input_rect_data->obj,
4072 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4073 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4074 evas_object_pass_events_set(cw->default_input_obj, 1);
4075 evas_object_pass_events_set(cw->obj, 1);
4078 evas_object_show(input_rect_data->obj);
4079 evas_object_show(cw->input_obj);
4084 evas_object_smart_member_del(cw->input_obj);
4085 E_FREE_FUNC(cw->input_obj, evas_object_del);
4086 evas_object_pass_events_set(cw->default_input_obj, 0);
4087 evas_object_pass_events_set(cw->obj, 0);
4092 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4095 E_Input_Rect_Smart_Data *input_rect_sd;
4096 E_Input_Rect_Data *input_rect_data;
4099 if (!cw->input_obj) return;
4101 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4104 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4106 *list = eina_list_append(*list, &input_rect_data->rect);
4112 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4115 if (l) *l = cw->client_inset.l;
4116 if (r) *r = cw->client_inset.r;
4117 if (t) *t = cw->client_inset.t;
4118 if (b) *b = cw->client_inset.b;
4121 /* set geometry for CSD */
4123 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4129 if (cw->frame_object)
4130 CRI("ACK! ec:%p", cw->ec);
4131 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4132 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4133 calc = cw->client_inset.calc;
4134 cw->client_inset.calc = l || r || t || b;
4135 eina_stringshare_replace(&cw->frame_theme, "borderless");
4136 if (cw->client_inset.calc)
4138 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4139 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4140 e_client_size_set(cw->ec, tw, th);
4142 else if (cw->ec->maximized || cw->ec->fullscreen)
4144 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4145 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4147 if (!cw->ec->new_client)
4149 if (calc && cw->client_inset.calc)
4151 tx = cw->ec->x - (l - cw->client_inset.l);
4152 ty = cw->ec->y - (t - cw->client_inset.t);
4153 e_client_pos_set(cw->ec, tx, ty);
4155 cw->ec->changes.pos = cw->ec->changes.size = 1;
4158 cw->client_inset.l = l;
4159 cw->client_inset.r = r;
4160 cw->client_inset.t = t;
4161 cw->client_inset.b = b;
4165 e_comp_object_frame_allowed(Evas_Object *obj)
4167 API_ENTRY EINA_FALSE;
4168 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4172 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4174 API_ENTRY EINA_FALSE;
4175 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4176 eina_stringshare_replace(&cw->frame_name, name);
4177 if (cw->frame_object)
4178 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4183 e_comp_object_frame_exists(Evas_Object *obj)
4185 API_ENTRY EINA_FALSE;
4186 return !!cw->frame_object;
4190 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4192 Evas_Object *o, *pbg;
4195 Eina_Stringshare *theme;
4197 API_ENTRY EINA_FALSE;
4199 if (!e_util_strcmp(cw->frame_theme, name))
4200 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4201 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4202 return _e_comp_object_shadow_setup(cw);
4203 pbg = cw->frame_object;
4204 theme = eina_stringshare_add(name);
4206 if (cw->frame_object)
4210 w = cw->ec->w, h = cw->ec->h;
4211 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4212 if ((cw->ec->w != w) || (cw->ec->h != h))
4214 cw->ec->changes.size = 1;
4217 E_FREE_FUNC(cw->frame_object, evas_object_del);
4218 if (!name) goto reshadow;
4220 o = edje_object_add(e_comp->evas);
4221 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4222 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4223 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4225 cw->frame_object = NULL;
4227 eina_stringshare_del(cw->frame_theme);
4228 cw->frame_theme = theme;
4233 if (theme != e_config->theme_default_border_style)
4235 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4236 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4240 ok = e_theme_edje_object_set(o, "base/theme/border",
4241 "e/widgets/border/default/border");
4242 if (ok && (theme == e_config->theme_default_border_style))
4244 /* Reset default border style to default */
4245 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4246 e_config_save_queue();
4253 cw->frame_object = o;
4254 eina_stringshare_del(cw->frame_theme);
4255 cw->frame_theme = theme;
4256 evas_object_name_set(o, "cw->frame_object");
4259 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4263 cw->ec->changes.icon = 1;
4269 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4274 _e_comp_object_shadow_setup(cw);
4277 int old_x, old_y, new_x = 0, new_y = 0;
4279 old_x = cw->x, old_y = cw->y;
4281 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4283 new_x = cw->ec->x, new_y = cw->ec->y;
4284 else if (cw->ec->placed || (!cw->ec->new_client))
4286 /* if no previous frame:
4287 * - reapply client_inset
4292 if (cw->ec->changes.size)
4299 x = cw->ec->client.x, y = cw->ec->client.y;
4300 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4301 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4303 new_x = x, new_y = y;
4306 if (old_x != new_x || old_y != new_y)
4308 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4309 cw->y = cw->x = -99999;
4310 evas_object_move(obj, new_x, new_y);
4314 if (cw->ec->maximized)
4316 cw->ec->changes.need_maximize = 1;
4319 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4320 if (cw->frame_object)
4322 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4325 cw->frame_extends = 0;
4326 evas_object_del(pbg);
4331 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4333 E_Comp_Object_Mover *prov;
4336 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4337 edje_object_signal_emit(cw->shobj, sig, src);
4338 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4339 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4340 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4342 /* start with highest priority callback first */
4343 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4345 if (!e_util_glob_match(sig, prov->sig)) continue;
4346 if (prov->func(prov->data, obj, sig)) break;
4351 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4353 /* FIXME: at some point I guess this should use eo to inherit
4354 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4355 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4358 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4362 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4365 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4369 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4372 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4376 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4379 Eina_Rectangle rect;
4382 if (cw->ec->input_only || (!cw->updates)) return;
4383 if (cw->nocomp) return;
4384 rect.x = x, rect.y = y;
4385 rect.w = w, rect.h = h;
4386 evas_object_smart_callback_call(obj, "damage", &rect);
4388 if (e_comp_is_on_overlay(cw->ec))
4390 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4391 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4392 * E module attempts to block screen update due to the particular policy.
4394 if (e_pixmap_resource_get(cw->ec->pixmap))
4395 cw->hwc_need_update = EINA_TRUE;
4398 /* ignore overdraw */
4399 if (cw->updates_full)
4401 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4402 e_comp_object_render_update_add(obj);
4404 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4405 evas_object_show(cw->smart_obj);
4409 /* clip rect to client surface */
4410 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4411 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4412 /* if rect is the total size of the client after clip, clear the updates
4413 * since this is guaranteed to be the whole region anyway
4415 eina_tiler_area_size_get(cw->updates, &tw, &th);
4416 if ((w > tw) || (h > th))
4418 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4419 eina_tiler_clear(cw->updates);
4420 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4422 tw = cw->ec->client.w, th = cw->ec->client.h;
4424 if ((!x) && (!y) && (w == tw) && (h == th))
4426 eina_tiler_clear(cw->updates);
4427 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4428 cw->updates_full = 1;
4429 cw->update_count = 0;
4432 if (cw->update_count > UPDATE_MAX)
4434 /* this is going to get really dumb, so just update the whole thing */
4435 eina_tiler_clear(cw->updates);
4436 cw->update_count = cw->updates_full = 1;
4437 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4438 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4442 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4443 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4445 cw->updates_exist = 1;
4446 e_comp_object_render_update_add(obj);
4448 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4449 evas_object_show(cw->smart_obj);
4453 e_comp_object_damage_exists(Evas_Object *obj)
4455 API_ENTRY EINA_FALSE;
4456 return cw->updates_exist;
4460 e_comp_object_render_update_add(Evas_Object *obj)
4464 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4465 if (cw->render_update_lock.lock) return;
4466 if (e_object_is_del(E_OBJECT(cw->ec)))
4467 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4468 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4472 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4474 e_comp_render_queue();
4478 e_comp_object_render_update_del(Evas_Object *obj)
4482 if (cw->ec->input_only || (!cw->updates)) return;
4483 if (!cw->update) return;
4485 /* this gets called during comp animating to clear the update flag */
4486 if (e_comp->grabbed) return;
4487 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4488 if (!e_comp->updates)
4490 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4491 if (e_comp->render_animator)
4492 ecore_animator_freeze(e_comp->render_animator);
4497 e_comp_object_shape_apply(Evas_Object *obj)
4501 unsigned int i, *pix, *p;
4505 if (!cw->ec) return; //NYI
4506 if (cw->external_content) return;
4509 if ((cw->ec->shape_rects_num >= 1) &&
4510 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4515 ERR("BUGGER: shape with native surface? cw=%p", cw);
4518 evas_object_image_size_get(cw->obj, &w, &h);
4519 if ((w < 1) || (h < 1)) return;
4522 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4523 _e_comp_object_alpha_set(cw);
4524 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4525 evas_object_image_alpha_set(o, 1);
4527 p = pix = evas_object_image_data_get(cw->obj, 1);
4530 evas_object_image_data_set(cw->obj, pix);
4535 unsigned char *spix, *sp;
4537 spix = calloc(w * h, sizeof(unsigned char));
4539 for (i = 0; i < cw->ec->shape_rects_num; i++)
4543 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4544 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4545 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4546 sp = spix + (w * ry) + rx;
4547 for (py = 0; py < rh; py++)
4549 for (px = 0; px < rw; px++)
4557 for (py = 0; py < h; py++)
4559 for (px = 0; px < w; px++)
4561 unsigned int mask, imask;
4563 mask = ((unsigned int)(*sp)) << 24;
4565 imask |= imask >> 8;
4566 imask |= imask >> 8;
4567 *p = mask | (*p & imask);
4568 //if (*sp) *p = 0xff000000 | *p;
4569 //else *p = 0x00000000;
4578 for (py = 0; py < h; py++)
4580 for (px = 0; px < w; px++)
4584 evas_object_image_data_set(cw->obj, pix);
4585 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4586 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4588 evas_object_image_data_set(o, pix);
4589 evas_object_image_data_update_add(o, 0, 0, w, h);
4591 // don't need to fix alpha chanel as blending
4592 // should be totally off here regardless of
4593 // alpha channel content
4597 _e_comp_object_clear(E_Comp_Object *cw)
4602 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4604 if (cw->render_update_lock.lock) return;
4607 e_pixmap_clear(cw->ec->pixmap);
4609 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4610 evas_object_image_size_set(cw->obj, 1, 1);
4611 evas_object_image_data_set(cw->obj, NULL);
4612 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4614 evas_object_image_size_set(o, 1, 1);
4615 evas_object_image_data_set(o, NULL);
4618 e_comp_object_render_update_del(cw->smart_obj);
4622 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4626 API_ENTRY EINA_FALSE;
4628 if (cw->transparent.set == set)
4633 evas_object_color_get(obj, &r, &g, &b, &a);
4634 evas_object_color_set(obj, 0, 0, 0, 0);
4636 cw->transparent.user_r = r;
4637 cw->transparent.user_g = g;
4638 cw->transparent.user_b = b;
4639 cw->transparent.user_a = a;
4641 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4643 cw->transparent.user_r,
4644 cw->transparent.user_g,
4645 cw->transparent.user_b,
4646 cw->transparent.user_a);
4648 cw->transparent.set = EINA_TRUE;
4652 cw->transparent.set = EINA_FALSE;
4654 evas_object_color_set(obj,
4655 cw->transparent.user_r,
4656 cw->transparent.user_g,
4657 cw->transparent.user_b,
4658 cw->transparent.user_a);
4660 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4662 cw->transparent.user_r,
4663 cw->transparent.user_g,
4664 cw->transparent.user_b,
4665 cw->transparent.user_a);
4671 /* helper function to simplify toggling of redirection for display servers which support it */
4673 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4678 if (cw->redirected == set) return;
4679 cw->redirected = set;
4680 if (cw->external_content) return;
4682 e_comp_object_map_update(obj);
4686 if (cw->updates_exist)
4687 e_comp_object_render_update_add(obj);
4689 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4691 _e_comp_object_transparent_set(obj, EINA_FALSE);
4692 evas_object_smart_callback_call(obj, "redirected", NULL);
4696 _e_comp_object_clear(cw);
4697 _e_comp_object_transparent_set(obj, EINA_TRUE);
4698 evas_object_smart_callback_call(obj, "unredirected", NULL);
4703 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4706 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4708 if (cw->buffer_destroy_listener.notify)
4710 cw->buffer_destroy_listener.notify = NULL;
4711 wl_list_remove(&cw->buffer_destroy_listener.link);
4714 if (e_object_is_del(E_OBJECT(cw->ec)))
4716 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4721 /* if it's current displaying buffer, do not remove its content */
4722 if (!evas_object_visible_get(cw->ec->frame))
4723 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4728 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4733 if (cw->buffer_destroy_listener.notify)
4735 wl_list_remove(&cw->buffer_destroy_listener.link);
4736 cw->buffer_destroy_listener.notify = NULL;
4739 if (cw->tbm_surface)
4741 tbm_surface_internal_unref(cw->tbm_surface);
4742 cw->tbm_surface = NULL;
4747 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4749 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4750 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4752 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4754 tbm_surface_internal_ref(ns->data.tbm.buffer);
4755 cw->tbm_surface = ns->data.tbm.buffer;
4759 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4760 evas_object_image_native_surface_set(cw->obj, ns);
4764 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4766 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4767 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4768 evas_object_image_native_surface_set(o, ns);
4775 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4777 Evas_Native_Surface ns;
4780 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4781 if (cw->ec->input_only) return;
4782 if (cw->external_content) return;
4783 if (cw->render_update_lock.lock) return;
4786 memset(&ns, 0, sizeof(Evas_Native_Surface));
4790 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4791 set = (!cw->ec->shaped);
4793 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4797 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4801 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4804 if (cw->ec->input_only) return;
4807 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4808 _e_comp_object_alpha_set(cw);
4810 e_comp_object_native_surface_set(obj, cw->native);
4811 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4815 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4821 if (cw->blanked == set) return;
4823 _e_comp_object_alpha_set(cw);
4826 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4827 evas_object_image_data_set(cw->obj, NULL);
4831 e_comp_object_native_surface_set(obj, 1);
4832 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4836 _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)
4841 if (!_damage_trace) return;
4845 if (!evas_object_visible_get(cw->obj)) return;
4847 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4849 o = evas_object_rectangle_add(e_comp->evas);
4850 evas_object_layer_set(o, E_LAYER_MAX);
4851 evas_object_name_set(o, "damage_trace");
4852 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4853 evas_object_resize(o, dmg_w, dmg_h);
4854 evas_object_color_set(o, 0, 128, 0, 128);
4855 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4856 evas_object_pass_events_set(o, EINA_TRUE);
4857 evas_object_show(o);
4859 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4861 dmg_w, dmg_h, dmg_x, dmg_y,
4862 origin->w, origin->h, origin->x, origin->y);
4864 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4867 /* mark an object as dirty and setup damages */
4869 e_comp_object_dirty(Evas_Object *obj)
4872 Eina_Rectangle *rect;
4876 Eina_Bool dirty, visible;
4880 if (cw->external_content) return;
4881 if (!cw->redirected) return;
4882 if (cw->render_update_lock.lock)
4884 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4887 /* only actually dirty if pixmap is available */
4888 if (!e_pixmap_resource_get(cw->ec->pixmap))
4890 // e_pixmap_size_get returns last attached buffer size
4891 // eventhough it is destroyed
4892 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4895 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4896 visible = cw->visible;
4897 if (!dirty) w = h = 1;
4898 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4900 evas_object_image_data_set(cw->obj, NULL);
4901 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4902 evas_object_image_size_set(cw->obj, tw, th);
4903 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4904 if (cw->pending_updates)
4905 eina_tiler_area_size_set(cw->pending_updates, w, h);
4906 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4908 evas_object_image_pixels_dirty_set(o, dirty);
4910 evas_object_image_data_set(o, NULL);
4911 evas_object_image_size_set(o, tw, th);
4912 visible |= evas_object_visible_get(o);
4916 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4920 e_comp_object_native_surface_set(obj, 1);
4922 m = _e_comp_object_map_damage_transform_get(cw->ec);
4923 it = eina_tiler_iterator_new(cw->updates);
4924 EINA_ITERATOR_FOREACH(it, rect)
4926 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4927 * of evas engine and doesn't convert damage according to evas_map.
4928 * so damage of evas_object_image use surface coordinate.
4932 int damage_x, damage_y, damage_w, damage_h;
4934 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4935 &damage_x, &damage_y, &damage_w, &damage_h);
4936 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4937 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4941 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4942 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4945 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4946 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4947 if (cw->pending_updates)
4948 eina_tiler_rect_add(cw->pending_updates, rect);
4950 eina_iterator_free(it);
4951 if (m) e_map_free(m);
4952 if (cw->pending_updates)
4953 eina_tiler_clear(cw->updates);
4956 cw->pending_updates = cw->updates;
4957 cw->updates = eina_tiler_new(w, h);
4958 eina_tiler_tile_size_set(cw->updates, 1, 1);
4960 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4961 evas_object_smart_callback_call(obj, "dirty", NULL);
4962 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4963 /* force render if main object is hidden but mirrors are visible */
4964 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4965 e_comp_object_render(obj);
4969 e_comp_object_render(Evas_Object *obj)
4976 API_ENTRY EINA_FALSE;
4978 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4979 if (cw->ec->input_only) return EINA_TRUE;
4980 if (cw->external_content) return EINA_TRUE;
4981 if (cw->native) return EINA_FALSE;
4982 /* if comp object is not redirected state, comp object should not be set by newly committed data
4983 because image size of comp object is 1x1 and it should not be shown on canvas */
4984 if (!cw->redirected) return EINA_TRUE;
4985 if (cw->render_update_lock.lock)
4987 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4990 e_comp_object_render_update_del(obj);
4991 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4993 if (!cw->pending_updates)
4995 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4996 evas_object_image_data_set(cw->obj, NULL);
4997 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4998 evas_object_image_data_set(o, NULL);
5002 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5004 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5006 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5009 e_pixmap_image_refresh(cw->ec->pixmap);
5010 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5013 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5014 e_pixmap_image_data_ref(cw->ec->pixmap);
5016 /* set pixel data */
5017 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5018 _e_comp_object_alpha_set(cw);
5019 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5021 evas_object_image_data_set(o, pix);
5022 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5023 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5026 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5028 e_comp_client_post_update_add(cw->ec);
5033 /* create a duplicate of an evas object */
5035 e_comp_object_util_mirror_add(Evas_Object *obj)
5039 unsigned int *pix = NULL;
5040 Eina_Bool argb = EINA_FALSE;
5045 cw = evas_object_data_get(obj, "comp_mirror");
5048 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5049 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5050 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5051 evas_object_image_alpha_set(o, 1);
5052 evas_object_image_source_set(o, obj);
5055 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5056 if (cw->external_content)
5058 ERR("%p of client %p is external content.", obj, cw->ec);
5061 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5062 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5063 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5064 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5065 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5066 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5067 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5068 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5069 evas_object_data_set(o, "comp_mirror", cw);
5071 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5072 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5074 evas_object_image_size_set(o, tw, th);
5077 pix = evas_object_image_data_get(cw->obj, 0);
5083 evas_object_image_native_surface_set(o, cw->ns);
5086 Evas_Native_Surface ns;
5087 memset(&ns, 0, sizeof(Evas_Native_Surface));
5088 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5089 evas_object_image_native_surface_set(o, &ns);
5094 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5095 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5097 (e_pixmap_image_exists(cw->ec->pixmap)))
5098 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5100 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5107 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5108 evas_object_image_pixels_dirty_set(o, dirty);
5109 evas_object_image_data_set(o, pix);
5110 evas_object_image_data_set(cw->obj, pix);
5112 evas_object_image_data_update_add(o, 0, 0, tw, th);
5117 //////////////////////////////////////////////////////
5120 e_comp_object_effect_allowed_get(Evas_Object *obj)
5122 API_ENTRY EINA_FALSE;
5124 if (!cw->shobj) return EINA_FALSE;
5125 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5126 return !e_comp_config_get()->match.disable_borders;
5129 /* setup an api effect for a client */
5131 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5134 Eina_Stringshare *grp;
5135 E_Comp_Config *config;
5136 Eina_Bool loaded = EINA_FALSE;
5138 API_ENTRY EINA_FALSE;
5139 if (!cw->shobj) return EINA_FALSE; //input window
5141 if (!effect) effect = "none";
5142 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5144 config = e_comp_config_get();
5145 if ((config) && (config->effect_file))
5147 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5149 cw->effect_set = EINA_TRUE;
5156 edje_object_file_get(cw->effect_obj, NULL, &grp);
5157 cw->effect_set = !eina_streq(effect, "none");
5158 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5159 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5161 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5162 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5163 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5165 if (cw->effect_running)
5167 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5170 cw->effect_set = EINA_FALSE;
5171 return cw->effect_set;
5175 if (cw->effect_running)
5177 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5180 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5181 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5182 if (cw->effect_clip)
5184 evas_object_clip_unset(cw->clip);
5185 cw->effect_clip = 0;
5187 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5189 _e_comp_object_dim_update(cw);
5191 return cw->effect_set;
5194 /* set params for embryo scripts in effect */
5196 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5198 Edje_Message_Int_Set *msg;
5202 EINA_SAFETY_ON_NULL_RETURN(params);
5203 EINA_SAFETY_ON_FALSE_RETURN(count);
5204 if (!cw->effect_set) return;
5206 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5207 msg->count = (int)count;
5208 for (x = 0; x < count; x++)
5209 msg->val[x] = params[x];
5210 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5211 edje_object_message_signal_process(cw->effect_obj);
5215 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5217 Edje_Signal_Cb end_cb;
5219 E_Comp_Object *cw = data;
5221 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5222 cw->effect_running = 0;
5223 if (!_e_comp_object_animating_end(cw)) return;
5225 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5227 evas_object_data_del(cw->smart_obj, "effect_running");
5228 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5229 e_client_visibility_calculate();
5232 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5233 if (!end_cb) return;
5234 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5235 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5236 end_cb(end_data, cw->smart_obj, emission, source);
5239 /* clip effect to client's zone */
5241 e_comp_object_effect_clip(Evas_Object *obj)
5244 if (!cw->ec->zone) return;
5245 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5246 if (!cw->effect_clip_able) return;
5247 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5248 cw->effect_clip = 1;
5251 /* unclip effect from client's zone */
5253 e_comp_object_effect_unclip(Evas_Object *obj)
5256 if (!cw->effect_clip) return;
5257 evas_object_clip_unset(cw->smart_obj);
5258 cw->effect_clip = 0;
5261 /* start effect, running end_cb after */
5263 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5265 API_ENTRY EINA_FALSE;
5266 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5267 if (!cw->effect_set) return EINA_FALSE;
5269 if (cw->effect_running)
5271 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5274 e_comp_object_effect_clip(obj);
5275 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5277 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5278 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5279 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5280 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5282 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5283 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5285 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5286 _e_comp_object_animating_begin(cw);
5287 cw->effect_running = 1;
5291 /* stop a currently-running effect immediately */
5293 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5296 Edje_Signal_Cb end_cb_before = NULL;
5297 void *end_data_before = NULL;
5298 API_ENTRY EINA_FALSE;
5300 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5301 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5303 if (end_cb_before != end_cb) return EINA_TRUE;
5304 e_comp_object_effect_unclip(obj);
5305 if (cw->effect_clip)
5307 evas_object_clip_unset(cw->effect_obj);
5308 cw->effect_clip = 0;
5310 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5311 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5313 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5315 evas_object_data_del(cw->smart_obj, "effect_running");
5316 e_client_visibility_calculate();
5319 cw->effect_running = 0;
5320 ret = _e_comp_object_animating_end(cw);
5322 if ((ret) && (end_cb_before))
5324 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5325 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5332 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5334 return a->pri - b->pri;
5337 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5338 E_API E_Comp_Object_Mover *
5339 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5341 E_Comp_Object_Mover *prov;
5343 prov = E_NEW(E_Comp_Object_Mover, 1);
5344 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5345 prov->func = provider;
5346 prov->data = (void*)data;
5349 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5350 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5355 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5357 EINA_SAFETY_ON_NULL_RETURN(prov);
5358 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5363 e_comp_object_effect_object_get(Evas_Object *obj)
5367 return cw->effect_obj;
5371 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5373 API_ENTRY EINA_FALSE;
5374 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5375 if (!cw->effect_set) return EINA_FALSE;
5382 ////////////////////////////////////
5385 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5387 if (e_comp->autoclose.obj)
5389 e_comp_ungrab_input(0, 1);
5390 if (e_comp->autoclose.del_cb)
5391 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5392 else if (!already_del)
5394 evas_object_hide(e_comp->autoclose.obj);
5395 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5397 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5399 e_comp->autoclose.obj = NULL;
5400 e_comp->autoclose.data = NULL;
5401 e_comp->autoclose.del_cb = NULL;
5402 e_comp->autoclose.key_cb = NULL;
5403 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5407 _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)
5409 _e_comp_object_autoclose_cleanup(0);
5413 _e_comp_object_autoclose_setup(Evas_Object *obj)
5415 if (!e_comp->autoclose.rect)
5417 /* create rect just below autoclose object to catch mouse events */
5418 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5419 evas_object_move(e_comp->autoclose.rect, 0, 0);
5420 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5421 evas_object_show(e_comp->autoclose.rect);
5422 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5423 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5424 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5425 e_comp_grab_input(0, 1);
5427 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5428 evas_object_focus_set(obj, 1);
5432 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5434 _e_comp_object_autoclose_setup(obj);
5435 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5439 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5441 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5442 _e_comp_object_autoclose_cleanup(1);
5443 if (e_client_focused_get()) return;
5444 if (e_config->focus_policy != E_FOCUS_MOUSE)
5449 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5453 if (e_comp->autoclose.obj)
5455 if (e_comp->autoclose.obj == obj) return;
5456 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5457 e_comp->autoclose.obj = obj;
5458 e_comp->autoclose.del_cb = del_cb;
5459 e_comp->autoclose.key_cb = cb;
5460 e_comp->autoclose.data = (void*)data;
5461 if (evas_object_visible_get(obj))
5462 _e_comp_object_autoclose_setup(obj);
5464 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5465 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5468 e_comp->autoclose.obj = obj;
5469 e_comp->autoclose.del_cb = del_cb;
5470 e_comp->autoclose.key_cb = cb;
5471 e_comp->autoclose.data = (void*)data;
5472 if (evas_object_visible_get(obj))
5473 _e_comp_object_autoclose_setup(obj);
5475 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5476 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5480 e_comp_object_is_animating(Evas_Object *obj)
5484 return cw->animating;
5488 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5492 if ((cw->external_content) &&
5493 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5495 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5496 "But current external content is %d object for %p.",
5497 cw->content_type, cw->ec);
5501 cw->user_alpha_set = EINA_TRUE;
5502 cw->user_alpha = alpha;
5504 if (!cw->obj) return;
5506 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5508 evas_object_image_alpha_set(cw->obj, alpha);
5510 if ((!cw->native) && (!cw->external_content))
5511 evas_object_image_data_set(cw->obj, NULL);
5515 e_comp_object_alpha_get(Evas_Object *obj)
5517 API_ENTRY EINA_FALSE;
5519 return evas_object_image_alpha_get(cw->obj);
5523 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5525 Eina_Bool mask_set = EINA_FALSE;
5529 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5530 if (cw->ec->input_only) return;
5537 o = evas_object_rectangle_add(e_comp->evas);
5538 evas_object_color_set(o, 0, 0, 0, 0);
5539 evas_object_clip_set(o, cw->clip);
5540 evas_object_smart_member_add(o, obj);
5541 evas_object_move(o, 0, 0);
5542 evas_object_resize(o, cw->w, cw->h);
5543 /* save render op value to restore when clear a mask.
5545 * NOTE: DO NOT change the render op on ec->frame while mask object
5546 * is set. it will overwrite the changed op value. */
5547 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5548 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5549 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5550 if (cw->visible) evas_object_show(o);
5553 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5554 ELOGF("COMP", " |mask_obj", cw->ec);
5555 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5562 evas_object_smart_member_del(cw->mask.obj);
5563 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5565 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5566 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5572 e_comp_object_mask_has(Evas_Object *obj)
5574 API_ENTRY EINA_FALSE;
5576 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5580 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5585 if ((cw->external_content) &&
5586 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5588 WRN("Can set up size to ONLY evas \"image\" object. "
5589 "But current external content is %d object for %p.",
5590 cw->content_type, cw->ec);
5594 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5596 evas_object_image_size_set(cw->obj, tw, th);
5600 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5602 Eina_Bool transform_set = EINA_FALSE;
5604 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5605 if (cw->ec->input_only) return;
5607 transform_set = !!set;
5611 if (!cw->transform_bg_obj)
5613 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5614 evas_object_move(o, 0, 0);
5615 evas_object_resize(o, 1, 1);
5616 if (cw->transform_bg_color.a >= 255)
5617 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5619 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5620 evas_object_color_set(o,
5621 cw->transform_bg_color.r,
5622 cw->transform_bg_color.g,
5623 cw->transform_bg_color.b,
5624 cw->transform_bg_color.a);
5625 if (cw->visible) evas_object_show(o);
5627 cw->transform_bg_obj = o;
5628 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5630 _e_comp_object_transform_obj_stack_update(obj);
5634 if (cw->transform_bg_obj)
5636 evas_object_smart_member_del(cw->transform_bg_obj);
5637 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5643 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5647 cw->transform_bg_color.r = r;
5648 cw->transform_bg_color.g = g;
5649 cw->transform_bg_color.b = b;
5650 cw->transform_bg_color.a = a;
5652 if (cw->transform_bg_obj)
5654 evas_object_color_set(cw->transform_bg_obj,
5655 cw->transform_bg_color.r,
5656 cw->transform_bg_color.g,
5657 cw->transform_bg_color.b,
5658 cw->transform_bg_color.a);
5663 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5666 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5667 if (cw->ec->input_only) return;
5668 if (!cw->transform_bg_obj) return;
5670 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5674 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5677 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5678 if (cw->ec->input_only) return;
5679 if (!cw->transform_bg_obj) return;
5681 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5685 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5687 Eina_Bool transform_set = EINA_FALSE;
5689 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5690 if (cw->ec->input_only) return;
5692 transform_set = !!set;
5696 if (!cw->transform_tranp_obj)
5698 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5699 evas_object_move(o, 0, 0);
5700 evas_object_resize(o, 1, 1);
5701 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5702 evas_object_color_set(o, 0, 0, 0, 0);
5703 if (cw->visible) evas_object_show(o);
5705 cw->transform_tranp_obj = o;
5706 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5708 _e_comp_object_transform_obj_stack_update(obj);
5712 if (cw->transform_tranp_obj)
5714 evas_object_smart_member_del(cw->transform_tranp_obj);
5715 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5721 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5724 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5725 if (cw->ec->input_only) return;
5726 if (!cw->transform_tranp_obj) return;
5728 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5732 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5735 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5736 if (cw->ec->input_only) return;
5737 if (!cw->transform_tranp_obj) return;
5739 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5743 e_comp_object_layer_update(Evas_Object *obj,
5744 Evas_Object *above, Evas_Object *below)
5746 E_Comp_Object *cw2 = NULL;
5747 Evas_Object *o = NULL;
5752 if (cw->ec->layer_block) return;
5753 if ((above) && (below))
5755 ERR("Invalid layer update request! cw=%p", cw);
5763 layer = evas_object_layer_get(o);
5764 cw2 = evas_object_data_get(o, "comp_obj");
5767 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5769 o = evas_object_above_get(o);
5770 if ((!o) || (o == cw->smart_obj)) break;
5771 if (evas_object_layer_get(o) != layer)
5773 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5778 ec = e_client_top_get();
5779 if (ec) o = ec->frame;
5782 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5786 _e_comp_object_layers_remove(cw);
5789 if (cw2->layer > cw->layer)
5790 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5791 else if (cw2->layer == cw->layer)
5794 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5796 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5798 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5801 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5804 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5808 e_comp_object_layer_get(Evas_Object *obj)
5815 e_comp_object_content_set(Evas_Object *obj,
5816 Evas_Object *content,
5817 E_Comp_Object_Content_Type type)
5819 API_ENTRY EINA_FALSE;
5821 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5822 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5823 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5827 ERR("Can't set e.swallow.content to requested content. "
5828 "Previous comp object should not be changed at all.");
5832 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5834 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5835 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5837 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5838 type, content, cw->ec, cw->ec->pixmap);
5842 cw->external_content = EINA_TRUE;
5845 cw->content_type = type;
5846 e_util_size_debug_set(cw->obj, 1);
5847 evas_object_name_set(cw->obj, "cw->obj");
5848 _e_comp_object_alpha_set(cw);
5851 _e_comp_object_shadow_setup(cw);
5857 e_comp_object_content_unset(Evas_Object *obj)
5859 API_ENTRY EINA_FALSE;
5861 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5864 if (!cw->obj && !cw->ec->visible)
5866 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5870 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5872 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5878 if (cw->frame_object)
5879 edje_object_part_unswallow(cw->frame_object, cw->obj);
5881 edje_object_part_unswallow(cw->shobj, cw->obj);
5883 evas_object_del(cw->obj);
5884 evas_object_hide(cw->obj);
5888 cw->external_content = EINA_FALSE;
5889 if (cw->ec->is_cursor)
5892 DBG("%p is cursor surface..", cw->ec);
5893 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5895 evas_object_resize(cw->ec->frame, pw, ph);
5896 evas_object_hide(cw->ec->frame);
5901 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5902 cw->obj = evas_object_image_filled_add(e_comp->evas);
5903 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5904 e_util_size_debug_set(cw->obj, 1);
5905 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5906 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5907 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5908 evas_object_name_set(cw->obj, "cw->obj");
5909 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5910 _e_comp_object_alpha_set(cw);
5913 _e_comp_object_shadow_setup(cw);
5918 _e_comp_intercept_show_helper(cw);
5922 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5923 e_comp_object_dirty(cw->smart_obj);
5924 e_comp_object_render(cw->smart_obj);
5925 e_comp_object_render_update_add(obj);
5930 EINTERN Evas_Object *
5931 e_comp_object_content_get(Evas_Object *obj)
5935 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5937 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5939 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5946 E_API E_Comp_Object_Content_Type
5947 e_comp_object_content_type_get(Evas_Object *obj)
5949 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5951 return cw->content_type;
5955 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5958 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5959 E_Comp_Config *conf = e_comp_config_get();
5960 if (cw->ec->input_only) return;
5961 if (!conf->dim_rect_enable) return;
5963 cw->dim.mask_set = mask_set;
5969 if (!cw->dim.enable) return;
5970 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5974 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5976 Eina_Bool mask_set = EINA_FALSE;
5980 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5981 E_Comp_Config *conf = e_comp_config_get();
5982 if (cw->ec->input_only) return;
5983 if (!conf->dim_rect_enable) return;
5989 if (cw->dim.mask_obj)
5991 evas_object_smart_member_del(cw->dim.mask_obj);
5992 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5995 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);
5996 o = evas_object_rectangle_add(e_comp->evas);
5997 evas_object_color_set(o, 0, 0, 0, 0);
5998 evas_object_smart_member_add(o, obj);
5999 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6000 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6002 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6003 if (cw->visible) evas_object_show(o);
6005 cw->dim.mask_obj = o;
6006 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6008 evas_object_layer_set(cw->dim.mask_obj, 9998);
6012 if (cw->dim.mask_obj)
6014 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6015 evas_object_smart_member_del(cw->dim.mask_obj);
6016 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6022 e_comp_object_dim_client_set(E_Client *ec)
6024 E_Comp_Config *conf = e_comp_config_get();
6026 if (!conf->dim_rect_enable) return ;
6027 if (dim_client == ec) return;
6029 Eina_Bool prev_dim = EINA_FALSE;
6030 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6032 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6033 prev_dim = EINA_TRUE;
6035 if (prev_dim && dim_client->visible && ec)
6037 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6038 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6042 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6043 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6049 e_comp_object_dim_client_get(void)
6051 E_Comp_Config *conf = e_comp_config_get();
6053 if (!conf->dim_rect_enable ) return NULL;
6059 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6062 char emit[32] = "\0";
6063 E_Comp_Config *conf = e_comp_config_get();
6066 if (!conf->dim_rect_enable) return;
6067 if (!cw->effect_obj) return;
6068 if (enable == cw->dim.enable) return;
6070 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6071 if (noeffect || !conf->dim_rect_effect)
6073 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6077 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6080 cw->dim.enable = enable;
6082 if (cw->dim.mask_set && !enable)
6084 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6085 edje_object_signal_emit(cw->effect_obj, emit, "e");
6087 else if (cw->dim.mask_set && enable)
6089 edje_object_signal_emit(cw->effect_obj, emit, "e");
6090 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6094 edje_object_signal_emit(cw->effect_obj, emit, "e");
6099 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6101 API_ENTRY EINA_FALSE;
6102 E_Comp_Config *conf = e_comp_config_get();
6104 if (!ec) return EINA_FALSE;
6105 if (!conf->dim_rect_enable) return EINA_FALSE;
6107 if (cw->dim.enable) return EINA_TRUE;
6113 _e_comp_object_dim_update(E_Comp_Object *cw)
6115 E_Comp_Config *conf = e_comp_config_get();
6118 if (!conf->dim_rect_enable) return;
6119 if (!cw->effect_obj) return;
6122 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6123 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6125 if (cw->dim.mask_set)
6127 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6133 e_comp_object_clear(Evas_Object *obj)
6137 _e_comp_object_clear(cw);
6141 e_comp_object_hwc_update_exists(Evas_Object *obj)
6143 API_ENTRY EINA_FALSE;
6144 return cw->hwc_need_update;
6149 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6152 cw->hwc_need_update = set;
6156 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6158 API_ENTRY EINA_FALSE;
6159 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6163 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6166 if (cw->indicator.obj != indicator)
6167 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6168 cw->indicator.obj = indicator;
6169 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6173 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6176 if (cw->indicator.obj != indicator) return;
6177 cw->indicator.obj = NULL;
6178 edje_object_part_unswallow(cw->shobj, indicator);
6182 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6185 Edje_Message_Int_Set *msg;
6187 if (!cw->indicator.obj) return;
6189 cw->indicator.w = w;
6190 cw->indicator.h = h;
6192 if (!cw->shobj) return;
6194 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6198 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6199 edje_object_message_signal_process(cw->shobj);
6202 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6204 e_comp_object_map_update(Evas_Object *obj)
6207 E_Client *ec = cw->ec;
6208 E_Comp_Wl_Client_Data *cdata;
6210 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6213 int l, remain = sizeof buffer;
6216 if (e_object_is_del(E_OBJECT(ec))) return;
6217 cdata = e_client_cdata_get(ec);
6220 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6221 * when new buffer is attached.
6223 if (!cdata->buffer_ref.buffer) return;
6225 if ((!cw->redirected) ||
6226 (e_client_video_hw_composition_check(ec)) ||
6227 (!e_comp_wl_output_buffer_transform_get(ec) &&
6228 cdata->scaler.buffer_viewport.buffer.scale == 1))
6230 if (evas_object_map_enable_get(cw->effect_obj))
6232 ELOGF("TRANSFORM", "map: disable", cw->ec);
6233 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6234 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6235 evas_object_resize(cw->effect_obj, tw, th);
6242 EINA_SAFETY_ON_NULL_RETURN(map);
6244 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6250 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6252 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6253 e_map_point_image_uv_set(map, 0, x, y);
6254 l = snprintf(p, remain, "%d,%d", x, y);
6255 p += l, remain -= l;
6257 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6258 e_map_point_image_uv_set(map, 1, x, y);
6259 l = snprintf(p, remain, " %d,%d", x, y);
6260 p += l, remain -= l;
6262 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6263 e_map_point_image_uv_set(map, 2, x, y);
6264 l = snprintf(p, remain, " %d,%d", x, y);
6265 p += l, remain -= l;
6267 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6268 e_map_point_image_uv_set(map, 3, x, y);
6269 l = snprintf(p, remain, " %d,%d", x, y);
6270 p += l, remain -= l;
6272 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6274 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6276 e_comp_object_map_set(cw->effect_obj, map);
6277 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6281 /* if there's screen rotation with comp mode, then ec->effect_obj and
6282 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6284 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6285 evas_object_resize(cw->effect_obj, tw, th);
6289 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6291 API_ENTRY EINA_FALSE;
6293 cw->render_trace = set;
6299 e_comp_object_native_usable_get(Evas_Object *obj)
6301 API_ENTRY EINA_FALSE;
6302 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6304 if (cw->ec->input_only) return EINA_FALSE;
6305 if (cw->external_content) return EINA_FALSE;
6306 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6308 /* just return true value, if it is normal case */
6309 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6312 Evas_Native_Surface *ns;
6313 ns = evas_object_image_native_surface_get(cw->obj);
6315 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6318 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6326 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6328 API_ENTRY EINA_FALSE;
6329 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6330 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6331 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6335 case E_COMP_IMAGE_FILTER_BLUR:
6336 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6338 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6339 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6341 case E_COMP_IMAGE_FILTER_INVERSE:
6342 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6344 case E_COMP_IMAGE_FILTER_NONE:
6346 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6350 cw->image_filter = filter;
6355 EINTERN E_Comp_Image_Filter
6356 e_comp_object_image_filter_get(Evas_Object *obj)
6358 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6359 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6360 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6361 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6363 return cw->image_filter;
6367 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6371 if (!_damage_trace) return;
6373 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6374 evas_object_del(obj);
6376 _damage_trace_post_objs = NULL;
6380 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6382 if (!_damage_trace) return;
6384 _damage_trace_post_objs = _damage_trace_objs;
6385 _damage_trace_objs = NULL;
6389 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6391 if (_damage_trace == onoff) return;
6395 evas_event_callback_add(e_comp->evas,
6396 EVAS_CALLBACK_RENDER_PRE,
6397 _e_comp_object_damage_trace_render_pre_cb,
6400 evas_event_callback_add(e_comp->evas,
6401 EVAS_CALLBACK_RENDER_POST,
6402 _e_comp_object_damage_trace_render_post_cb,
6409 EINA_LIST_FREE(_damage_trace_objs, obj)
6410 evas_object_del(obj);
6412 _damage_trace_objs = NULL;
6414 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6415 evas_object_del(obj);
6417 _damage_trace_post_objs = NULL;
6419 evas_event_callback_del(e_comp->evas,
6420 EVAS_CALLBACK_RENDER_PRE,
6421 _e_comp_object_damage_trace_render_pre_cb);
6423 evas_event_callback_del(e_comp->evas,
6424 EVAS_CALLBACK_RENDER_POST,
6425 _e_comp_object_damage_trace_render_post_cb);
6428 _damage_trace = onoff;
6432 e_comp_object_redirected_get(Evas_Object *obj)
6434 API_ENTRY EINA_FALSE;
6435 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6437 return cw->redirected;
6441 e_comp_object_color_visible_get(Evas_Object *obj)
6443 API_ENTRY EINA_FALSE;
6446 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6448 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6452 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6456 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6460 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6468 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6470 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6472 return e_map_set_to_comp_object(em, obj);
6476 e_comp_object_map_get(const Evas_Object *obj)
6478 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6480 return e_map_get_from_comp_object(obj);
6484 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6486 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6488 evas_object_map_enable_set(obj, enable);
6494 e_comp_object_render_update_lock(Evas_Object *obj)
6496 API_ENTRY EINA_FALSE;
6498 if (cw->render_update_lock.lock == 0)
6500 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6501 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6502 e_pixmap_resource_get(cw->ec->pixmap));
6503 e_comp_object_render_update_del(obj);
6504 ELOGF("COMP", "Render update lock enabled", cw->ec);
6507 cw->render_update_lock.lock++;
6513 e_comp_object_render_update_unlock(Evas_Object *obj)
6517 if (cw->render_update_lock.lock == 0)
6520 cw->render_update_lock.lock--;
6522 if (cw->render_update_lock.lock == 0)
6525 if (cw->render_update_lock.pending_move_set)
6527 evas_object_move(obj,
6528 cw->render_update_lock.pending_move_x,
6529 cw->render_update_lock.pending_move_y);
6530 cw->render_update_lock.pending_move_x = 0;
6531 cw->render_update_lock.pending_move_y = 0;
6532 cw->render_update_lock.pending_move_set = EINA_FALSE;
6535 if (cw->render_update_lock.pending_resize_set)
6537 evas_object_resize(obj,
6538 cw->render_update_lock.pending_resize_w,
6539 cw->render_update_lock.pending_resize_h);
6540 cw->render_update_lock.pending_resize_w = 0;
6541 cw->render_update_lock.pending_resize_h = 0;
6542 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6545 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6547 if ((cw->ec->exp_iconify.buffer_flush) &&
6548 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6549 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6550 e_comp_object_clear(obj);
6552 e_comp_object_render_update_add(obj);
6554 ELOGF("COMP", "Render update lock disabled", cw->ec);
6559 e_comp_object_render_update_lock_get(Evas_Object *obj)
6561 API_ENTRY EINA_FALSE;
6563 if (cw->render_update_lock.lock > 0)
6570 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6574 if (cw->transparent.set)
6576 if (r) *r = cw->transparent.user_r;
6577 if (g) *g = cw->transparent.user_g;
6578 if (b) *b = cw->transparent.user_b;
6579 if (a) *a = cw->transparent.user_a;
6583 evas_object_color_get(obj, r, g, b, a);