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;
2703 /* check for dialog children that steal focus */
2704 if ((ec->modal) && (ec->modal != ec) &&
2705 (ec->modal->visible) && (!e_object_is_del(E_OBJECT(ec->modal))))
2707 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
2709 ELOGF("FOCUS", "focus set | intercept focus to modal", ec->modal);
2710 e_client_frame_focus_set(ec->modal, focus);
2714 else if ((ec->leader) && (ec->leader->modal) &&
2715 (ec->leader->modal != ec) && ec->leader->modal->visible &&
2716 (!e_object_is_del(E_OBJECT(ec->leader->modal))))
2718 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
2720 ELOGF("FOCUS", "focus set | intercept focus to leader->modal", ec->leader->modal);
2721 e_client_frame_focus_set(ec->leader->modal, focus);
2727 /* not yet visible, wait till the next time... */
2728 ec->want_focus = !ec->hidden;
2733 e_client_focused_set(ec);
2737 if (e_client_focused_get() == ec)
2738 e_client_focused_set(NULL);
2742 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2744 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2746 evas_object_focus_set(obj, focus);
2750 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2752 E_Comp_Object *cw = data;
2754 if (cw->transparent.set)
2756 cw->transparent.user_r = r;
2757 cw->transparent.user_g = g;
2758 cw->transparent.user_b = b;
2759 cw->transparent.user_a = a;
2761 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2763 cw->transparent.user_r,
2764 cw->transparent.user_g,
2765 cw->transparent.user_b,
2766 cw->transparent.user_a);
2770 evas_object_color_set(obj, r, g, b, a);
2773 ////////////////////////////////////////////////////
2776 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2778 int w, h, ox, oy, ow, oh;
2780 Eina_Bool pass_event_flag = EINA_FALSE;
2781 E_Input_Rect_Data *input_rect_data;
2782 E_Input_Rect_Smart_Data *input_rect_sd;
2784 if (cw->frame_object)
2786 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2787 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2788 /* set a fixed size, force edje calc, check size difference */
2789 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2790 edje_object_message_signal_process(cw->frame_object);
2791 edje_object_calc_force(cw->frame_object);
2792 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2793 cw->client_inset.l = ox;
2794 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2795 cw->client_inset.t = oy;
2796 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2797 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2798 evas_object_resize(cw->frame_object, w, h);
2802 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2805 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2807 if (input_rect_data->obj)
2809 pass_event_flag = EINA_TRUE;
2815 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2816 evas_object_pass_events_set(cw->obj, pass_event_flag);
2820 cw->client_inset.l = 0;
2821 cw->client_inset.r = 0;
2822 cw->client_inset.t = 0;
2823 cw->client_inset.b = 0;
2825 cw->client_inset.calc = !!cw->frame_object;
2829 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2831 E_Comp_Object *cw = data;
2834 /* - get current size
2836 * - readjust for new frame size
2839 w = cw->ec->w, h = cw->ec->h;
2840 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2842 _e_comp_object_frame_recalc(cw);
2844 if (!cw->ec->fullscreen)
2845 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2847 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2848 if (cw->ec->shading || cw->ec->shaded) return;
2849 if (cw->ec->fullscreen)
2850 evas_object_resize(cw->ec->frame, cw->ec->zone->w, cw->ec->zone->h);
2851 else if (cw->ec->new_client)
2853 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2854 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2855 evas_object_resize(cw->ec->frame, w, h);
2857 else if ((w != cw->ec->w) || (h != cw->ec->h))
2858 evas_object_resize(cw->ec->frame, w, h);
2862 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2864 E_Comp_Object *cw = data;
2866 if (!cw->ec) return; //NYI
2867 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2869 cw->shade.x = cw->x;
2870 cw->shade.y = cw->y;
2871 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2875 _e_comp_smart_cb_shaded(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,shaded", "e");
2886 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2888 E_Comp_Object *cw = data;
2890 if (!cw->ec) return; //NYI
2891 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2893 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2897 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2899 E_Comp_Object *cw = data;
2901 if (!cw->ec) return; //NYI
2902 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2904 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2908 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2910 E_Comp_Object *cw = data;
2912 _e_comp_object_shadow_setup(cw);
2913 if (cw->frame_object)
2915 _e_comp_object_shadow(cw);
2916 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2917 _e_comp_object_frame_recalc(cw);
2918 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2923 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2925 E_Comp_Object *cw = data;
2927 if (_e_comp_object_shadow_setup(cw))
2928 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2929 if (cw->frame_object)
2931 _e_comp_object_shadow(cw);
2932 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2933 _e_comp_object_frame_recalc(cw);
2934 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2939 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2941 E_Comp_Object *cw = data;
2943 if (cw->frame_object)
2945 _e_comp_object_shadow(cw);
2946 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2947 _e_comp_object_frame_recalc(cw);
2948 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2953 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2955 E_Comp_Object *cw = data;
2957 if (_e_comp_object_shadow_setup(cw))
2960 cw->ec->changes.size = 1;
2962 if (cw->frame_object)
2964 _e_comp_object_shadow(cw);
2965 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2966 _e_comp_object_frame_recalc(cw);
2967 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2972 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2974 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2978 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2980 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2984 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2986 E_Comp_Object *cw = data;
2988 if (!cw->ec) return; //NYI
2989 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2993 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2995 E_Comp_Object *cw = data;
2997 if (!cw->ec) return; //NYI
2998 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3002 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3004 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3008 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3010 E_Comp_Object *cw = data;
3012 if (!e_object_is_del(E_OBJECT(cw->ec)))
3013 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3017 _e_comp_input_obj_smart_add(Evas_Object *obj)
3019 E_Input_Rect_Smart_Data *input_rect_sd;
3020 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3022 if (!input_rect_sd) return;
3023 evas_object_smart_data_set(obj, input_rect_sd);
3027 _e_comp_input_obj_smart_del(Evas_Object *obj)
3029 E_Input_Rect_Smart_Data *input_rect_sd;
3030 E_Input_Rect_Data *input_rect_data;
3032 input_rect_sd = evas_object_smart_data_get(obj);
3033 if (!input_rect_sd) return;
3035 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3037 if (input_rect_data->obj)
3039 evas_object_smart_member_del(input_rect_data->obj);
3040 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3042 E_FREE(input_rect_data);
3044 E_FREE(input_rect_sd);
3048 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3050 E_Input_Rect_Smart_Data *input_rect_sd;
3051 E_Input_Rect_Data *input_rect_data;
3055 input_rect_sd = evas_object_smart_data_get(obj);
3056 if (!input_rect_sd) return;
3058 cw = input_rect_sd->cw;
3059 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3061 if (input_rect_data->obj)
3063 evas_object_geometry_set(input_rect_data->obj,
3064 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3065 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3066 input_rect_data->rect.w, input_rect_data->rect.h);
3072 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3074 E_Input_Rect_Smart_Data *input_rect_sd;
3075 E_Input_Rect_Data *input_rect_data;
3079 input_rect_sd = evas_object_smart_data_get(obj);
3080 if (!input_rect_sd) return;
3082 cw = input_rect_sd->cw;
3083 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3085 if (input_rect_data->obj)
3087 evas_object_geometry_set(input_rect_data->obj,
3088 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3089 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3090 input_rect_data->rect.w, input_rect_data->rect.h);
3096 _e_comp_input_obj_smart_show(Evas_Object *obj)
3098 E_Input_Rect_Smart_Data *input_rect_sd;
3099 E_Input_Rect_Data *input_rect_data;
3102 input_rect_sd = evas_object_smart_data_get(obj);
3103 if (!input_rect_sd) return;
3105 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3107 if (input_rect_data->obj)
3109 evas_object_show(input_rect_data->obj);
3115 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3117 E_Input_Rect_Smart_Data *input_rect_sd;
3118 E_Input_Rect_Data *input_rect_data;
3121 input_rect_sd = evas_object_smart_data_get(obj);
3122 if (!input_rect_sd) return;
3124 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3126 if (input_rect_data->obj)
3128 evas_object_hide(input_rect_data->obj);
3134 _e_comp_input_obj_smart_init(void)
3136 if (_e_comp_input_obj_smart) return;
3138 static const Evas_Smart_Class sc =
3140 INPUT_OBJ_SMART_NAME,
3141 EVAS_SMART_CLASS_VERSION,
3142 _e_comp_input_obj_smart_add,
3143 _e_comp_input_obj_smart_del,
3144 _e_comp_input_obj_smart_move,
3145 _e_comp_input_obj_smart_resize,
3146 _e_comp_input_obj_smart_show,
3147 _e_comp_input_obj_smart_hide,
3160 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3166 _e_comp_smart_add(Evas_Object *obj)
3170 cw = E_NEW(E_Comp_Object, 1);
3171 EINA_SAFETY_ON_NULL_RETURN(cw);
3173 cw->smart_obj = obj;
3174 cw->x = cw->y = cw->w = cw->h = -1;
3175 evas_object_smart_data_set(obj, cw);
3176 cw->opacity = 255.0;
3177 cw->external_content = 0;
3178 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3179 cw->transform_bg_color.r = 0;
3180 cw->transform_bg_color.g = 0;
3181 cw->transform_bg_color.b = 0;
3182 cw->transform_bg_color.a = 255;
3183 evas_object_data_set(obj, "comp_obj", cw);
3184 evas_object_move(obj, -1, -1);
3185 /* intercept ALL the callbacks! */
3186 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3187 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3188 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3189 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3190 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3191 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3192 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3193 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3194 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3195 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3196 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3198 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3199 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3200 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3201 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3203 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3204 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3205 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3206 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3208 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3209 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3211 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3212 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3214 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3216 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3217 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3221 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3224 evas_object_color_set(cw->clip, r, g, b, a);
3225 evas_object_smart_callback_call(obj, "color_set", NULL);
3230 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3233 evas_object_clip_set(cw->clip, clip);
3237 _e_comp_smart_clip_unset(Evas_Object *obj)
3240 evas_object_clip_unset(cw->clip);
3244 _e_comp_smart_hide(Evas_Object *obj)
3246 TRACE_DS_BEGIN(COMP:SMART HIDE);
3251 evas_object_hide(cw->clip);
3252 if (cw->input_obj) evas_object_hide(cw->input_obj);
3253 evas_object_hide(cw->effect_obj);
3254 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3255 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3256 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3263 /* unset native surface if current displaying buffer was destroied */
3264 if (!cw->buffer_destroy_listener.notify)
3266 Evas_Native_Surface *ns;
3267 ns = evas_object_image_native_surface_get(cw->obj);
3268 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3269 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3272 if (!cw->ec->input_only)
3274 edje_object_freeze(cw->effect_obj);
3275 edje_object_freeze(cw->shobj);
3276 edje_object_play_set(cw->shobj, 0);
3277 if (cw->frame_object)
3278 edje_object_play_set(cw->frame_object, 0);
3280 /* ensure focus-out */
3281 if (cw->ec->focused &&
3282 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3284 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3285 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3286 e_client_focus_defer_unset(cw->ec);
3288 e_comp_render_queue(); //force nocomp recheck
3294 _e_comp_smart_show(Evas_Object *obj)
3302 if ((cw->w < 0) || (cw->h < 0))
3303 CRI("ACK! ec:%p", cw->ec);
3305 TRACE_DS_BEGIN(COMP:SMART SHOW);
3307 e_comp_object_map_update(obj);
3309 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3310 evas_object_show(tmp->frame);
3312 evas_object_show(cw->clip);
3313 if (cw->input_obj) evas_object_show(cw->input_obj);
3314 if (!cw->ec->input_only)
3316 edje_object_thaw(cw->effect_obj);
3317 edje_object_thaw(cw->shobj);
3318 edje_object_play_set(cw->shobj, 1);
3319 if (cw->frame_object)
3320 edje_object_play_set(cw->frame_object, 1);
3322 evas_object_show(cw->effect_obj);
3323 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3324 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3325 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3326 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3327 e_comp_render_queue();
3328 if (cw->ec->input_only)
3333 if (cw->ec->iconic && (!cw->ec->new_client))
3335 if (e_client_is_iconified_by_client(cw->ec))
3337 ELOGF("COMP", "Set launching flag..", cw->ec);
3338 cw->ec->launching = EINA_TRUE;
3341 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3343 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3346 ELOGF("COMP", "Set launching flag..", cw->ec);
3347 cw->ec->launching = EINA_TRUE;
3349 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3350 _e_comp_object_animating_begin(cw);
3351 if (!_e_comp_object_effect_visibility_start(cw, 1))
3357 /* ensure some random effect doesn't lock the client offscreen */
3361 e_comp_object_effect_set(obj, NULL);
3364 _e_comp_object_dim_update(cw);
3370 _e_comp_smart_del(Evas_Object *obj)
3376 if (cw->buffer_destroy_listener.notify)
3378 wl_list_remove(&cw->buffer_destroy_listener.link);
3379 cw->buffer_destroy_listener.notify = NULL;
3382 if (cw->tbm_surface)
3384 tbm_surface_internal_unref(cw->tbm_surface);
3385 cw->tbm_surface = NULL;
3388 if (cw->render_update_lock.buffer_ref.buffer)
3390 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3391 cw->ec, cw->render_update_lock.lock);
3392 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3395 e_comp_object_render_update_del(cw->smart_obj);
3396 E_FREE_FUNC(cw->updates, eina_tiler_free);
3397 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3404 EINA_LIST_FREE(cw->obj_mirror, o)
3406 evas_object_image_data_set(o, NULL);
3407 evas_object_freeze_events_set(o, 1);
3408 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3412 _e_comp_object_layers_remove(cw);
3413 l = evas_object_data_get(obj, "comp_object-to_del");
3414 E_FREE_LIST(l, evas_object_del);
3415 _e_comp_object_mouse_event_callback_unset(cw);
3416 evas_object_del(cw->clip);
3417 evas_object_del(cw->effect_obj);
3418 evas_object_del(cw->shobj);
3419 evas_object_del(cw->frame_object);
3420 evas_object_del(cw->input_obj);
3421 evas_object_del(cw->obj);
3422 evas_object_del(cw->mask.obj);
3423 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3424 evas_object_del(cw->transform_bg_obj);
3425 evas_object_del(cw->transform_tranp_obj);
3426 evas_object_del(cw->default_input_obj);
3427 eina_stringshare_del(cw->frame_theme);
3428 eina_stringshare_del(cw->frame_name);
3432 e_comp->animating--;
3434 e_object_unref(E_OBJECT(cw->ec));
3436 cw->ec->frame = NULL;
3441 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3445 cw->x = x, cw->y = y;
3446 evas_object_move(cw->effect_obj, x, y);
3447 evas_object_move(cw->default_input_obj, x, y);
3448 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3450 e_comp_object_map_update(obj);
3454 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3456 Eina_Bool first = EINA_FALSE;
3461 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3463 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3465 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3467 if (cw->w != w || cw->h != h)
3468 e_comp_object_map_update(obj);
3470 first = ((cw->w < 1) || (cw->h < 1));
3471 cw->w = w, cw->h = h;
3472 if ((!cw->ec->shading) && (!cw->ec->shaded))
3476 if (cw->frame_object)
3477 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3480 /* verify pixmap:object size */
3481 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3483 if ((ww != pw) || (hh != ph))
3484 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3486 evas_object_resize(cw->effect_obj, tw, th);
3487 evas_object_resize(cw->default_input_obj, w, h);
3489 evas_object_resize(cw->input_obj, w, h);
3491 evas_object_resize(cw->mask.obj, w, h);
3492 /* resize render update tiler */
3495 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3496 cw->updates_full = 0;
3497 if (cw->updates) eina_tiler_clear(cw->updates);
3501 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3502 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3507 evas_object_resize(cw->effect_obj, tw, th);
3508 evas_object_resize(cw->default_input_obj, w, h);
3515 e_comp_render_queue();
3521 _e_comp_smart_init(void)
3523 if (_e_comp_smart) return;
3525 static const Evas_Smart_Class sc =
3528 EVAS_SMART_CLASS_VERSION,
3532 _e_comp_smart_resize,
3535 _e_comp_smart_color_set,
3536 _e_comp_smart_clip_set,
3537 _e_comp_smart_clip_unset,
3547 _e_comp_smart = evas_smart_class_new(&sc);
3552 e_comp_object_init(void)
3554 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3555 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3556 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3557 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3561 e_comp_object_shutdown(void)
3567 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3569 API_ENTRY EINA_FALSE;
3570 return !!cw->force_visible;
3572 /////////////////////////////////////////////////////////
3575 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3578 Eina_Bool comp_object;
3580 comp_object = !!evas_object_data_get(obj, "comp_object");
3585 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3587 e_comp_render_queue();
3589 l = evas_object_data_get(obj, "comp_object-to_del");
3590 E_FREE_LIST(l, evas_object_del);
3594 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3596 if (e_comp_util_object_is_above_nocomp(obj) &&
3597 (!evas_object_data_get(obj, "comp_override")))
3599 evas_object_data_set(obj, "comp_override", (void*)1);
3600 e_comp_override_add();
3605 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3607 Eina_Bool ref = EINA_TRUE;
3608 if (evas_object_visible_get(obj))
3612 d = evas_object_data_del(obj, "comp_hiding");
3614 /* currently trying to hide */
3617 /* already visible */
3621 evas_object_show(obj);
3624 evas_object_ref(obj);
3625 evas_object_data_set(obj, "comp_ref", (void*)1);
3627 edje_object_signal_emit(obj, "e,state,visible", "e");
3628 evas_object_data_set(obj, "comp_showing", (void*)1);
3629 if (e_comp_util_object_is_above_nocomp(obj))
3631 evas_object_data_set(obj, "comp_override", (void*)1);
3632 e_comp_override_add();
3637 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3639 if (!evas_object_visible_get(obj)) return;
3640 /* already hiding */
3641 if (evas_object_data_get(obj, "comp_hiding")) return;
3642 if (!evas_object_data_del(obj, "comp_showing"))
3644 evas_object_ref(obj);
3645 evas_object_data_set(obj, "comp_ref", (void*)1);
3647 edje_object_signal_emit(obj, "e,state,hidden", "e");
3648 evas_object_data_set(obj, "comp_hiding", (void*)1);
3650 if (evas_object_data_del(obj, "comp_override"))
3651 e_comp_override_timed_pop();
3655 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3657 if (!e_util_strcmp(emission, "e,action,hide,done"))
3659 if (!evas_object_data_del(obj, "comp_hiding")) return;
3660 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3661 evas_object_hide(obj);
3662 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3665 evas_object_data_del(obj, "comp_showing");
3666 if (evas_object_data_del(obj, "comp_ref"))
3667 evas_object_unref(obj);
3671 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3677 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3681 E_API E_Comp_Object_Hook *
3682 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3684 E_Comp_Object_Hook *ch;
3686 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3687 ch = E_NEW(E_Comp_Object_Hook, 1);
3688 if (!ch) return NULL;
3689 ch->hookpoint = hookpoint;
3691 ch->data = (void*)data;
3692 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3697 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3700 if (_e_comp_object_hooks_walking == 0)
3702 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3706 _e_comp_object_hooks_delete++;
3709 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3710 E_API E_Comp_Object_Intercept_Hook *
3711 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3713 E_Comp_Object_Intercept_Hook *ch;
3715 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3716 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3717 if (!ch) return NULL;
3718 ch->hookpoint = hookpoint;
3720 ch->data = (void*)data;
3721 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3726 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3729 if (_e_comp_object_intercept_hooks_walking == 0)
3731 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3735 _e_comp_object_intercept_hooks_delete++;
3739 EINTERN Evas_Object *
3740 e_comp_object_util_add(Evas_Object *obj)
3742 Evas_Object *o, *z = NULL;
3744 E_Comp_Config *conf = e_comp_config_get();
3745 Eina_Bool skip = EINA_FALSE;
3751 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3753 name = evas_object_name_get(obj);
3754 vis = evas_object_visible_get(obj);
3755 o = edje_object_add(e_comp->evas);
3756 evas_object_data_set(o, "comp_object", (void*)1);
3758 skip = (!strncmp(name, "noshadow", 8));
3760 evas_object_data_set(o, "comp_object_skip", (void*)1);
3765 if (conf->shadow_style)
3769 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3770 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3775 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3778 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3779 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3781 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3783 evas_object_geometry_get(obj, &x, &y, &w, &h);
3784 evas_object_geometry_set(o, x, y, w, h);
3785 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3787 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3789 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3790 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3791 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3792 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3793 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3794 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3796 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3798 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3800 _e_comp_object_event_add(o);
3803 evas_object_show(o);
3808 /* utility functions for deleting objects when their "owner" is deleted */
3810 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3815 EINA_SAFETY_ON_NULL_RETURN(to_del);
3816 l = evas_object_data_get(obj, "comp_object-to_del");
3817 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3818 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3819 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3823 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3828 EINA_SAFETY_ON_NULL_RETURN(to_del);
3829 l = evas_object_data_get(obj, "comp_object-to_del");
3831 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3834 /////////////////////////////////////////////////////////
3836 EINTERN Evas_Object *
3837 e_comp_object_client_add(E_Client *ec)
3842 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3843 if (ec->frame) return NULL;
3844 _e_comp_smart_init();
3845 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3846 cw = evas_object_smart_data_get(o);
3847 if (!cw) return NULL;
3848 evas_object_data_set(o, "E_Client", ec);
3851 evas_object_data_set(o, "comp_object", (void*)1);
3853 _e_comp_object_event_add(o);
3858 /* utility functions for getting client inset */
3860 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3863 if (!cw->client_inset.calc)
3869 if (ax) *ax = x - cw->client_inset.l;
3870 if (ay) *ay = y - cw->client_inset.t;
3874 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3877 if (!cw->client_inset.calc)
3883 if (ax) *ax = x + cw->client_inset.l;
3884 if (ay) *ay = y + cw->client_inset.t;
3888 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3891 if (!cw->client_inset.calc)
3897 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3898 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3902 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3905 if (!cw->client_inset.calc)
3911 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3912 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3916 e_comp_object_client_get(Evas_Object *obj)
3921 /* FIXME: remove this when eo is used */
3922 o = evas_object_data_get(obj, "comp_smart_obj");
3924 return e_comp_object_client_get(o);
3925 return cw ? cw->ec : NULL;
3929 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3932 if (cw->frame_extends)
3933 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3938 if (w) *w = cw->ec->w;
3939 if (h) *h = cw->ec->h;
3944 e_comp_object_util_zone_get(Evas_Object *obj)
3946 E_Zone *zone = NULL;
3950 zone = cw->ec->zone;
3955 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3956 zone = e_comp_zone_xy_get(x, y);
3962 e_comp_object_util_center(Evas_Object *obj)
3964 int x, y, w, h, ow, oh;
3969 zone = e_comp_object_util_zone_get(obj);
3970 EINA_SAFETY_ON_NULL_RETURN(zone);
3971 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3972 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3973 ow = cw->ec->w, oh = cw->ec->h;
3975 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3976 x = x + (w - ow) / 2;
3977 y = y + (h - oh) / 2;
3978 evas_object_move(obj, x, y);
3982 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3984 int x, y, w, h, ow, oh;
3987 EINA_SAFETY_ON_NULL_RETURN(on);
3988 evas_object_geometry_get(on, &x, &y, &w, &h);
3989 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3990 ow = cw->ec->w, oh = cw->ec->h;
3992 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3993 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3997 e_comp_object_util_fullscreen(Evas_Object *obj)
4002 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4005 evas_object_move(obj, 0, 0);
4006 evas_object_resize(obj, e_comp->w, e_comp->h);
4011 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4019 ow = cw->w, oh = cw->h;
4021 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4022 zone = e_comp_object_util_zone_get(obj);
4023 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4024 if (x) *x = zx + (zw - ow) / 2;
4025 if (y) *y = zy + (zh - oh) / 2;
4029 e_comp_object_input_objs_del(Evas_Object *obj)
4032 E_Input_Rect_Data *input_rect_data;
4033 E_Input_Rect_Smart_Data *input_rect_sd;
4038 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4039 if (!input_rect_sd) return;
4041 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4043 if (input_rect_data->obj)
4045 evas_object_smart_member_del(input_rect_data->obj);
4046 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4048 E_FREE(input_rect_data);
4053 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4056 E_Input_Rect_Data *input_rect_data = NULL;
4057 E_Input_Rect_Smart_Data *input_rect_sd;
4058 int client_w, client_h;
4060 if (cw->ec->client.w)
4061 client_w = cw->ec->client.w;
4063 client_w = cw->ec->w;
4065 if (cw->ec->client.h)
4066 client_h = cw->ec->client.h;
4068 client_h = cw->ec->h;
4070 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4074 _e_comp_input_obj_smart_init();
4075 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4076 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4077 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4080 input_rect_sd->cw = cw;
4083 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4086 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4087 if (input_rect_data)
4089 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4090 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4094 if ((input_rect_data) &&
4095 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4097 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4098 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4099 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4100 evas_object_clip_set(input_rect_data->obj, cw->clip);
4101 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4102 evas_object_geometry_set(input_rect_data->obj,
4103 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4104 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4105 evas_object_pass_events_set(cw->default_input_obj, 1);
4106 evas_object_pass_events_set(cw->obj, 1);
4109 evas_object_show(input_rect_data->obj);
4110 evas_object_show(cw->input_obj);
4115 evas_object_smart_member_del(cw->input_obj);
4116 E_FREE_FUNC(cw->input_obj, evas_object_del);
4117 evas_object_pass_events_set(cw->default_input_obj, 0);
4118 evas_object_pass_events_set(cw->obj, 0);
4123 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4126 E_Input_Rect_Smart_Data *input_rect_sd;
4127 E_Input_Rect_Data *input_rect_data;
4130 if (!cw->input_obj) return;
4132 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4135 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4137 *list = eina_list_append(*list, &input_rect_data->rect);
4143 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4146 if (l) *l = cw->client_inset.l;
4147 if (r) *r = cw->client_inset.r;
4148 if (t) *t = cw->client_inset.t;
4149 if (b) *b = cw->client_inset.b;
4152 /* set geometry for CSD */
4154 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4160 if (cw->frame_object)
4161 CRI("ACK! ec:%p", cw->ec);
4162 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4163 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4164 calc = cw->client_inset.calc;
4165 cw->client_inset.calc = l || r || t || b;
4166 eina_stringshare_replace(&cw->frame_theme, "borderless");
4167 if (cw->client_inset.calc)
4169 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4170 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4171 e_client_size_set(cw->ec, tw, th);
4173 else if (cw->ec->maximized || cw->ec->fullscreen)
4175 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4176 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4178 if (!cw->ec->new_client)
4180 if (calc && cw->client_inset.calc)
4182 tx = cw->ec->x - (l - cw->client_inset.l);
4183 ty = cw->ec->y - (t - cw->client_inset.t);
4184 e_client_pos_set(cw->ec, tx, ty);
4186 cw->ec->changes.pos = cw->ec->changes.size = 1;
4189 cw->client_inset.l = l;
4190 cw->client_inset.r = r;
4191 cw->client_inset.t = t;
4192 cw->client_inset.b = b;
4196 e_comp_object_frame_allowed(Evas_Object *obj)
4198 API_ENTRY EINA_FALSE;
4199 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4203 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4205 API_ENTRY EINA_FALSE;
4206 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4207 eina_stringshare_replace(&cw->frame_name, name);
4208 if (cw->frame_object)
4209 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4214 e_comp_object_frame_exists(Evas_Object *obj)
4216 API_ENTRY EINA_FALSE;
4217 return !!cw->frame_object;
4221 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4223 Evas_Object *o, *pbg;
4226 Eina_Stringshare *theme;
4228 API_ENTRY EINA_FALSE;
4230 if (!e_util_strcmp(cw->frame_theme, name))
4231 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4232 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4233 return _e_comp_object_shadow_setup(cw);
4234 pbg = cw->frame_object;
4235 theme = eina_stringshare_add(name);
4237 if (cw->frame_object)
4241 w = cw->ec->w, h = cw->ec->h;
4242 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4243 if ((cw->ec->w != w) || (cw->ec->h != h))
4245 cw->ec->changes.size = 1;
4248 E_FREE_FUNC(cw->frame_object, evas_object_del);
4249 if (!name) goto reshadow;
4251 o = edje_object_add(e_comp->evas);
4252 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4253 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4254 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4256 cw->frame_object = NULL;
4258 eina_stringshare_del(cw->frame_theme);
4259 cw->frame_theme = theme;
4264 if (theme != e_config->theme_default_border_style)
4266 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4267 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4271 ok = e_theme_edje_object_set(o, "base/theme/border",
4272 "e/widgets/border/default/border");
4273 if (ok && (theme == e_config->theme_default_border_style))
4275 /* Reset default border style to default */
4276 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4277 e_config_save_queue();
4284 cw->frame_object = o;
4285 eina_stringshare_del(cw->frame_theme);
4286 cw->frame_theme = theme;
4287 evas_object_name_set(o, "cw->frame_object");
4290 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4294 cw->ec->changes.icon = 1;
4300 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4305 _e_comp_object_shadow_setup(cw);
4308 int old_x, old_y, new_x = 0, new_y = 0;
4310 old_x = cw->x, old_y = cw->y;
4312 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4314 new_x = cw->ec->x, new_y = cw->ec->y;
4315 else if (cw->ec->placed || (!cw->ec->new_client))
4317 /* if no previous frame:
4318 * - reapply client_inset
4323 if (cw->ec->changes.size)
4330 x = cw->ec->client.x, y = cw->ec->client.y;
4331 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4332 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4334 new_x = x, new_y = y;
4337 if (old_x != new_x || old_y != new_y)
4339 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4340 cw->y = cw->x = -99999;
4341 evas_object_move(obj, new_x, new_y);
4345 if (cw->ec->maximized)
4347 cw->ec->changes.need_maximize = 1;
4350 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4351 if (cw->frame_object)
4353 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4356 cw->frame_extends = 0;
4357 evas_object_del(pbg);
4362 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4364 E_Comp_Object_Mover *prov;
4367 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4368 edje_object_signal_emit(cw->shobj, sig, src);
4369 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4370 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4371 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4373 /* start with highest priority callback first */
4374 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4376 if (!e_util_glob_match(sig, prov->sig)) continue;
4377 if (prov->func(prov->data, obj, sig)) break;
4382 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4384 /* FIXME: at some point I guess this should use eo to inherit
4385 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4386 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4389 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4393 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4396 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4400 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4403 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4407 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4410 Eina_Rectangle rect;
4413 if (cw->ec->input_only || (!cw->updates)) return;
4414 if (cw->nocomp) return;
4415 rect.x = x, rect.y = y;
4416 rect.w = w, rect.h = h;
4417 evas_object_smart_callback_call(obj, "damage", &rect);
4419 if (e_comp_is_on_overlay(cw->ec))
4421 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4422 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4423 * E module attempts to block screen update due to the particular policy.
4425 if (e_pixmap_resource_get(cw->ec->pixmap))
4426 cw->hwc_need_update = EINA_TRUE;
4429 /* ignore overdraw */
4430 if (cw->updates_full)
4432 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4433 e_comp_object_render_update_add(obj);
4435 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4436 evas_object_show(cw->smart_obj);
4440 /* clip rect to client surface */
4441 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4442 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4443 /* if rect is the total size of the client after clip, clear the updates
4444 * since this is guaranteed to be the whole region anyway
4446 eina_tiler_area_size_get(cw->updates, &tw, &th);
4447 if ((w > tw) || (h > th))
4449 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4450 eina_tiler_clear(cw->updates);
4451 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4453 tw = cw->ec->client.w, th = cw->ec->client.h;
4455 if ((!x) && (!y) && (w == tw) && (h == th))
4457 eina_tiler_clear(cw->updates);
4458 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4459 cw->updates_full = 1;
4460 cw->update_count = 0;
4463 if (cw->update_count > UPDATE_MAX)
4465 /* this is going to get really dumb, so just update the whole thing */
4466 eina_tiler_clear(cw->updates);
4467 cw->update_count = cw->updates_full = 1;
4468 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4469 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4473 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4474 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4476 cw->updates_exist = 1;
4477 e_comp_object_render_update_add(obj);
4479 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4480 evas_object_show(cw->smart_obj);
4484 e_comp_object_damage_exists(Evas_Object *obj)
4486 API_ENTRY EINA_FALSE;
4487 return cw->updates_exist;
4491 e_comp_object_render_update_add(Evas_Object *obj)
4495 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4496 if (cw->render_update_lock.lock) return;
4497 if (e_object_is_del(E_OBJECT(cw->ec)))
4498 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4499 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4503 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4505 e_comp_render_queue();
4509 e_comp_object_render_update_del(Evas_Object *obj)
4513 if (cw->ec->input_only || (!cw->updates)) return;
4514 if (!cw->update) return;
4516 /* this gets called during comp animating to clear the update flag */
4517 if (e_comp->grabbed) return;
4518 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4519 if (!e_comp->updates)
4521 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4522 if (e_comp->render_animator)
4523 ecore_animator_freeze(e_comp->render_animator);
4528 e_comp_object_shape_apply(Evas_Object *obj)
4532 unsigned int i, *pix, *p;
4536 if (!cw->ec) return; //NYI
4537 if (cw->external_content) return;
4540 if ((cw->ec->shape_rects_num >= 1) &&
4541 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4546 ERR("BUGGER: shape with native surface? cw=%p", cw);
4549 evas_object_image_size_get(cw->obj, &w, &h);
4550 if ((w < 1) || (h < 1)) return;
4553 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4554 _e_comp_object_alpha_set(cw);
4555 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4556 evas_object_image_alpha_set(o, 1);
4558 p = pix = evas_object_image_data_get(cw->obj, 1);
4561 evas_object_image_data_set(cw->obj, pix);
4566 unsigned char *spix, *sp;
4568 spix = calloc(w * h, sizeof(unsigned char));
4570 for (i = 0; i < cw->ec->shape_rects_num; i++)
4574 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4575 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4576 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4577 sp = spix + (w * ry) + rx;
4578 for (py = 0; py < rh; py++)
4580 for (px = 0; px < rw; px++)
4588 for (py = 0; py < h; py++)
4590 for (px = 0; px < w; px++)
4592 unsigned int mask, imask;
4594 mask = ((unsigned int)(*sp)) << 24;
4596 imask |= imask >> 8;
4597 imask |= imask >> 8;
4598 *p = mask | (*p & imask);
4599 //if (*sp) *p = 0xff000000 | *p;
4600 //else *p = 0x00000000;
4609 for (py = 0; py < h; py++)
4611 for (px = 0; px < w; px++)
4615 evas_object_image_data_set(cw->obj, pix);
4616 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4617 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4619 evas_object_image_data_set(o, pix);
4620 evas_object_image_data_update_add(o, 0, 0, w, h);
4622 // don't need to fix alpha chanel as blending
4623 // should be totally off here regardless of
4624 // alpha channel content
4628 _e_comp_object_clear(E_Comp_Object *cw)
4633 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4635 if (cw->render_update_lock.lock) return;
4638 e_pixmap_clear(cw->ec->pixmap);
4640 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4641 evas_object_image_size_set(cw->obj, 1, 1);
4642 evas_object_image_data_set(cw->obj, NULL);
4643 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4645 evas_object_image_size_set(o, 1, 1);
4646 evas_object_image_data_set(o, NULL);
4649 e_comp_object_render_update_del(cw->smart_obj);
4653 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4657 API_ENTRY EINA_FALSE;
4659 if (cw->transparent.set == set)
4664 evas_object_color_get(obj, &r, &g, &b, &a);
4665 evas_object_color_set(obj, 0, 0, 0, 0);
4667 cw->transparent.user_r = r;
4668 cw->transparent.user_g = g;
4669 cw->transparent.user_b = b;
4670 cw->transparent.user_a = a;
4672 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4674 cw->transparent.user_r,
4675 cw->transparent.user_g,
4676 cw->transparent.user_b,
4677 cw->transparent.user_a);
4679 cw->transparent.set = EINA_TRUE;
4683 cw->transparent.set = EINA_FALSE;
4685 evas_object_color_set(obj,
4686 cw->transparent.user_r,
4687 cw->transparent.user_g,
4688 cw->transparent.user_b,
4689 cw->transparent.user_a);
4691 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4693 cw->transparent.user_r,
4694 cw->transparent.user_g,
4695 cw->transparent.user_b,
4696 cw->transparent.user_a);
4702 /* helper function to simplify toggling of redirection for display servers which support it */
4704 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4709 if (cw->redirected == set) return;
4710 cw->redirected = set;
4711 if (cw->external_content) return;
4713 e_comp_object_map_update(obj);
4717 if (cw->updates_exist)
4718 e_comp_object_render_update_add(obj);
4720 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4722 _e_comp_object_transparent_set(obj, EINA_FALSE);
4723 evas_object_smart_callback_call(obj, "redirected", NULL);
4727 _e_comp_object_clear(cw);
4728 _e_comp_object_transparent_set(obj, EINA_TRUE);
4729 evas_object_smart_callback_call(obj, "unredirected", NULL);
4734 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4737 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4739 if (cw->buffer_destroy_listener.notify)
4741 cw->buffer_destroy_listener.notify = NULL;
4742 wl_list_remove(&cw->buffer_destroy_listener.link);
4745 if (e_object_is_del(E_OBJECT(cw->ec)))
4747 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4752 /* if it's current displaying buffer, do not remove its content */
4753 if (!evas_object_visible_get(cw->ec->frame))
4754 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4759 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4764 if (cw->buffer_destroy_listener.notify)
4766 wl_list_remove(&cw->buffer_destroy_listener.link);
4767 cw->buffer_destroy_listener.notify = NULL;
4770 if (cw->tbm_surface)
4772 tbm_surface_internal_unref(cw->tbm_surface);
4773 cw->tbm_surface = NULL;
4778 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4780 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4781 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4783 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4785 tbm_surface_internal_ref(ns->data.tbm.buffer);
4786 cw->tbm_surface = ns->data.tbm.buffer;
4790 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4791 evas_object_image_native_surface_set(cw->obj, ns);
4795 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4797 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4798 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4799 evas_object_image_native_surface_set(o, ns);
4806 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4808 Evas_Native_Surface ns;
4811 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4812 if (cw->ec->input_only) return;
4813 if (cw->external_content) return;
4814 if (cw->render_update_lock.lock) return;
4817 memset(&ns, 0, sizeof(Evas_Native_Surface));
4821 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4822 set = (!cw->ec->shaped);
4824 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4828 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4832 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4835 if (cw->ec->input_only) return;
4838 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4839 _e_comp_object_alpha_set(cw);
4841 e_comp_object_native_surface_set(obj, cw->native);
4842 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4846 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4852 if (cw->blanked == set) return;
4854 _e_comp_object_alpha_set(cw);
4857 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4858 evas_object_image_data_set(cw->obj, NULL);
4862 e_comp_object_native_surface_set(obj, 1);
4863 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4867 _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)
4872 if (!_damage_trace) return;
4876 if (!evas_object_visible_get(cw->obj)) return;
4878 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4880 o = evas_object_rectangle_add(e_comp->evas);
4881 evas_object_layer_set(o, E_LAYER_MAX);
4882 evas_object_name_set(o, "damage_trace");
4883 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4884 evas_object_resize(o, dmg_w, dmg_h);
4885 evas_object_color_set(o, 0, 128, 0, 128);
4886 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4887 evas_object_pass_events_set(o, EINA_TRUE);
4888 evas_object_show(o);
4890 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4892 dmg_w, dmg_h, dmg_x, dmg_y,
4893 origin->w, origin->h, origin->x, origin->y);
4895 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4898 /* mark an object as dirty and setup damages */
4900 e_comp_object_dirty(Evas_Object *obj)
4903 Eina_Rectangle *rect;
4907 Eina_Bool dirty, visible;
4911 if (cw->external_content) return;
4912 if (!cw->redirected) return;
4913 if (cw->render_update_lock.lock)
4915 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4918 /* only actually dirty if pixmap is available */
4919 if (!e_pixmap_resource_get(cw->ec->pixmap))
4921 // e_pixmap_size_get returns last attached buffer size
4922 // eventhough it is destroyed
4923 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4926 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4927 visible = cw->visible;
4928 if (!dirty) w = h = 1;
4929 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4931 evas_object_image_data_set(cw->obj, NULL);
4932 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4933 evas_object_image_size_set(cw->obj, tw, th);
4934 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4935 if (cw->pending_updates)
4936 eina_tiler_area_size_set(cw->pending_updates, w, h);
4937 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4939 evas_object_image_pixels_dirty_set(o, dirty);
4941 evas_object_image_data_set(o, NULL);
4942 evas_object_image_size_set(o, tw, th);
4943 visible |= evas_object_visible_get(o);
4947 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4951 e_comp_object_native_surface_set(obj, 1);
4953 m = _e_comp_object_map_damage_transform_get(cw->ec);
4954 it = eina_tiler_iterator_new(cw->updates);
4955 EINA_ITERATOR_FOREACH(it, rect)
4957 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4958 * of evas engine and doesn't convert damage according to evas_map.
4959 * so damage of evas_object_image use surface coordinate.
4963 int damage_x, damage_y, damage_w, damage_h;
4965 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4966 &damage_x, &damage_y, &damage_w, &damage_h);
4967 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4968 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4972 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4973 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4976 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4977 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4978 if (cw->pending_updates)
4979 eina_tiler_rect_add(cw->pending_updates, rect);
4981 eina_iterator_free(it);
4982 if (m) e_map_free(m);
4983 if (cw->pending_updates)
4984 eina_tiler_clear(cw->updates);
4987 cw->pending_updates = cw->updates;
4988 cw->updates = eina_tiler_new(w, h);
4989 eina_tiler_tile_size_set(cw->updates, 1, 1);
4991 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4992 evas_object_smart_callback_call(obj, "dirty", NULL);
4993 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4994 /* force render if main object is hidden but mirrors are visible */
4995 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4996 e_comp_object_render(obj);
5000 e_comp_object_render(Evas_Object *obj)
5007 API_ENTRY EINA_FALSE;
5009 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5010 if (cw->ec->input_only) return EINA_TRUE;
5011 if (cw->external_content) return EINA_TRUE;
5012 if (cw->native) return EINA_FALSE;
5013 /* if comp object is not redirected state, comp object should not be set by newly committed data
5014 because image size of comp object is 1x1 and it should not be shown on canvas */
5015 if (!cw->redirected) return EINA_TRUE;
5016 if (cw->render_update_lock.lock)
5018 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5021 e_comp_object_render_update_del(obj);
5022 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5024 if (!cw->pending_updates)
5026 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5027 evas_object_image_data_set(cw->obj, NULL);
5028 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5029 evas_object_image_data_set(o, NULL);
5033 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5035 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5037 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5040 e_pixmap_image_refresh(cw->ec->pixmap);
5041 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5044 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5045 e_pixmap_image_data_ref(cw->ec->pixmap);
5047 /* set pixel data */
5048 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5049 _e_comp_object_alpha_set(cw);
5050 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5052 evas_object_image_data_set(o, pix);
5053 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5054 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5057 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5059 e_comp_client_post_update_add(cw->ec);
5064 /* create a duplicate of an evas object */
5065 EINTERN Evas_Object *
5066 e_comp_object_util_mirror_add(Evas_Object *obj)
5070 unsigned int *pix = NULL;
5071 Eina_Bool argb = EINA_FALSE;
5076 cw = evas_object_data_get(obj, "comp_mirror");
5079 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5080 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5081 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5082 evas_object_image_alpha_set(o, 1);
5083 evas_object_image_source_set(o, obj);
5086 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5087 if (cw->external_content)
5089 ERR("%p of client %p is external content.", obj, cw->ec);
5092 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5093 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5094 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5095 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5096 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5097 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5098 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5099 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5100 evas_object_data_set(o, "comp_mirror", cw);
5102 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5103 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5105 evas_object_image_size_set(o, tw, th);
5108 pix = evas_object_image_data_get(cw->obj, 0);
5114 evas_object_image_native_surface_set(o, cw->ns);
5117 Evas_Native_Surface ns;
5118 memset(&ns, 0, sizeof(Evas_Native_Surface));
5119 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5120 evas_object_image_native_surface_set(o, &ns);
5125 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5126 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5128 (e_pixmap_image_exists(cw->ec->pixmap)))
5129 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5131 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5138 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5139 evas_object_image_pixels_dirty_set(o, dirty);
5140 evas_object_image_data_set(o, pix);
5141 evas_object_image_data_set(cw->obj, pix);
5143 evas_object_image_data_update_add(o, 0, 0, tw, th);
5148 //////////////////////////////////////////////////////
5151 e_comp_object_effect_allowed_get(Evas_Object *obj)
5153 API_ENTRY EINA_FALSE;
5155 if (!cw->shobj) return EINA_FALSE;
5156 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5157 return !e_comp_config_get()->match.disable_borders;
5160 /* setup an api effect for a client */
5162 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5165 Eina_Stringshare *grp;
5166 E_Comp_Config *config;
5167 Eina_Bool loaded = EINA_FALSE;
5169 API_ENTRY EINA_FALSE;
5170 if (!cw->shobj) return EINA_FALSE; //input window
5172 if (!effect) effect = "none";
5173 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5175 config = e_comp_config_get();
5176 if ((config) && (config->effect_file))
5178 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5180 cw->effect_set = EINA_TRUE;
5187 edje_object_file_get(cw->effect_obj, NULL, &grp);
5188 cw->effect_set = !eina_streq(effect, "none");
5189 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5190 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5192 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5193 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5194 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5196 if (cw->effect_running)
5198 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5201 cw->effect_set = EINA_FALSE;
5202 return cw->effect_set;
5206 if (cw->effect_running)
5208 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5211 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5212 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5213 if (cw->effect_clip)
5215 evas_object_clip_unset(cw->clip);
5216 cw->effect_clip = 0;
5218 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5220 _e_comp_object_dim_update(cw);
5222 return cw->effect_set;
5225 /* set params for embryo scripts in effect */
5227 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5229 Edje_Message_Int_Set *msg;
5233 EINA_SAFETY_ON_NULL_RETURN(params);
5234 EINA_SAFETY_ON_FALSE_RETURN(count);
5235 if (!cw->effect_set) return;
5237 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5238 msg->count = (int)count;
5239 for (x = 0; x < count; x++)
5240 msg->val[x] = params[x];
5241 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5242 edje_object_message_signal_process(cw->effect_obj);
5246 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5248 Edje_Signal_Cb end_cb;
5250 E_Comp_Object *cw = data;
5252 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5253 cw->effect_running = 0;
5254 if (!_e_comp_object_animating_end(cw)) return;
5256 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5258 evas_object_data_del(cw->smart_obj, "effect_running");
5259 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5260 e_client_visibility_calculate();
5263 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5264 if (!end_cb) return;
5265 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5266 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5267 end_cb(end_data, cw->smart_obj, emission, source);
5270 /* clip effect to client's zone */
5272 e_comp_object_effect_clip(Evas_Object *obj)
5275 if (!cw->ec->zone) return;
5276 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5277 if (!cw->effect_clip_able) return;
5278 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5279 cw->effect_clip = 1;
5282 /* unclip effect from client's zone */
5284 e_comp_object_effect_unclip(Evas_Object *obj)
5287 if (!cw->effect_clip) return;
5288 evas_object_clip_unset(cw->smart_obj);
5289 cw->effect_clip = 0;
5292 /* start effect, running end_cb after */
5294 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5296 API_ENTRY EINA_FALSE;
5297 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5298 if (!cw->effect_set) return EINA_FALSE;
5300 if (cw->effect_running)
5302 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5305 e_comp_object_effect_clip(obj);
5306 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5308 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5309 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5310 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5311 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5313 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5314 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5316 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5317 _e_comp_object_animating_begin(cw);
5318 cw->effect_running = 1;
5322 /* stop a currently-running effect immediately */
5324 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5327 Edje_Signal_Cb end_cb_before = NULL;
5328 void *end_data_before = NULL;
5329 API_ENTRY EINA_FALSE;
5331 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5332 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5334 if (end_cb_before != end_cb) return EINA_TRUE;
5335 e_comp_object_effect_unclip(obj);
5336 if (cw->effect_clip)
5338 evas_object_clip_unset(cw->effect_obj);
5339 cw->effect_clip = 0;
5341 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5342 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5344 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5346 evas_object_data_del(cw->smart_obj, "effect_running");
5347 e_client_visibility_calculate();
5350 cw->effect_running = 0;
5351 ret = _e_comp_object_animating_end(cw);
5353 if ((ret) && (end_cb_before))
5355 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5356 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5363 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5365 return a->pri - b->pri;
5368 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5369 E_API E_Comp_Object_Mover *
5370 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5372 E_Comp_Object_Mover *prov;
5374 prov = E_NEW(E_Comp_Object_Mover, 1);
5375 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5376 prov->func = provider;
5377 prov->data = (void*)data;
5380 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5381 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5386 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5388 EINA_SAFETY_ON_NULL_RETURN(prov);
5389 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5394 e_comp_object_effect_object_get(Evas_Object *obj)
5398 return cw->effect_obj;
5402 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5404 API_ENTRY EINA_FALSE;
5405 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5406 if (!cw->effect_set) return EINA_FALSE;
5413 ////////////////////////////////////
5416 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5418 if (e_comp->autoclose.obj)
5420 e_comp_ungrab_input(0, 1);
5421 if (e_comp->autoclose.del_cb)
5422 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5423 else if (!already_del)
5425 evas_object_hide(e_comp->autoclose.obj);
5426 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5428 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5430 e_comp->autoclose.obj = NULL;
5431 e_comp->autoclose.data = NULL;
5432 e_comp->autoclose.del_cb = NULL;
5433 e_comp->autoclose.key_cb = NULL;
5434 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5438 _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)
5440 _e_comp_object_autoclose_cleanup(0);
5444 _e_comp_object_autoclose_setup(Evas_Object *obj)
5446 if (!e_comp->autoclose.rect)
5448 /* create rect just below autoclose object to catch mouse events */
5449 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5450 evas_object_move(e_comp->autoclose.rect, 0, 0);
5451 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5452 evas_object_show(e_comp->autoclose.rect);
5453 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5454 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5455 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5456 e_comp_grab_input(0, 1);
5458 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5459 evas_object_focus_set(obj, 1);
5463 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5465 _e_comp_object_autoclose_setup(obj);
5466 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5470 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5472 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5473 _e_comp_object_autoclose_cleanup(1);
5474 if (e_client_focused_get()) return;
5475 if (e_config->focus_policy != E_FOCUS_MOUSE)
5480 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5484 if (e_comp->autoclose.obj)
5486 if (e_comp->autoclose.obj == obj) return;
5487 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5488 e_comp->autoclose.obj = obj;
5489 e_comp->autoclose.del_cb = del_cb;
5490 e_comp->autoclose.key_cb = cb;
5491 e_comp->autoclose.data = (void*)data;
5492 if (evas_object_visible_get(obj))
5493 _e_comp_object_autoclose_setup(obj);
5495 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5496 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5499 e_comp->autoclose.obj = obj;
5500 e_comp->autoclose.del_cb = del_cb;
5501 e_comp->autoclose.key_cb = cb;
5502 e_comp->autoclose.data = (void*)data;
5503 if (evas_object_visible_get(obj))
5504 _e_comp_object_autoclose_setup(obj);
5506 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5507 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5511 e_comp_object_is_animating(Evas_Object *obj)
5515 return cw->animating;
5519 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5523 if ((cw->external_content) &&
5524 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5526 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5527 "But current external content is %d object for %p.",
5528 cw->content_type, cw->ec);
5532 cw->user_alpha_set = EINA_TRUE;
5533 cw->user_alpha = alpha;
5535 if (!cw->obj) return;
5537 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5539 evas_object_image_alpha_set(cw->obj, alpha);
5541 if ((!cw->native) && (!cw->external_content))
5542 evas_object_image_data_set(cw->obj, NULL);
5546 e_comp_object_alpha_get(Evas_Object *obj)
5548 API_ENTRY EINA_FALSE;
5550 return evas_object_image_alpha_get(cw->obj);
5554 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5556 Eina_Bool mask_set = EINA_FALSE;
5560 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5561 if (cw->ec->input_only) return;
5568 o = evas_object_rectangle_add(e_comp->evas);
5569 evas_object_color_set(o, 0, 0, 0, 0);
5570 evas_object_clip_set(o, cw->clip);
5571 evas_object_smart_member_add(o, obj);
5572 evas_object_move(o, 0, 0);
5573 evas_object_resize(o, cw->w, cw->h);
5574 /* save render op value to restore when clear a mask.
5576 * NOTE: DO NOT change the render op on ec->frame while mask object
5577 * is set. it will overwrite the changed op value. */
5578 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5579 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5580 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5581 if (cw->visible) evas_object_show(o);
5584 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5585 ELOGF("COMP", " |mask_obj", cw->ec);
5586 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5593 evas_object_smart_member_del(cw->mask.obj);
5594 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5596 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5597 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5603 e_comp_object_mask_has(Evas_Object *obj)
5605 API_ENTRY EINA_FALSE;
5607 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5611 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5616 if ((cw->external_content) &&
5617 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5619 WRN("Can set up size to ONLY evas \"image\" object. "
5620 "But current external content is %d object for %p.",
5621 cw->content_type, cw->ec);
5625 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5627 evas_object_image_size_set(cw->obj, tw, th);
5631 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5633 Eina_Bool transform_set = EINA_FALSE;
5635 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5636 if (cw->ec->input_only) return;
5638 transform_set = !!set;
5642 if (!cw->transform_bg_obj)
5644 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5645 evas_object_move(o, 0, 0);
5646 evas_object_resize(o, 1, 1);
5647 if (cw->transform_bg_color.a >= 255)
5648 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5650 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5651 evas_object_color_set(o,
5652 cw->transform_bg_color.r,
5653 cw->transform_bg_color.g,
5654 cw->transform_bg_color.b,
5655 cw->transform_bg_color.a);
5656 if (cw->visible) evas_object_show(o);
5658 cw->transform_bg_obj = o;
5659 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5661 _e_comp_object_transform_obj_stack_update(obj);
5665 if (cw->transform_bg_obj)
5667 evas_object_smart_member_del(cw->transform_bg_obj);
5668 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5674 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5678 cw->transform_bg_color.r = r;
5679 cw->transform_bg_color.g = g;
5680 cw->transform_bg_color.b = b;
5681 cw->transform_bg_color.a = a;
5683 if (cw->transform_bg_obj)
5685 evas_object_color_set(cw->transform_bg_obj,
5686 cw->transform_bg_color.r,
5687 cw->transform_bg_color.g,
5688 cw->transform_bg_color.b,
5689 cw->transform_bg_color.a);
5694 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5697 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5698 if (cw->ec->input_only) return;
5699 if (!cw->transform_bg_obj) return;
5701 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5705 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5708 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5709 if (cw->ec->input_only) return;
5710 if (!cw->transform_bg_obj) return;
5712 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5716 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5718 Eina_Bool transform_set = EINA_FALSE;
5720 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5721 if (cw->ec->input_only) return;
5723 transform_set = !!set;
5727 if (!cw->transform_tranp_obj)
5729 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5730 evas_object_move(o, 0, 0);
5731 evas_object_resize(o, 1, 1);
5732 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5733 evas_object_color_set(o, 0, 0, 0, 0);
5734 if (cw->visible) evas_object_show(o);
5736 cw->transform_tranp_obj = o;
5737 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5739 _e_comp_object_transform_obj_stack_update(obj);
5743 if (cw->transform_tranp_obj)
5745 evas_object_smart_member_del(cw->transform_tranp_obj);
5746 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5752 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5755 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5756 if (cw->ec->input_only) return;
5757 if (!cw->transform_tranp_obj) return;
5759 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5763 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5766 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5767 if (cw->ec->input_only) return;
5768 if (!cw->transform_tranp_obj) return;
5770 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5774 e_comp_object_layer_update(Evas_Object *obj,
5775 Evas_Object *above, Evas_Object *below)
5777 E_Comp_Object *cw2 = NULL;
5778 Evas_Object *o = NULL;
5783 if (cw->ec->layer_block) return;
5784 if ((above) && (below))
5786 ERR("Invalid layer update request! cw=%p", cw);
5794 layer = evas_object_layer_get(o);
5795 cw2 = evas_object_data_get(o, "comp_obj");
5798 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5800 o = evas_object_above_get(o);
5801 if ((!o) || (o == cw->smart_obj)) break;
5802 if (evas_object_layer_get(o) != layer)
5804 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5809 ec = e_client_top_get();
5810 if (ec) o = ec->frame;
5813 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5817 _e_comp_object_layers_remove(cw);
5820 if (cw2->layer > cw->layer)
5821 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5822 else if (cw2->layer == cw->layer)
5825 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5827 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5829 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5832 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5835 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5839 e_comp_object_layer_get(Evas_Object *obj)
5846 e_comp_object_content_set(Evas_Object *obj,
5847 Evas_Object *content,
5848 E_Comp_Object_Content_Type type)
5850 API_ENTRY EINA_FALSE;
5852 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5853 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5854 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5858 ERR("Can't set e.swallow.content to requested content. "
5859 "Previous comp object should not be changed at all.");
5863 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5865 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5866 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5868 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5869 type, content, cw->ec, cw->ec->pixmap);
5873 cw->external_content = EINA_TRUE;
5876 cw->content_type = type;
5877 e_util_size_debug_set(cw->obj, 1);
5878 evas_object_name_set(cw->obj, "cw->obj");
5879 _e_comp_object_alpha_set(cw);
5882 _e_comp_object_shadow_setup(cw);
5888 e_comp_object_content_unset(Evas_Object *obj)
5890 API_ENTRY EINA_FALSE;
5892 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5893 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5895 if (!cw->obj && !cw->ec->visible)
5897 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5901 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5903 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5909 if (cw->frame_object)
5910 edje_object_part_unswallow(cw->frame_object, cw->obj);
5912 edje_object_part_unswallow(cw->shobj, cw->obj);
5914 evas_object_del(cw->obj);
5915 evas_object_hide(cw->obj);
5919 cw->external_content = EINA_FALSE;
5920 if (cw->ec->is_cursor)
5923 DBG("%p is cursor surface..", cw->ec);
5924 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5926 evas_object_resize(cw->ec->frame, pw, ph);
5927 evas_object_hide(cw->ec->frame);
5932 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5933 cw->obj = evas_object_image_filled_add(e_comp->evas);
5934 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5935 e_util_size_debug_set(cw->obj, 1);
5936 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5937 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5938 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5939 evas_object_name_set(cw->obj, "cw->obj");
5940 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5941 _e_comp_object_alpha_set(cw);
5944 _e_comp_object_shadow_setup(cw);
5949 _e_comp_intercept_show_helper(cw);
5953 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5954 e_comp_object_dirty(cw->smart_obj);
5955 e_comp_object_render(cw->smart_obj);
5956 e_comp_object_render_update_add(obj);
5961 EINTERN Evas_Object *
5962 e_comp_object_content_get(Evas_Object *obj)
5966 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5968 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5970 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5977 E_API E_Comp_Object_Content_Type
5978 e_comp_object_content_type_get(Evas_Object *obj)
5980 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5982 return cw->content_type;
5986 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5989 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5990 E_Comp_Config *conf = e_comp_config_get();
5991 if (cw->ec->input_only) return;
5992 if (!conf->dim_rect_enable) return;
5994 cw->dim.mask_set = mask_set;
6000 if (!cw->dim.enable) return;
6001 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6005 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6007 Eina_Bool mask_set = EINA_FALSE;
6011 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6012 E_Comp_Config *conf = e_comp_config_get();
6013 if (cw->ec->input_only) return;
6014 if (!conf->dim_rect_enable) return;
6020 if (cw->dim.mask_obj)
6022 evas_object_smart_member_del(cw->dim.mask_obj);
6023 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6026 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);
6027 o = evas_object_rectangle_add(e_comp->evas);
6028 evas_object_color_set(o, 0, 0, 0, 0);
6029 evas_object_smart_member_add(o, obj);
6030 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6031 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6033 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6034 if (cw->visible) evas_object_show(o);
6036 cw->dim.mask_obj = o;
6037 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6039 evas_object_layer_set(cw->dim.mask_obj, 9998);
6043 if (cw->dim.mask_obj)
6045 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6046 evas_object_smart_member_del(cw->dim.mask_obj);
6047 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6053 e_comp_object_dim_client_set(E_Client *ec)
6055 E_Comp_Config *conf = e_comp_config_get();
6057 if (!conf->dim_rect_enable) return ;
6058 if (dim_client == ec) return;
6060 Eina_Bool prev_dim = EINA_FALSE;
6061 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6063 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6064 prev_dim = EINA_TRUE;
6066 if (prev_dim && dim_client->visible && ec)
6068 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6069 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6073 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6074 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6080 e_comp_object_dim_client_get(void)
6082 E_Comp_Config *conf = e_comp_config_get();
6084 if (!conf->dim_rect_enable ) return NULL;
6090 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6093 char emit[32] = "\0";
6094 E_Comp_Config *conf = e_comp_config_get();
6097 if (!conf->dim_rect_enable) return;
6098 if (!cw->effect_obj) return;
6099 if (enable == cw->dim.enable) return;
6101 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6102 if (noeffect || !conf->dim_rect_effect)
6104 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6108 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6111 cw->dim.enable = enable;
6113 if (cw->dim.mask_set && !enable)
6115 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6116 edje_object_signal_emit(cw->effect_obj, emit, "e");
6118 else if (cw->dim.mask_set && enable)
6120 edje_object_signal_emit(cw->effect_obj, emit, "e");
6121 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6125 edje_object_signal_emit(cw->effect_obj, emit, "e");
6130 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6132 API_ENTRY EINA_FALSE;
6133 E_Comp_Config *conf = e_comp_config_get();
6135 if (!ec) return EINA_FALSE;
6136 if (!conf->dim_rect_enable) return EINA_FALSE;
6138 if (cw->dim.enable) return EINA_TRUE;
6144 _e_comp_object_dim_update(E_Comp_Object *cw)
6146 E_Comp_Config *conf = e_comp_config_get();
6149 if (!conf->dim_rect_enable) return;
6150 if (!cw->effect_obj) return;
6153 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6154 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6156 if (cw->dim.mask_set)
6158 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6164 e_comp_object_clear(Evas_Object *obj)
6168 _e_comp_object_clear(cw);
6172 e_comp_object_hwc_update_exists(Evas_Object *obj)
6174 API_ENTRY EINA_FALSE;
6175 return cw->hwc_need_update;
6180 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6183 cw->hwc_need_update = set;
6187 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6189 API_ENTRY EINA_FALSE;
6190 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6194 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6197 if (cw->indicator.obj != indicator)
6198 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6199 cw->indicator.obj = indicator;
6200 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6204 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6207 if (cw->indicator.obj != indicator) return;
6208 cw->indicator.obj = NULL;
6209 edje_object_part_unswallow(cw->shobj, indicator);
6213 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6216 Edje_Message_Int_Set *msg;
6218 if (!cw->indicator.obj) return;
6220 cw->indicator.w = w;
6221 cw->indicator.h = h;
6223 if (!cw->shobj) return;
6225 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6229 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6230 edje_object_message_signal_process(cw->shobj);
6233 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6235 e_comp_object_map_update(Evas_Object *obj)
6238 E_Client *ec = cw->ec;
6239 E_Comp_Wl_Client_Data *cdata;
6241 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6244 int l, remain = sizeof buffer;
6247 if (e_object_is_del(E_OBJECT(ec))) return;
6248 cdata = e_client_cdata_get(ec);
6251 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6252 * when new buffer is attached.
6254 if (!cdata->buffer_ref.buffer) return;
6256 if ((!cw->redirected) ||
6257 (e_client_video_hw_composition_check(ec)) ||
6258 (!e_comp_wl_output_buffer_transform_get(ec) &&
6259 cdata->scaler.buffer_viewport.buffer.scale == 1))
6261 if (evas_object_map_enable_get(cw->effect_obj))
6263 ELOGF("TRANSFORM", "map: disable", cw->ec);
6264 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6265 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6266 evas_object_resize(cw->effect_obj, tw, th);
6273 EINA_SAFETY_ON_NULL_RETURN(map);
6275 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6281 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6283 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6284 e_map_point_image_uv_set(map, 0, x, y);
6285 l = snprintf(p, remain, "%d,%d", x, y);
6286 p += l, remain -= l;
6288 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6289 e_map_point_image_uv_set(map, 1, x, y);
6290 l = snprintf(p, remain, " %d,%d", x, y);
6291 p += l, remain -= l;
6293 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6294 e_map_point_image_uv_set(map, 2, x, y);
6295 l = snprintf(p, remain, " %d,%d", x, y);
6296 p += l, remain -= l;
6298 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6299 e_map_point_image_uv_set(map, 3, x, y);
6300 l = snprintf(p, remain, " %d,%d", x, y);
6301 p += l, remain -= l;
6303 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6305 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6307 e_comp_object_map_set(cw->effect_obj, map);
6308 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6312 /* if there's screen rotation with comp mode, then ec->effect_obj and
6313 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6315 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6316 evas_object_resize(cw->effect_obj, tw, th);
6320 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6322 API_ENTRY EINA_FALSE;
6324 cw->render_trace = set;
6330 e_comp_object_native_usable_get(Evas_Object *obj)
6332 API_ENTRY EINA_FALSE;
6333 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6335 if (cw->ec->input_only) return EINA_FALSE;
6336 if (cw->external_content) return EINA_FALSE;
6337 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6339 /* just return true value, if it is normal case */
6340 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6343 Evas_Native_Surface *ns;
6344 ns = evas_object_image_native_surface_get(cw->obj);
6346 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6349 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6357 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6359 API_ENTRY EINA_FALSE;
6360 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6361 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6362 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6366 case E_COMP_IMAGE_FILTER_BLUR:
6367 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6369 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6370 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6372 case E_COMP_IMAGE_FILTER_INVERSE:
6373 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6375 case E_COMP_IMAGE_FILTER_NONE:
6377 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6381 cw->image_filter = filter;
6386 EINTERN E_Comp_Image_Filter
6387 e_comp_object_image_filter_get(Evas_Object *obj)
6389 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6390 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6391 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6392 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6394 return cw->image_filter;
6398 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6402 if (!_damage_trace) return;
6404 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6405 evas_object_del(obj);
6407 _damage_trace_post_objs = NULL;
6411 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6413 if (!_damage_trace) return;
6415 _damage_trace_post_objs = _damage_trace_objs;
6416 _damage_trace_objs = NULL;
6420 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6422 if (_damage_trace == onoff) return;
6426 evas_event_callback_add(e_comp->evas,
6427 EVAS_CALLBACK_RENDER_PRE,
6428 _e_comp_object_damage_trace_render_pre_cb,
6431 evas_event_callback_add(e_comp->evas,
6432 EVAS_CALLBACK_RENDER_POST,
6433 _e_comp_object_damage_trace_render_post_cb,
6440 EINA_LIST_FREE(_damage_trace_objs, obj)
6441 evas_object_del(obj);
6443 _damage_trace_objs = NULL;
6445 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6446 evas_object_del(obj);
6448 _damage_trace_post_objs = NULL;
6450 evas_event_callback_del(e_comp->evas,
6451 EVAS_CALLBACK_RENDER_PRE,
6452 _e_comp_object_damage_trace_render_pre_cb);
6454 evas_event_callback_del(e_comp->evas,
6455 EVAS_CALLBACK_RENDER_POST,
6456 _e_comp_object_damage_trace_render_post_cb);
6459 _damage_trace = onoff;
6463 e_comp_object_redirected_get(Evas_Object *obj)
6465 API_ENTRY EINA_FALSE;
6466 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6468 return cw->redirected;
6472 e_comp_object_color_visible_get(Evas_Object *obj)
6474 API_ENTRY EINA_FALSE;
6477 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6479 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6483 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6487 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6491 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6499 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6501 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6503 return e_map_set_to_comp_object(em, obj);
6507 e_comp_object_map_get(const Evas_Object *obj)
6509 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6511 return e_map_get_from_comp_object(obj);
6515 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6517 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6519 evas_object_map_enable_set(obj, enable);
6525 e_comp_object_render_update_lock(Evas_Object *obj)
6527 API_ENTRY EINA_FALSE;
6529 if (cw->render_update_lock.lock == 0)
6531 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6532 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6533 e_pixmap_resource_get(cw->ec->pixmap));
6534 e_comp_object_render_update_del(obj);
6535 ELOGF("COMP", "Render update lock enabled", cw->ec);
6538 cw->render_update_lock.lock++;
6544 e_comp_object_render_update_unlock(Evas_Object *obj)
6548 if (cw->render_update_lock.lock == 0)
6551 cw->render_update_lock.lock--;
6553 if (cw->render_update_lock.lock == 0)
6556 if (cw->render_update_lock.pending_move_set)
6558 evas_object_move(obj,
6559 cw->render_update_lock.pending_move_x,
6560 cw->render_update_lock.pending_move_y);
6561 cw->render_update_lock.pending_move_x = 0;
6562 cw->render_update_lock.pending_move_y = 0;
6563 cw->render_update_lock.pending_move_set = EINA_FALSE;
6566 if (cw->render_update_lock.pending_resize_set)
6568 evas_object_resize(obj,
6569 cw->render_update_lock.pending_resize_w,
6570 cw->render_update_lock.pending_resize_h);
6571 cw->render_update_lock.pending_resize_w = 0;
6572 cw->render_update_lock.pending_resize_h = 0;
6573 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6576 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6578 if ((cw->ec->exp_iconify.buffer_flush) &&
6579 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6580 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6581 e_comp_object_clear(obj);
6583 e_comp_object_render_update_add(obj);
6585 ELOGF("COMP", "Render update lock disabled", cw->ec);
6590 e_comp_object_render_update_lock_get(Evas_Object *obj)
6592 API_ENTRY EINA_FALSE;
6594 if (cw->render_update_lock.lock > 0)
6601 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6605 if (cw->transparent.set)
6607 if (r) *r = cw->transparent.user_r;
6608 if (g) *g = cw->transparent.user_g;
6609 if (b) *b = cw->transparent.user_b;
6610 if (a) *a = cw->transparent.user_a;
6614 evas_object_color_get(obj, r, g, b, a);