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, E_Comp_Object_Type type)
3742 Evas_Object *o, *z = NULL;
3744 Eina_List *l, *list = NULL;
3745 E_Comp_Config *conf = e_comp_config_get();
3746 Eina_Bool skip = EINA_FALSE, fast = EINA_FALSE, shadow = EINA_FALSE;
3753 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3758 list = conf->match.objects;
3759 skip = conf->match.disable_objects;
3760 fast = conf->fast_objects;
3762 name = evas_object_name_get(obj);
3763 vis = evas_object_visible_get(obj);
3764 o = edje_object_add(e_comp->evas);
3765 evas_object_data_set(o, "comp_object", (void*)1);
3766 if (name && (!skip))
3767 skip = (!strncmp(name, "noshadow", 8));
3769 evas_object_data_set(o, "comp_object_skip", (void*)1);
3772 EINA_LIST_FOREACH(list, l, m)
3774 if (((m->name) && (!name)) ||
3775 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
3777 if (!m->shadow_style) continue;
3780 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
3781 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3785 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
3786 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3790 shadow = !m->no_shadow;
3800 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/none");
3802 if (conf->shadow_style)
3806 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
3807 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3811 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3812 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3817 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default/fast");
3819 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3822 if (shadow && (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow"))))
3823 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3825 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3827 evas_object_geometry_get(obj, &x, &y, &w, &h);
3828 evas_object_geometry_set(o, x, y, w, h);
3829 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3831 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3833 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3834 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3835 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3836 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3837 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3838 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3840 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3842 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3844 _e_comp_object_event_add(o);
3847 evas_object_show(o);
3852 /* utility functions for deleting objects when their "owner" is deleted */
3854 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3859 EINA_SAFETY_ON_NULL_RETURN(to_del);
3860 l = evas_object_data_get(obj, "comp_object-to_del");
3861 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3862 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3863 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3867 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3872 EINA_SAFETY_ON_NULL_RETURN(to_del);
3873 l = evas_object_data_get(obj, "comp_object-to_del");
3875 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3878 /////////////////////////////////////////////////////////
3880 EINTERN Evas_Object *
3881 e_comp_object_client_add(E_Client *ec)
3886 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3887 if (ec->frame) return NULL;
3888 _e_comp_smart_init();
3889 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3890 cw = evas_object_smart_data_get(o);
3891 if (!cw) return NULL;
3892 evas_object_data_set(o, "E_Client", ec);
3895 evas_object_data_set(o, "comp_object", (void*)1);
3897 _e_comp_object_event_add(o);
3902 /* utility functions for getting client inset */
3904 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3907 if (!cw->client_inset.calc)
3913 if (ax) *ax = x - cw->client_inset.l;
3914 if (ay) *ay = y - cw->client_inset.t;
3918 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3921 if (!cw->client_inset.calc)
3927 if (ax) *ax = x + cw->client_inset.l;
3928 if (ay) *ay = y + cw->client_inset.t;
3932 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3935 if (!cw->client_inset.calc)
3941 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3942 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3946 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3949 if (!cw->client_inset.calc)
3955 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3956 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3960 e_comp_object_client_get(Evas_Object *obj)
3965 /* FIXME: remove this when eo is used */
3966 o = evas_object_data_get(obj, "comp_smart_obj");
3968 return e_comp_object_client_get(o);
3969 return cw ? cw->ec : NULL;
3973 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3976 if (cw->frame_extends)
3977 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3982 if (w) *w = cw->ec->w;
3983 if (h) *h = cw->ec->h;
3988 e_comp_object_util_zone_get(Evas_Object *obj)
3990 E_Zone *zone = NULL;
3994 zone = cw->ec->zone;
3999 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4000 zone = e_comp_zone_xy_get(x, y);
4006 e_comp_object_util_center(Evas_Object *obj)
4008 int x, y, w, h, ow, oh;
4013 zone = e_comp_object_util_zone_get(obj);
4014 EINA_SAFETY_ON_NULL_RETURN(zone);
4015 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
4016 if (cw && (cw->ec->changes.size || cw->ec->new_client))
4017 ow = cw->ec->w, oh = cw->ec->h;
4019 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4020 x = x + (w - ow) / 2;
4021 y = y + (h - oh) / 2;
4022 evas_object_move(obj, x, y);
4026 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
4028 int x, y, w, h, ow, oh;
4031 EINA_SAFETY_ON_NULL_RETURN(on);
4032 evas_object_geometry_get(on, &x, &y, &w, &h);
4033 if (cw && (cw->ec->changes.size || cw->ec->new_client))
4034 ow = cw->ec->w, oh = cw->ec->h;
4036 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4037 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
4041 e_comp_object_util_fullscreen(Evas_Object *obj)
4046 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4049 evas_object_move(obj, 0, 0);
4050 evas_object_resize(obj, e_comp->w, e_comp->h);
4055 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4063 ow = cw->w, oh = cw->h;
4065 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4066 zone = e_comp_object_util_zone_get(obj);
4067 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4068 if (x) *x = zx + (zw - ow) / 2;
4069 if (y) *y = zy + (zh - oh) / 2;
4073 e_comp_object_input_objs_del(Evas_Object *obj)
4076 E_Input_Rect_Data *input_rect_data;
4077 E_Input_Rect_Smart_Data *input_rect_sd;
4082 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4083 if (!input_rect_sd) return;
4085 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4087 if (input_rect_data->obj)
4089 evas_object_smart_member_del(input_rect_data->obj);
4090 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4092 E_FREE(input_rect_data);
4097 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4100 E_Input_Rect_Data *input_rect_data = NULL;
4101 E_Input_Rect_Smart_Data *input_rect_sd;
4102 int client_w, client_h;
4104 if (cw->ec->client.w)
4105 client_w = cw->ec->client.w;
4107 client_w = cw->ec->w;
4109 if (cw->ec->client.h)
4110 client_h = cw->ec->client.h;
4112 client_h = cw->ec->h;
4114 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4118 _e_comp_input_obj_smart_init();
4119 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4120 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4121 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4124 input_rect_sd->cw = cw;
4127 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4130 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4131 if (input_rect_data)
4133 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4134 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4138 if ((input_rect_data) &&
4139 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4141 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4142 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4143 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4144 evas_object_clip_set(input_rect_data->obj, cw->clip);
4145 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4146 evas_object_geometry_set(input_rect_data->obj,
4147 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4148 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4149 evas_object_pass_events_set(cw->default_input_obj, 1);
4150 evas_object_pass_events_set(cw->obj, 1);
4153 evas_object_show(input_rect_data->obj);
4154 evas_object_show(cw->input_obj);
4159 evas_object_smart_member_del(cw->input_obj);
4160 E_FREE_FUNC(cw->input_obj, evas_object_del);
4161 evas_object_pass_events_set(cw->default_input_obj, 0);
4162 evas_object_pass_events_set(cw->obj, 0);
4167 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4170 E_Input_Rect_Smart_Data *input_rect_sd;
4171 E_Input_Rect_Data *input_rect_data;
4174 if (!cw->input_obj) return;
4176 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4179 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4181 *list = eina_list_append(*list, &input_rect_data->rect);
4187 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4190 if (l) *l = cw->client_inset.l;
4191 if (r) *r = cw->client_inset.r;
4192 if (t) *t = cw->client_inset.t;
4193 if (b) *b = cw->client_inset.b;
4196 /* set geometry for CSD */
4198 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4204 if (cw->frame_object)
4205 CRI("ACK! ec:%p", cw->ec);
4206 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4207 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4208 calc = cw->client_inset.calc;
4209 cw->client_inset.calc = l || r || t || b;
4210 eina_stringshare_replace(&cw->frame_theme, "borderless");
4211 if (cw->client_inset.calc)
4213 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4214 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4215 e_client_size_set(cw->ec, tw, th);
4217 else if (cw->ec->maximized || cw->ec->fullscreen)
4219 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4220 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4222 if (!cw->ec->new_client)
4224 if (calc && cw->client_inset.calc)
4226 tx = cw->ec->x - (l - cw->client_inset.l);
4227 ty = cw->ec->y - (t - cw->client_inset.t);
4228 e_client_pos_set(cw->ec, tx, ty);
4230 cw->ec->changes.pos = cw->ec->changes.size = 1;
4233 cw->client_inset.l = l;
4234 cw->client_inset.r = r;
4235 cw->client_inset.t = t;
4236 cw->client_inset.b = b;
4240 e_comp_object_frame_allowed(Evas_Object *obj)
4242 API_ENTRY EINA_FALSE;
4243 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4247 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4249 API_ENTRY EINA_FALSE;
4250 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4251 eina_stringshare_replace(&cw->frame_name, name);
4252 if (cw->frame_object)
4253 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4258 e_comp_object_frame_exists(Evas_Object *obj)
4260 API_ENTRY EINA_FALSE;
4261 return !!cw->frame_object;
4265 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4267 Evas_Object *o, *pbg;
4270 Eina_Stringshare *theme;
4272 API_ENTRY EINA_FALSE;
4274 if (!e_util_strcmp(cw->frame_theme, name))
4275 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4276 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4277 return _e_comp_object_shadow_setup(cw);
4278 pbg = cw->frame_object;
4279 theme = eina_stringshare_add(name);
4281 if (cw->frame_object)
4285 w = cw->ec->w, h = cw->ec->h;
4286 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4287 if ((cw->ec->w != w) || (cw->ec->h != h))
4289 cw->ec->changes.size = 1;
4292 E_FREE_FUNC(cw->frame_object, evas_object_del);
4293 if (!name) goto reshadow;
4295 o = edje_object_add(e_comp->evas);
4296 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4297 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4298 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4300 cw->frame_object = NULL;
4302 eina_stringshare_del(cw->frame_theme);
4303 cw->frame_theme = theme;
4308 if (theme != e_config->theme_default_border_style)
4310 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4311 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4315 ok = e_theme_edje_object_set(o, "base/theme/border",
4316 "e/widgets/border/default/border");
4317 if (ok && (theme == e_config->theme_default_border_style))
4319 /* Reset default border style to default */
4320 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4321 e_config_save_queue();
4328 cw->frame_object = o;
4329 eina_stringshare_del(cw->frame_theme);
4330 cw->frame_theme = theme;
4331 evas_object_name_set(o, "cw->frame_object");
4334 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4338 cw->ec->changes.icon = 1;
4344 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4349 _e_comp_object_shadow_setup(cw);
4352 int old_x, old_y, new_x = 0, new_y = 0;
4354 old_x = cw->x, old_y = cw->y;
4356 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4358 new_x = cw->ec->x, new_y = cw->ec->y;
4359 else if (cw->ec->placed || (!cw->ec->new_client))
4361 /* if no previous frame:
4362 * - reapply client_inset
4367 if (cw->ec->changes.size)
4374 x = cw->ec->client.x, y = cw->ec->client.y;
4375 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4376 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4378 new_x = x, new_y = y;
4381 if (old_x != new_x || old_y != new_y)
4383 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4384 cw->y = cw->x = -99999;
4385 evas_object_move(obj, new_x, new_y);
4389 if (cw->ec->maximized)
4391 cw->ec->changes.need_maximize = 1;
4394 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4395 if (cw->frame_object)
4397 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4400 cw->frame_extends = 0;
4401 evas_object_del(pbg);
4406 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4408 E_Comp_Object_Mover *prov;
4411 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4412 edje_object_signal_emit(cw->shobj, sig, src);
4413 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4414 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4415 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4417 /* start with highest priority callback first */
4418 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4420 if (!e_util_glob_match(sig, prov->sig)) continue;
4421 if (prov->func(prov->data, obj, sig)) break;
4426 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4428 /* FIXME: at some point I guess this should use eo to inherit
4429 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4430 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4433 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4437 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4440 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4444 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4447 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4451 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4454 Eina_Rectangle rect;
4457 if (cw->ec->input_only || (!cw->updates)) return;
4458 if (cw->nocomp) return;
4459 rect.x = x, rect.y = y;
4460 rect.w = w, rect.h = h;
4461 evas_object_smart_callback_call(obj, "damage", &rect);
4463 if (e_comp_is_on_overlay(cw->ec))
4465 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4466 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4467 * E module attempts to block screen update due to the particular policy.
4469 if (e_pixmap_resource_get(cw->ec->pixmap))
4470 cw->hwc_need_update = EINA_TRUE;
4473 /* ignore overdraw */
4474 if (cw->updates_full)
4476 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
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 /* clip rect to client surface */
4485 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4486 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4487 /* if rect is the total size of the client after clip, clear the updates
4488 * since this is guaranteed to be the whole region anyway
4490 eina_tiler_area_size_get(cw->updates, &tw, &th);
4491 if ((w > tw) || (h > th))
4493 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4494 eina_tiler_clear(cw->updates);
4495 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4497 tw = cw->ec->client.w, th = cw->ec->client.h;
4499 if ((!x) && (!y) && (w == tw) && (h == th))
4501 eina_tiler_clear(cw->updates);
4502 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4503 cw->updates_full = 1;
4504 cw->update_count = 0;
4507 if (cw->update_count > UPDATE_MAX)
4509 /* this is going to get really dumb, so just update the whole thing */
4510 eina_tiler_clear(cw->updates);
4511 cw->update_count = cw->updates_full = 1;
4512 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4513 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4517 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4518 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4520 cw->updates_exist = 1;
4521 e_comp_object_render_update_add(obj);
4523 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4524 evas_object_show(cw->smart_obj);
4528 e_comp_object_damage_exists(Evas_Object *obj)
4530 API_ENTRY EINA_FALSE;
4531 return cw->updates_exist;
4535 e_comp_object_render_update_add(Evas_Object *obj)
4539 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4540 if (cw->render_update_lock.lock) return;
4541 if (e_object_is_del(E_OBJECT(cw->ec)))
4542 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4543 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4547 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4549 e_comp_render_queue();
4553 e_comp_object_render_update_del(Evas_Object *obj)
4557 if (cw->ec->input_only || (!cw->updates)) return;
4558 if (!cw->update) return;
4560 /* this gets called during comp animating to clear the update flag */
4561 if (e_comp->grabbed) return;
4562 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4563 if (!e_comp->updates)
4565 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4566 if (e_comp->render_animator)
4567 ecore_animator_freeze(e_comp->render_animator);
4572 e_comp_object_shape_apply(Evas_Object *obj)
4576 unsigned int i, *pix, *p;
4580 if (!cw->ec) return; //NYI
4581 if (cw->external_content) return;
4584 if ((cw->ec->shape_rects_num >= 1) &&
4585 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4590 ERR("BUGGER: shape with native surface? cw=%p", cw);
4593 evas_object_image_size_get(cw->obj, &w, &h);
4594 if ((w < 1) || (h < 1)) return;
4597 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4598 _e_comp_object_alpha_set(cw);
4599 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4600 evas_object_image_alpha_set(o, 1);
4602 p = pix = evas_object_image_data_get(cw->obj, 1);
4605 evas_object_image_data_set(cw->obj, pix);
4610 unsigned char *spix, *sp;
4612 spix = calloc(w * h, sizeof(unsigned char));
4614 for (i = 0; i < cw->ec->shape_rects_num; i++)
4618 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4619 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4620 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4621 sp = spix + (w * ry) + rx;
4622 for (py = 0; py < rh; py++)
4624 for (px = 0; px < rw; px++)
4632 for (py = 0; py < h; py++)
4634 for (px = 0; px < w; px++)
4636 unsigned int mask, imask;
4638 mask = ((unsigned int)(*sp)) << 24;
4640 imask |= imask >> 8;
4641 imask |= imask >> 8;
4642 *p = mask | (*p & imask);
4643 //if (*sp) *p = 0xff000000 | *p;
4644 //else *p = 0x00000000;
4653 for (py = 0; py < h; py++)
4655 for (px = 0; px < w; px++)
4659 evas_object_image_data_set(cw->obj, pix);
4660 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4661 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4663 evas_object_image_data_set(o, pix);
4664 evas_object_image_data_update_add(o, 0, 0, w, h);
4666 // don't need to fix alpha chanel as blending
4667 // should be totally off here regardless of
4668 // alpha channel content
4672 _e_comp_object_clear(E_Comp_Object *cw)
4677 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4679 if (cw->render_update_lock.lock) return;
4682 e_pixmap_clear(cw->ec->pixmap);
4684 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4685 evas_object_image_size_set(cw->obj, 1, 1);
4686 evas_object_image_data_set(cw->obj, NULL);
4687 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4689 evas_object_image_size_set(o, 1, 1);
4690 evas_object_image_data_set(o, NULL);
4693 e_comp_object_render_update_del(cw->smart_obj);
4697 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4701 API_ENTRY EINA_FALSE;
4703 if (cw->transparent.set == set)
4708 evas_object_color_get(obj, &r, &g, &b, &a);
4709 evas_object_color_set(obj, 0, 0, 0, 0);
4711 cw->transparent.user_r = r;
4712 cw->transparent.user_g = g;
4713 cw->transparent.user_b = b;
4714 cw->transparent.user_a = a;
4716 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4718 cw->transparent.user_r,
4719 cw->transparent.user_g,
4720 cw->transparent.user_b,
4721 cw->transparent.user_a);
4723 cw->transparent.set = EINA_TRUE;
4727 cw->transparent.set = EINA_FALSE;
4729 evas_object_color_set(obj,
4730 cw->transparent.user_r,
4731 cw->transparent.user_g,
4732 cw->transparent.user_b,
4733 cw->transparent.user_a);
4735 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4737 cw->transparent.user_r,
4738 cw->transparent.user_g,
4739 cw->transparent.user_b,
4740 cw->transparent.user_a);
4746 /* helper function to simplify toggling of redirection for display servers which support it */
4748 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4753 if (cw->redirected == set) return;
4754 cw->redirected = set;
4755 if (cw->external_content) return;
4757 e_comp_object_map_update(obj);
4761 if (cw->updates_exist)
4762 e_comp_object_render_update_add(obj);
4764 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4766 _e_comp_object_transparent_set(obj, EINA_FALSE);
4767 evas_object_smart_callback_call(obj, "redirected", NULL);
4771 _e_comp_object_clear(cw);
4772 _e_comp_object_transparent_set(obj, EINA_TRUE);
4773 evas_object_smart_callback_call(obj, "unredirected", NULL);
4778 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4781 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4783 if (cw->buffer_destroy_listener.notify)
4785 cw->buffer_destroy_listener.notify = NULL;
4786 wl_list_remove(&cw->buffer_destroy_listener.link);
4789 if (e_object_is_del(E_OBJECT(cw->ec)))
4791 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4796 /* if it's current displaying buffer, do not remove its content */
4797 if (!evas_object_visible_get(cw->ec->frame))
4798 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4803 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4808 if (cw->buffer_destroy_listener.notify)
4810 wl_list_remove(&cw->buffer_destroy_listener.link);
4811 cw->buffer_destroy_listener.notify = NULL;
4814 if (cw->tbm_surface)
4816 tbm_surface_internal_unref(cw->tbm_surface);
4817 cw->tbm_surface = NULL;
4822 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4824 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4825 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4827 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4829 tbm_surface_internal_ref(ns->data.tbm.buffer);
4830 cw->tbm_surface = ns->data.tbm.buffer;
4834 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4835 evas_object_image_native_surface_set(cw->obj, ns);
4839 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4841 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4842 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4843 evas_object_image_native_surface_set(o, ns);
4850 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4852 Evas_Native_Surface ns;
4855 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4856 if (cw->ec->input_only) return;
4857 if (cw->external_content) return;
4858 if (cw->render_update_lock.lock) return;
4861 memset(&ns, 0, sizeof(Evas_Native_Surface));
4865 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4866 set = (!cw->ec->shaped);
4868 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4872 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4876 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4879 if (cw->ec->input_only) return;
4882 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4883 _e_comp_object_alpha_set(cw);
4885 e_comp_object_native_surface_set(obj, cw->native);
4886 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4890 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4896 if (cw->blanked == set) return;
4898 _e_comp_object_alpha_set(cw);
4901 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4902 evas_object_image_data_set(cw->obj, NULL);
4906 e_comp_object_native_surface_set(obj, 1);
4907 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4911 _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)
4916 if (!_damage_trace) return;
4920 if (!evas_object_visible_get(cw->obj)) return;
4922 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4924 o = evas_object_rectangle_add(e_comp->evas);
4925 evas_object_layer_set(o, E_LAYER_MAX);
4926 evas_object_name_set(o, "damage_trace");
4927 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4928 evas_object_resize(o, dmg_w, dmg_h);
4929 evas_object_color_set(o, 0, 128, 0, 128);
4930 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4931 evas_object_pass_events_set(o, EINA_TRUE);
4932 evas_object_show(o);
4934 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4936 dmg_w, dmg_h, dmg_x, dmg_y,
4937 origin->w, origin->h, origin->x, origin->y);
4939 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4942 /* mark an object as dirty and setup damages */
4944 e_comp_object_dirty(Evas_Object *obj)
4947 Eina_Rectangle *rect;
4951 Eina_Bool dirty, visible;
4955 if (cw->external_content) return;
4956 if (!cw->redirected) return;
4957 if (cw->render_update_lock.lock)
4959 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4962 /* only actually dirty if pixmap is available */
4963 if (!e_pixmap_resource_get(cw->ec->pixmap))
4965 // e_pixmap_size_get returns last attached buffer size
4966 // eventhough it is destroyed
4967 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4970 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4971 visible = cw->visible;
4972 if (!dirty) w = h = 1;
4973 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4975 evas_object_image_data_set(cw->obj, NULL);
4976 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4977 evas_object_image_size_set(cw->obj, tw, th);
4978 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4979 if (cw->pending_updates)
4980 eina_tiler_area_size_set(cw->pending_updates, w, h);
4981 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4983 evas_object_image_pixels_dirty_set(o, dirty);
4985 evas_object_image_data_set(o, NULL);
4986 evas_object_image_size_set(o, tw, th);
4987 visible |= evas_object_visible_get(o);
4991 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4995 e_comp_object_native_surface_set(obj, 1);
4997 m = _e_comp_object_map_damage_transform_get(cw->ec);
4998 it = eina_tiler_iterator_new(cw->updates);
4999 EINA_ITERATOR_FOREACH(it, rect)
5001 /* evas converts damage according to rotation of ecore_evas in damage_region_set
5002 * of evas engine and doesn't convert damage according to evas_map.
5003 * so damage of evas_object_image use surface coordinate.
5007 int damage_x, damage_y, damage_w, damage_h;
5009 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
5010 &damage_x, &damage_y, &damage_w, &damage_h);
5011 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
5012 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
5016 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
5017 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
5020 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
5021 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
5022 if (cw->pending_updates)
5023 eina_tiler_rect_add(cw->pending_updates, rect);
5025 eina_iterator_free(it);
5026 if (m) e_map_free(m);
5027 if (cw->pending_updates)
5028 eina_tiler_clear(cw->updates);
5031 cw->pending_updates = cw->updates;
5032 cw->updates = eina_tiler_new(w, h);
5033 eina_tiler_tile_size_set(cw->updates, 1, 1);
5035 cw->update_count = cw->updates_full = cw->updates_exist = 0;
5036 evas_object_smart_callback_call(obj, "dirty", NULL);
5037 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
5038 /* force render if main object is hidden but mirrors are visible */
5039 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
5040 e_comp_object_render(obj);
5044 e_comp_object_render(Evas_Object *obj)
5051 API_ENTRY EINA_FALSE;
5053 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5054 if (cw->ec->input_only) return EINA_TRUE;
5055 if (cw->external_content) return EINA_TRUE;
5056 if (cw->native) return EINA_FALSE;
5057 /* if comp object is not redirected state, comp object should not be set by newly committed data
5058 because image size of comp object is 1x1 and it should not be shown on canvas */
5059 if (!cw->redirected) return EINA_TRUE;
5060 if (cw->render_update_lock.lock)
5062 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5065 e_comp_object_render_update_del(obj);
5066 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5068 if (!cw->pending_updates)
5070 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5071 evas_object_image_data_set(cw->obj, NULL);
5072 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5073 evas_object_image_data_set(o, NULL);
5077 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5079 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5081 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5084 e_pixmap_image_refresh(cw->ec->pixmap);
5085 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5088 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5089 e_pixmap_image_data_ref(cw->ec->pixmap);
5091 /* set pixel data */
5092 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5093 _e_comp_object_alpha_set(cw);
5094 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5096 evas_object_image_data_set(o, pix);
5097 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5098 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5101 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5103 e_comp_client_post_update_add(cw->ec);
5108 /* create a duplicate of an evas object */
5109 EINTERN Evas_Object *
5110 e_comp_object_util_mirror_add(Evas_Object *obj)
5114 unsigned int *pix = NULL;
5115 Eina_Bool argb = EINA_FALSE;
5120 cw = evas_object_data_get(obj, "comp_mirror");
5123 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5124 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5125 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5126 evas_object_image_alpha_set(o, 1);
5127 evas_object_image_source_set(o, obj);
5130 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5131 if (cw->external_content)
5133 ERR("%p of client %p is external content.", obj, cw->ec);
5136 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5137 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5138 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5139 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5140 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5141 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5142 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5143 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5144 evas_object_data_set(o, "comp_mirror", cw);
5146 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5147 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5149 evas_object_image_size_set(o, tw, th);
5152 pix = evas_object_image_data_get(cw->obj, 0);
5158 evas_object_image_native_surface_set(o, cw->ns);
5161 Evas_Native_Surface ns;
5162 memset(&ns, 0, sizeof(Evas_Native_Surface));
5163 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5164 evas_object_image_native_surface_set(o, &ns);
5169 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5170 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5172 (e_pixmap_image_exists(cw->ec->pixmap)))
5173 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5175 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5182 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5183 evas_object_image_pixels_dirty_set(o, dirty);
5184 evas_object_image_data_set(o, pix);
5185 evas_object_image_data_set(cw->obj, pix);
5187 evas_object_image_data_update_add(o, 0, 0, tw, th);
5192 //////////////////////////////////////////////////////
5195 e_comp_object_effect_allowed_get(Evas_Object *obj)
5197 API_ENTRY EINA_FALSE;
5199 if (!cw->shobj) return EINA_FALSE;
5200 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5201 return !e_comp_config_get()->match.disable_borders;
5204 /* setup an api effect for a client */
5206 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5209 Eina_Stringshare *grp;
5210 E_Comp_Config *config;
5211 Eina_Bool loaded = EINA_FALSE;
5213 API_ENTRY EINA_FALSE;
5214 if (!cw->shobj) return EINA_FALSE; //input window
5216 if (!effect) effect = "none";
5217 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5219 config = e_comp_config_get();
5220 if ((config) && (config->effect_file))
5222 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5224 cw->effect_set = EINA_TRUE;
5231 edje_object_file_get(cw->effect_obj, NULL, &grp);
5232 cw->effect_set = !eina_streq(effect, "none");
5233 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5234 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5236 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5237 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5238 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5240 if (cw->effect_running)
5242 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5245 cw->effect_set = EINA_FALSE;
5246 return cw->effect_set;
5250 if (cw->effect_running)
5252 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5255 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5256 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5257 if (cw->effect_clip)
5259 evas_object_clip_unset(cw->clip);
5260 cw->effect_clip = 0;
5262 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5264 _e_comp_object_dim_update(cw);
5266 return cw->effect_set;
5269 /* set params for embryo scripts in effect */
5271 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5273 Edje_Message_Int_Set *msg;
5277 EINA_SAFETY_ON_NULL_RETURN(params);
5278 EINA_SAFETY_ON_FALSE_RETURN(count);
5279 if (!cw->effect_set) return;
5281 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5282 msg->count = (int)count;
5283 for (x = 0; x < count; x++)
5284 msg->val[x] = params[x];
5285 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5286 edje_object_message_signal_process(cw->effect_obj);
5290 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5292 Edje_Signal_Cb end_cb;
5294 E_Comp_Object *cw = data;
5296 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5297 cw->effect_running = 0;
5298 if (!_e_comp_object_animating_end(cw)) return;
5300 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5302 evas_object_data_del(cw->smart_obj, "effect_running");
5303 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5304 e_client_visibility_calculate();
5307 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5308 if (!end_cb) return;
5309 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5310 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5311 end_cb(end_data, cw->smart_obj, emission, source);
5314 /* clip effect to client's zone */
5316 e_comp_object_effect_clip(Evas_Object *obj)
5319 if (!cw->ec->zone) return;
5320 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5321 if (!cw->effect_clip_able) return;
5322 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5323 cw->effect_clip = 1;
5326 /* unclip effect from client's zone */
5328 e_comp_object_effect_unclip(Evas_Object *obj)
5331 if (!cw->effect_clip) return;
5332 evas_object_clip_unset(cw->smart_obj);
5333 cw->effect_clip = 0;
5336 /* start effect, running end_cb after */
5338 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5340 API_ENTRY EINA_FALSE;
5341 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5342 if (!cw->effect_set) return EINA_FALSE;
5344 if (cw->effect_running)
5346 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5349 e_comp_object_effect_clip(obj);
5350 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5352 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5353 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5354 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5355 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5357 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5358 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5360 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5361 _e_comp_object_animating_begin(cw);
5362 cw->effect_running = 1;
5366 /* stop a currently-running effect immediately */
5368 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5371 Edje_Signal_Cb end_cb_before = NULL;
5372 void *end_data_before = NULL;
5373 API_ENTRY EINA_FALSE;
5375 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5376 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5378 if (end_cb_before != end_cb) return EINA_TRUE;
5379 e_comp_object_effect_unclip(obj);
5380 if (cw->effect_clip)
5382 evas_object_clip_unset(cw->effect_obj);
5383 cw->effect_clip = 0;
5385 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5386 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5388 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5390 evas_object_data_del(cw->smart_obj, "effect_running");
5391 e_client_visibility_calculate();
5394 cw->effect_running = 0;
5395 ret = _e_comp_object_animating_end(cw);
5397 if ((ret) && (end_cb_before))
5399 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5400 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5407 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5409 return a->pri - b->pri;
5412 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5413 E_API E_Comp_Object_Mover *
5414 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5416 E_Comp_Object_Mover *prov;
5418 prov = E_NEW(E_Comp_Object_Mover, 1);
5419 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5420 prov->func = provider;
5421 prov->data = (void*)data;
5424 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5425 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5430 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5432 EINA_SAFETY_ON_NULL_RETURN(prov);
5433 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5438 e_comp_object_effect_object_get(Evas_Object *obj)
5442 return cw->effect_obj;
5446 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5448 API_ENTRY EINA_FALSE;
5449 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5450 if (!cw->effect_set) return EINA_FALSE;
5457 ////////////////////////////////////
5460 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5462 if (e_comp->autoclose.obj)
5464 e_comp_ungrab_input(0, 1);
5465 if (e_comp->autoclose.del_cb)
5466 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5467 else if (!already_del)
5469 evas_object_hide(e_comp->autoclose.obj);
5470 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5472 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5474 e_comp->autoclose.obj = NULL;
5475 e_comp->autoclose.data = NULL;
5476 e_comp->autoclose.del_cb = NULL;
5477 e_comp->autoclose.key_cb = NULL;
5478 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5482 _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)
5484 _e_comp_object_autoclose_cleanup(0);
5488 _e_comp_object_autoclose_setup(Evas_Object *obj)
5490 if (!e_comp->autoclose.rect)
5492 /* create rect just below autoclose object to catch mouse events */
5493 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5494 evas_object_move(e_comp->autoclose.rect, 0, 0);
5495 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5496 evas_object_show(e_comp->autoclose.rect);
5497 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5498 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5499 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5500 e_comp_grab_input(0, 1);
5502 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5503 evas_object_focus_set(obj, 1);
5507 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5509 _e_comp_object_autoclose_setup(obj);
5510 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5514 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5516 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5517 _e_comp_object_autoclose_cleanup(1);
5518 if (e_client_focused_get()) return;
5519 if (e_config->focus_policy != E_FOCUS_MOUSE)
5524 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5528 if (e_comp->autoclose.obj)
5530 if (e_comp->autoclose.obj == obj) return;
5531 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5532 e_comp->autoclose.obj = obj;
5533 e_comp->autoclose.del_cb = del_cb;
5534 e_comp->autoclose.key_cb = cb;
5535 e_comp->autoclose.data = (void*)data;
5536 if (evas_object_visible_get(obj))
5537 _e_comp_object_autoclose_setup(obj);
5539 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5540 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5543 e_comp->autoclose.obj = obj;
5544 e_comp->autoclose.del_cb = del_cb;
5545 e_comp->autoclose.key_cb = cb;
5546 e_comp->autoclose.data = (void*)data;
5547 if (evas_object_visible_get(obj))
5548 _e_comp_object_autoclose_setup(obj);
5550 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5551 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5555 e_comp_object_is_animating(Evas_Object *obj)
5559 return cw->animating;
5563 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5567 if ((cw->external_content) &&
5568 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5570 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5571 "But current external content is %d object for %p.",
5572 cw->content_type, cw->ec);
5576 cw->user_alpha_set = EINA_TRUE;
5577 cw->user_alpha = alpha;
5579 if (!cw->obj) return;
5581 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5583 evas_object_image_alpha_set(cw->obj, alpha);
5585 if ((!cw->native) && (!cw->external_content))
5586 evas_object_image_data_set(cw->obj, NULL);
5590 e_comp_object_alpha_get(Evas_Object *obj)
5592 API_ENTRY EINA_FALSE;
5594 return evas_object_image_alpha_get(cw->obj);
5598 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5600 Eina_Bool mask_set = EINA_FALSE;
5604 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5605 if (cw->ec->input_only) return;
5612 o = evas_object_rectangle_add(e_comp->evas);
5613 evas_object_color_set(o, 0, 0, 0, 0);
5614 evas_object_clip_set(o, cw->clip);
5615 evas_object_smart_member_add(o, obj);
5616 evas_object_move(o, 0, 0);
5617 evas_object_resize(o, cw->w, cw->h);
5618 /* save render op value to restore when clear a mask.
5620 * NOTE: DO NOT change the render op on ec->frame while mask object
5621 * is set. it will overwrite the changed op value. */
5622 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5623 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5624 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5625 if (cw->visible) evas_object_show(o);
5628 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5629 ELOGF("COMP", " |mask_obj", cw->ec);
5630 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5637 evas_object_smart_member_del(cw->mask.obj);
5638 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5640 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5641 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5647 e_comp_object_mask_has(Evas_Object *obj)
5649 API_ENTRY EINA_FALSE;
5651 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5655 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5660 if ((cw->external_content) &&
5661 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5663 WRN("Can set up size to ONLY evas \"image\" object. "
5664 "But current external content is %d object for %p.",
5665 cw->content_type, cw->ec);
5669 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5671 evas_object_image_size_set(cw->obj, tw, th);
5675 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5677 Eina_Bool transform_set = EINA_FALSE;
5679 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5680 if (cw->ec->input_only) return;
5682 transform_set = !!set;
5686 if (!cw->transform_bg_obj)
5688 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5689 evas_object_move(o, 0, 0);
5690 evas_object_resize(o, 1, 1);
5691 if (cw->transform_bg_color.a >= 255)
5692 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5694 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5695 evas_object_color_set(o,
5696 cw->transform_bg_color.r,
5697 cw->transform_bg_color.g,
5698 cw->transform_bg_color.b,
5699 cw->transform_bg_color.a);
5700 if (cw->visible) evas_object_show(o);
5702 cw->transform_bg_obj = o;
5703 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5705 _e_comp_object_transform_obj_stack_update(obj);
5709 if (cw->transform_bg_obj)
5711 evas_object_smart_member_del(cw->transform_bg_obj);
5712 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5718 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5722 cw->transform_bg_color.r = r;
5723 cw->transform_bg_color.g = g;
5724 cw->transform_bg_color.b = b;
5725 cw->transform_bg_color.a = a;
5727 if (cw->transform_bg_obj)
5729 evas_object_color_set(cw->transform_bg_obj,
5730 cw->transform_bg_color.r,
5731 cw->transform_bg_color.g,
5732 cw->transform_bg_color.b,
5733 cw->transform_bg_color.a);
5738 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5741 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5742 if (cw->ec->input_only) return;
5743 if (!cw->transform_bg_obj) return;
5745 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5749 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5752 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5753 if (cw->ec->input_only) return;
5754 if (!cw->transform_bg_obj) return;
5756 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5760 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5762 Eina_Bool transform_set = EINA_FALSE;
5764 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5765 if (cw->ec->input_only) return;
5767 transform_set = !!set;
5771 if (!cw->transform_tranp_obj)
5773 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5774 evas_object_move(o, 0, 0);
5775 evas_object_resize(o, 1, 1);
5776 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5777 evas_object_color_set(o, 0, 0, 0, 0);
5778 if (cw->visible) evas_object_show(o);
5780 cw->transform_tranp_obj = o;
5781 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5783 _e_comp_object_transform_obj_stack_update(obj);
5787 if (cw->transform_tranp_obj)
5789 evas_object_smart_member_del(cw->transform_tranp_obj);
5790 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5796 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5799 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5800 if (cw->ec->input_only) return;
5801 if (!cw->transform_tranp_obj) return;
5803 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5807 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5810 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5811 if (cw->ec->input_only) return;
5812 if (!cw->transform_tranp_obj) return;
5814 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5818 e_comp_object_layer_update(Evas_Object *obj,
5819 Evas_Object *above, Evas_Object *below)
5821 E_Comp_Object *cw2 = NULL;
5822 Evas_Object *o = NULL;
5827 if (cw->ec->layer_block) return;
5828 if ((above) && (below))
5830 ERR("Invalid layer update request! cw=%p", cw);
5838 layer = evas_object_layer_get(o);
5839 cw2 = evas_object_data_get(o, "comp_obj");
5842 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5844 o = evas_object_above_get(o);
5845 if ((!o) || (o == cw->smart_obj)) break;
5846 if (evas_object_layer_get(o) != layer)
5848 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5853 ec = e_client_top_get();
5854 if (ec) o = ec->frame;
5857 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5861 _e_comp_object_layers_remove(cw);
5864 if (cw2->layer > cw->layer)
5865 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5866 else if (cw2->layer == cw->layer)
5869 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5871 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5873 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5876 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5879 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5883 e_comp_object_layer_get(Evas_Object *obj)
5890 e_comp_object_content_set(Evas_Object *obj,
5891 Evas_Object *content,
5892 E_Comp_Object_Content_Type type)
5894 API_ENTRY EINA_FALSE;
5896 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5897 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5898 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5902 ERR("Can't set e.swallow.content to requested content. "
5903 "Previous comp object should not be changed at all.");
5907 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5909 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5910 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5912 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5913 type, content, cw->ec, cw->ec->pixmap);
5917 cw->external_content = EINA_TRUE;
5920 cw->content_type = type;
5921 e_util_size_debug_set(cw->obj, 1);
5922 evas_object_name_set(cw->obj, "cw->obj");
5923 _e_comp_object_alpha_set(cw);
5926 _e_comp_object_shadow_setup(cw);
5932 e_comp_object_content_unset(Evas_Object *obj)
5934 API_ENTRY EINA_FALSE;
5936 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5937 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5939 if (!cw->obj && !cw->ec->visible)
5941 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5945 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5947 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5953 if (cw->frame_object)
5954 edje_object_part_unswallow(cw->frame_object, cw->obj);
5956 edje_object_part_unswallow(cw->shobj, cw->obj);
5958 evas_object_del(cw->obj);
5959 evas_object_hide(cw->obj);
5963 cw->external_content = EINA_FALSE;
5964 if (cw->ec->is_cursor)
5967 DBG("%p is cursor surface..", cw->ec);
5968 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5970 evas_object_resize(cw->ec->frame, pw, ph);
5971 evas_object_hide(cw->ec->frame);
5976 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5977 cw->obj = evas_object_image_filled_add(e_comp->evas);
5978 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5979 e_util_size_debug_set(cw->obj, 1);
5980 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5981 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5982 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5983 evas_object_name_set(cw->obj, "cw->obj");
5984 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5985 _e_comp_object_alpha_set(cw);
5988 _e_comp_object_shadow_setup(cw);
5993 _e_comp_intercept_show_helper(cw);
5997 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5998 e_comp_object_dirty(cw->smart_obj);
5999 e_comp_object_render(cw->smart_obj);
6000 e_comp_object_render_update_add(obj);
6005 EINTERN Evas_Object *
6006 e_comp_object_content_get(Evas_Object *obj)
6010 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
6012 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
6014 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
6021 E_API E_Comp_Object_Content_Type
6022 e_comp_object_content_type_get(Evas_Object *obj)
6024 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
6026 return cw->content_type;
6030 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
6033 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6034 E_Comp_Config *conf = e_comp_config_get();
6035 if (cw->ec->input_only) return;
6036 if (!conf->dim_rect_enable) return;
6038 cw->dim.mask_set = mask_set;
6044 if (!cw->dim.enable) return;
6045 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6049 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6051 Eina_Bool mask_set = EINA_FALSE;
6055 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6056 E_Comp_Config *conf = e_comp_config_get();
6057 if (cw->ec->input_only) return;
6058 if (!conf->dim_rect_enable) return;
6064 if (cw->dim.mask_obj)
6066 evas_object_smart_member_del(cw->dim.mask_obj);
6067 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6070 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);
6071 o = evas_object_rectangle_add(e_comp->evas);
6072 evas_object_color_set(o, 0, 0, 0, 0);
6073 evas_object_smart_member_add(o, obj);
6074 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6075 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6077 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6078 if (cw->visible) evas_object_show(o);
6080 cw->dim.mask_obj = o;
6081 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6083 evas_object_layer_set(cw->dim.mask_obj, 9998);
6087 if (cw->dim.mask_obj)
6089 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6090 evas_object_smart_member_del(cw->dim.mask_obj);
6091 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6097 e_comp_object_dim_client_set(E_Client *ec)
6099 E_Comp_Config *conf = e_comp_config_get();
6101 if (!conf->dim_rect_enable) return ;
6102 if (dim_client == ec) return;
6104 Eina_Bool prev_dim = EINA_FALSE;
6105 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6107 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6108 prev_dim = EINA_TRUE;
6110 if (prev_dim && dim_client->visible && ec)
6112 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6113 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6117 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6118 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6124 e_comp_object_dim_client_get(void)
6126 E_Comp_Config *conf = e_comp_config_get();
6128 if (!conf->dim_rect_enable ) return NULL;
6134 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6137 char emit[32] = "\0";
6138 E_Comp_Config *conf = e_comp_config_get();
6141 if (!conf->dim_rect_enable) return;
6142 if (!cw->effect_obj) return;
6143 if (enable == cw->dim.enable) return;
6145 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6146 if (noeffect || !conf->dim_rect_effect)
6148 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6152 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6155 cw->dim.enable = enable;
6157 if (cw->dim.mask_set && !enable)
6159 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6160 edje_object_signal_emit(cw->effect_obj, emit, "e");
6162 else if (cw->dim.mask_set && enable)
6164 edje_object_signal_emit(cw->effect_obj, emit, "e");
6165 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6169 edje_object_signal_emit(cw->effect_obj, emit, "e");
6174 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6176 API_ENTRY EINA_FALSE;
6177 E_Comp_Config *conf = e_comp_config_get();
6179 if (!ec) return EINA_FALSE;
6180 if (!conf->dim_rect_enable) return EINA_FALSE;
6182 if (cw->dim.enable) return EINA_TRUE;
6188 _e_comp_object_dim_update(E_Comp_Object *cw)
6190 E_Comp_Config *conf = e_comp_config_get();
6193 if (!conf->dim_rect_enable) return;
6194 if (!cw->effect_obj) return;
6197 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6198 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6200 if (cw->dim.mask_set)
6202 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6208 e_comp_object_clear(Evas_Object *obj)
6212 _e_comp_object_clear(cw);
6216 e_comp_object_hwc_update_exists(Evas_Object *obj)
6218 API_ENTRY EINA_FALSE;
6219 return cw->hwc_need_update;
6224 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6227 cw->hwc_need_update = set;
6231 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6233 API_ENTRY EINA_FALSE;
6234 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6238 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6241 if (cw->indicator.obj != indicator)
6242 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6243 cw->indicator.obj = indicator;
6244 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6248 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6251 if (cw->indicator.obj != indicator) return;
6252 cw->indicator.obj = NULL;
6253 edje_object_part_unswallow(cw->shobj, indicator);
6257 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6260 Edje_Message_Int_Set *msg;
6262 if (!cw->indicator.obj) return;
6264 cw->indicator.w = w;
6265 cw->indicator.h = h;
6267 if (!cw->shobj) return;
6269 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6273 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6274 edje_object_message_signal_process(cw->shobj);
6277 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6279 e_comp_object_map_update(Evas_Object *obj)
6282 E_Client *ec = cw->ec;
6283 E_Comp_Wl_Client_Data *cdata;
6285 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6288 int l, remain = sizeof buffer;
6291 if (e_object_is_del(E_OBJECT(ec))) return;
6292 cdata = e_client_cdata_get(ec);
6295 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6296 * when new buffer is attached.
6298 if (!cdata->buffer_ref.buffer) return;
6300 if ((!cw->redirected) ||
6301 (e_client_video_hw_composition_check(ec)) ||
6302 (!e_comp_wl_output_buffer_transform_get(ec) &&
6303 cdata->scaler.buffer_viewport.buffer.scale == 1))
6305 if (evas_object_map_enable_get(cw->effect_obj))
6307 ELOGF("TRANSFORM", "map: disable", cw->ec);
6308 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6309 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6310 evas_object_resize(cw->effect_obj, tw, th);
6317 EINA_SAFETY_ON_NULL_RETURN(map);
6319 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6325 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6327 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6328 e_map_point_image_uv_set(map, 0, x, y);
6329 l = snprintf(p, remain, "%d,%d", x, y);
6330 p += l, remain -= l;
6332 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6333 e_map_point_image_uv_set(map, 1, x, y);
6334 l = snprintf(p, remain, " %d,%d", x, y);
6335 p += l, remain -= l;
6337 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6338 e_map_point_image_uv_set(map, 2, x, y);
6339 l = snprintf(p, remain, " %d,%d", x, y);
6340 p += l, remain -= l;
6342 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6343 e_map_point_image_uv_set(map, 3, x, y);
6344 l = snprintf(p, remain, " %d,%d", x, y);
6345 p += l, remain -= l;
6347 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6349 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6351 e_comp_object_map_set(cw->effect_obj, map);
6352 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6356 /* if there's screen rotation with comp mode, then ec->effect_obj and
6357 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6359 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6360 evas_object_resize(cw->effect_obj, tw, th);
6364 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6366 API_ENTRY EINA_FALSE;
6368 cw->render_trace = set;
6374 e_comp_object_native_usable_get(Evas_Object *obj)
6376 API_ENTRY EINA_FALSE;
6377 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6379 if (cw->ec->input_only) return EINA_FALSE;
6380 if (cw->external_content) return EINA_FALSE;
6381 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6383 /* just return true value, if it is normal case */
6384 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6387 Evas_Native_Surface *ns;
6388 ns = evas_object_image_native_surface_get(cw->obj);
6390 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6393 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6401 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6403 API_ENTRY EINA_FALSE;
6404 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6405 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6406 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6410 case E_COMP_IMAGE_FILTER_BLUR:
6411 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6413 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6414 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6416 case E_COMP_IMAGE_FILTER_INVERSE:
6417 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6419 case E_COMP_IMAGE_FILTER_NONE:
6421 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6425 cw->image_filter = filter;
6430 EINTERN E_Comp_Image_Filter
6431 e_comp_object_image_filter_get(Evas_Object *obj)
6433 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6434 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6435 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6436 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6438 return cw->image_filter;
6442 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6446 if (!_damage_trace) return;
6448 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6449 evas_object_del(obj);
6451 _damage_trace_post_objs = NULL;
6455 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6457 if (!_damage_trace) return;
6459 _damage_trace_post_objs = _damage_trace_objs;
6460 _damage_trace_objs = NULL;
6464 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6466 if (_damage_trace == onoff) return;
6470 evas_event_callback_add(e_comp->evas,
6471 EVAS_CALLBACK_RENDER_PRE,
6472 _e_comp_object_damage_trace_render_pre_cb,
6475 evas_event_callback_add(e_comp->evas,
6476 EVAS_CALLBACK_RENDER_POST,
6477 _e_comp_object_damage_trace_render_post_cb,
6484 EINA_LIST_FREE(_damage_trace_objs, obj)
6485 evas_object_del(obj);
6487 _damage_trace_objs = NULL;
6489 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6490 evas_object_del(obj);
6492 _damage_trace_post_objs = NULL;
6494 evas_event_callback_del(e_comp->evas,
6495 EVAS_CALLBACK_RENDER_PRE,
6496 _e_comp_object_damage_trace_render_pre_cb);
6498 evas_event_callback_del(e_comp->evas,
6499 EVAS_CALLBACK_RENDER_POST,
6500 _e_comp_object_damage_trace_render_post_cb);
6503 _damage_trace = onoff;
6507 e_comp_object_redirected_get(Evas_Object *obj)
6509 API_ENTRY EINA_FALSE;
6510 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6512 return cw->redirected;
6516 e_comp_object_color_visible_get(Evas_Object *obj)
6518 API_ENTRY EINA_FALSE;
6521 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6523 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6527 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6531 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6535 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6543 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6545 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6547 return e_map_set_to_comp_object(em, obj);
6551 e_comp_object_map_get(const Evas_Object *obj)
6553 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6555 return e_map_get_from_comp_object(obj);
6559 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6561 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6563 evas_object_map_enable_set(obj, enable);
6569 e_comp_object_render_update_lock(Evas_Object *obj)
6571 API_ENTRY EINA_FALSE;
6573 if (cw->render_update_lock.lock == 0)
6575 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6576 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6577 e_pixmap_resource_get(cw->ec->pixmap));
6578 e_comp_object_render_update_del(obj);
6579 ELOGF("COMP", "Render update lock enabled", cw->ec);
6582 cw->render_update_lock.lock++;
6588 e_comp_object_render_update_unlock(Evas_Object *obj)
6592 if (cw->render_update_lock.lock == 0)
6595 cw->render_update_lock.lock--;
6597 if (cw->render_update_lock.lock == 0)
6600 if (cw->render_update_lock.pending_move_set)
6602 evas_object_move(obj,
6603 cw->render_update_lock.pending_move_x,
6604 cw->render_update_lock.pending_move_y);
6605 cw->render_update_lock.pending_move_x = 0;
6606 cw->render_update_lock.pending_move_y = 0;
6607 cw->render_update_lock.pending_move_set = EINA_FALSE;
6610 if (cw->render_update_lock.pending_resize_set)
6612 evas_object_resize(obj,
6613 cw->render_update_lock.pending_resize_w,
6614 cw->render_update_lock.pending_resize_h);
6615 cw->render_update_lock.pending_resize_w = 0;
6616 cw->render_update_lock.pending_resize_h = 0;
6617 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6620 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6622 if ((cw->ec->exp_iconify.buffer_flush) &&
6623 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6624 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6625 e_comp_object_clear(obj);
6627 e_comp_object_render_update_add(obj);
6629 ELOGF("COMP", "Render update lock disabled", cw->ec);
6634 e_comp_object_render_update_lock_get(Evas_Object *obj)
6636 API_ENTRY EINA_FALSE;
6638 if (cw->render_update_lock.lock > 0)
6645 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6649 if (cw->transparent.set)
6651 if (r) *r = cw->transparent.user_r;
6652 if (g) *g = cw->transparent.user_g;
6653 if (b) *b = cw->transparent.user_b;
6654 if (a) *a = cw->transparent.user_a;
6658 evas_object_color_get(obj, r, g, b, a);