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);
3757 case E_COMP_OBJECT_TYPE_POPUP:
3758 list = conf->match.popups;
3759 skip = conf->match.disable_popups;
3760 fast = conf->fast_popups;
3763 list = conf->match.objects;
3764 skip = conf->match.disable_objects;
3765 fast = conf->fast_objects;
3767 name = evas_object_name_get(obj);
3768 vis = evas_object_visible_get(obj);
3769 o = edje_object_add(e_comp->evas);
3770 evas_object_data_set(o, "comp_object", (void*)1);
3771 if (name && (!skip))
3772 skip = (!strncmp(name, "noshadow", 8));
3774 evas_object_data_set(o, "comp_object_skip", (void*)1);
3777 EINA_LIST_FOREACH(list, l, m)
3779 if (((m->name) && (!name)) ||
3780 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
3782 if (!m->shadow_style) continue;
3785 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
3786 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3790 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
3791 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3795 shadow = !m->no_shadow;
3805 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/none");
3807 if (conf->shadow_style)
3811 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
3812 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3816 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3817 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3822 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default/fast");
3824 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3827 if (shadow && (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow"))))
3828 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3830 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3832 evas_object_geometry_get(obj, &x, &y, &w, &h);
3833 evas_object_geometry_set(o, x, y, w, h);
3834 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3836 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3838 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3839 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3840 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3841 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3842 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3843 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3845 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3847 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3849 _e_comp_object_event_add(o);
3852 evas_object_show(o);
3857 /* utility functions for deleting objects when their "owner" is deleted */
3859 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3864 EINA_SAFETY_ON_NULL_RETURN(to_del);
3865 l = evas_object_data_get(obj, "comp_object-to_del");
3866 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3867 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3868 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3872 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3877 EINA_SAFETY_ON_NULL_RETURN(to_del);
3878 l = evas_object_data_get(obj, "comp_object-to_del");
3880 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3883 /////////////////////////////////////////////////////////
3885 EINTERN Evas_Object *
3886 e_comp_object_client_add(E_Client *ec)
3891 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3892 if (ec->frame) return NULL;
3893 _e_comp_smart_init();
3894 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3895 cw = evas_object_smart_data_get(o);
3896 if (!cw) return NULL;
3897 evas_object_data_set(o, "E_Client", ec);
3900 evas_object_data_set(o, "comp_object", (void*)1);
3902 _e_comp_object_event_add(o);
3907 /* utility functions for getting client inset */
3909 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3912 if (!cw->client_inset.calc)
3918 if (ax) *ax = x - cw->client_inset.l;
3919 if (ay) *ay = y - cw->client_inset.t;
3923 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3926 if (!cw->client_inset.calc)
3932 if (ax) *ax = x + cw->client_inset.l;
3933 if (ay) *ay = y + cw->client_inset.t;
3937 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3940 if (!cw->client_inset.calc)
3946 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3947 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3951 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3954 if (!cw->client_inset.calc)
3960 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3961 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3965 e_comp_object_client_get(Evas_Object *obj)
3970 /* FIXME: remove this when eo is used */
3971 o = evas_object_data_get(obj, "comp_smart_obj");
3973 return e_comp_object_client_get(o);
3974 return cw ? cw->ec : NULL;
3978 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3981 if (cw->frame_extends)
3982 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3987 if (w) *w = cw->ec->w;
3988 if (h) *h = cw->ec->h;
3993 e_comp_object_util_zone_get(Evas_Object *obj)
3995 E_Zone *zone = NULL;
3999 zone = cw->ec->zone;
4004 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4005 zone = e_comp_zone_xy_get(x, y);
4011 e_comp_object_util_center(Evas_Object *obj)
4013 int x, y, w, h, ow, oh;
4018 zone = e_comp_object_util_zone_get(obj);
4019 EINA_SAFETY_ON_NULL_RETURN(zone);
4020 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
4021 if (cw && (cw->ec->changes.size || cw->ec->new_client))
4022 ow = cw->ec->w, oh = cw->ec->h;
4024 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4025 x = x + (w - ow) / 2;
4026 y = y + (h - oh) / 2;
4027 evas_object_move(obj, x, y);
4031 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
4033 int x, y, w, h, ow, oh;
4036 EINA_SAFETY_ON_NULL_RETURN(on);
4037 evas_object_geometry_get(on, &x, &y, &w, &h);
4038 if (cw && (cw->ec->changes.size || cw->ec->new_client))
4039 ow = cw->ec->w, oh = cw->ec->h;
4041 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4042 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
4046 e_comp_object_util_fullscreen(Evas_Object *obj)
4051 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4054 evas_object_move(obj, 0, 0);
4055 evas_object_resize(obj, e_comp->w, e_comp->h);
4060 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4068 ow = cw->w, oh = cw->h;
4070 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4071 zone = e_comp_object_util_zone_get(obj);
4072 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4073 if (x) *x = zx + (zw - ow) / 2;
4074 if (y) *y = zy + (zh - oh) / 2;
4078 e_comp_object_input_objs_del(Evas_Object *obj)
4081 E_Input_Rect_Data *input_rect_data;
4082 E_Input_Rect_Smart_Data *input_rect_sd;
4087 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4088 if (!input_rect_sd) return;
4090 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4092 if (input_rect_data->obj)
4094 evas_object_smart_member_del(input_rect_data->obj);
4095 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4097 E_FREE(input_rect_data);
4102 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4105 E_Input_Rect_Data *input_rect_data = NULL;
4106 E_Input_Rect_Smart_Data *input_rect_sd;
4107 int client_w, client_h;
4109 if (cw->ec->client.w)
4110 client_w = cw->ec->client.w;
4112 client_w = cw->ec->w;
4114 if (cw->ec->client.h)
4115 client_h = cw->ec->client.h;
4117 client_h = cw->ec->h;
4119 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4123 _e_comp_input_obj_smart_init();
4124 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4125 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4126 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4129 input_rect_sd->cw = cw;
4132 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4135 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4136 if (input_rect_data)
4138 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4139 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4143 if ((input_rect_data) &&
4144 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4146 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4147 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4148 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4149 evas_object_clip_set(input_rect_data->obj, cw->clip);
4150 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4151 evas_object_geometry_set(input_rect_data->obj,
4152 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4153 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4154 evas_object_pass_events_set(cw->default_input_obj, 1);
4155 evas_object_pass_events_set(cw->obj, 1);
4158 evas_object_show(input_rect_data->obj);
4159 evas_object_show(cw->input_obj);
4164 evas_object_smart_member_del(cw->input_obj);
4165 E_FREE_FUNC(cw->input_obj, evas_object_del);
4166 evas_object_pass_events_set(cw->default_input_obj, 0);
4167 evas_object_pass_events_set(cw->obj, 0);
4172 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4175 E_Input_Rect_Smart_Data *input_rect_sd;
4176 E_Input_Rect_Data *input_rect_data;
4179 if (!cw->input_obj) return;
4181 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4184 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4186 *list = eina_list_append(*list, &input_rect_data->rect);
4192 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4195 if (l) *l = cw->client_inset.l;
4196 if (r) *r = cw->client_inset.r;
4197 if (t) *t = cw->client_inset.t;
4198 if (b) *b = cw->client_inset.b;
4201 /* set geometry for CSD */
4203 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4209 if (cw->frame_object)
4210 CRI("ACK! ec:%p", cw->ec);
4211 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4212 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4213 calc = cw->client_inset.calc;
4214 cw->client_inset.calc = l || r || t || b;
4215 eina_stringshare_replace(&cw->frame_theme, "borderless");
4216 if (cw->client_inset.calc)
4218 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4219 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4220 e_client_size_set(cw->ec, tw, th);
4222 else if (cw->ec->maximized || cw->ec->fullscreen)
4224 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4225 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4227 if (!cw->ec->new_client)
4229 if (calc && cw->client_inset.calc)
4231 tx = cw->ec->x - (l - cw->client_inset.l);
4232 ty = cw->ec->y - (t - cw->client_inset.t);
4233 e_client_pos_set(cw->ec, tx, ty);
4235 cw->ec->changes.pos = cw->ec->changes.size = 1;
4238 cw->client_inset.l = l;
4239 cw->client_inset.r = r;
4240 cw->client_inset.t = t;
4241 cw->client_inset.b = b;
4245 e_comp_object_frame_allowed(Evas_Object *obj)
4247 API_ENTRY EINA_FALSE;
4248 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4252 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4254 API_ENTRY EINA_FALSE;
4255 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4256 eina_stringshare_replace(&cw->frame_name, name);
4257 if (cw->frame_object)
4258 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4263 e_comp_object_frame_exists(Evas_Object *obj)
4265 API_ENTRY EINA_FALSE;
4266 return !!cw->frame_object;
4270 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4272 Evas_Object *o, *pbg;
4275 Eina_Stringshare *theme;
4277 API_ENTRY EINA_FALSE;
4279 if (!e_util_strcmp(cw->frame_theme, name))
4280 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4281 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4282 return _e_comp_object_shadow_setup(cw);
4283 pbg = cw->frame_object;
4284 theme = eina_stringshare_add(name);
4286 if (cw->frame_object)
4290 w = cw->ec->w, h = cw->ec->h;
4291 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4292 if ((cw->ec->w != w) || (cw->ec->h != h))
4294 cw->ec->changes.size = 1;
4297 E_FREE_FUNC(cw->frame_object, evas_object_del);
4298 if (!name) goto reshadow;
4300 o = edje_object_add(e_comp->evas);
4301 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4302 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4303 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4305 cw->frame_object = NULL;
4307 eina_stringshare_del(cw->frame_theme);
4308 cw->frame_theme = theme;
4313 if (theme != e_config->theme_default_border_style)
4315 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4316 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4320 ok = e_theme_edje_object_set(o, "base/theme/border",
4321 "e/widgets/border/default/border");
4322 if (ok && (theme == e_config->theme_default_border_style))
4324 /* Reset default border style to default */
4325 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4326 e_config_save_queue();
4333 cw->frame_object = o;
4334 eina_stringshare_del(cw->frame_theme);
4335 cw->frame_theme = theme;
4336 evas_object_name_set(o, "cw->frame_object");
4339 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4343 cw->ec->changes.icon = 1;
4349 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4354 _e_comp_object_shadow_setup(cw);
4357 int old_x, old_y, new_x = 0, new_y = 0;
4359 old_x = cw->x, old_y = cw->y;
4361 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4363 new_x = cw->ec->x, new_y = cw->ec->y;
4364 else if (cw->ec->placed || (!cw->ec->new_client))
4366 /* if no previous frame:
4367 * - reapply client_inset
4372 if (cw->ec->changes.size)
4379 x = cw->ec->client.x, y = cw->ec->client.y;
4380 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4381 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4383 new_x = x, new_y = y;
4386 if (old_x != new_x || old_y != new_y)
4388 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4389 cw->y = cw->x = -99999;
4390 evas_object_move(obj, new_x, new_y);
4394 if (cw->ec->maximized)
4396 cw->ec->changes.need_maximize = 1;
4399 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4400 if (cw->frame_object)
4402 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4405 cw->frame_extends = 0;
4406 evas_object_del(pbg);
4411 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4413 E_Comp_Object_Mover *prov;
4416 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4417 edje_object_signal_emit(cw->shobj, sig, src);
4418 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4419 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4420 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4422 /* start with highest priority callback first */
4423 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4425 if (!e_util_glob_match(sig, prov->sig)) continue;
4426 if (prov->func(prov->data, obj, sig)) break;
4431 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4433 /* FIXME: at some point I guess this should use eo to inherit
4434 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4435 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4438 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4442 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4445 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4449 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4452 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4456 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4459 Eina_Rectangle rect;
4462 if (cw->ec->input_only || (!cw->updates)) return;
4463 if (cw->nocomp) return;
4464 rect.x = x, rect.y = y;
4465 rect.w = w, rect.h = h;
4466 evas_object_smart_callback_call(obj, "damage", &rect);
4468 if (e_comp_is_on_overlay(cw->ec))
4470 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4471 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4472 * E module attempts to block screen update due to the particular policy.
4474 if (e_pixmap_resource_get(cw->ec->pixmap))
4475 cw->hwc_need_update = EINA_TRUE;
4478 /* ignore overdraw */
4479 if (cw->updates_full)
4481 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4482 e_comp_object_render_update_add(obj);
4484 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4485 evas_object_show(cw->smart_obj);
4489 /* clip rect to client surface */
4490 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4491 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4492 /* if rect is the total size of the client after clip, clear the updates
4493 * since this is guaranteed to be the whole region anyway
4495 eina_tiler_area_size_get(cw->updates, &tw, &th);
4496 if ((w > tw) || (h > th))
4498 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4499 eina_tiler_clear(cw->updates);
4500 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4502 tw = cw->ec->client.w, th = cw->ec->client.h;
4504 if ((!x) && (!y) && (w == tw) && (h == th))
4506 eina_tiler_clear(cw->updates);
4507 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4508 cw->updates_full = 1;
4509 cw->update_count = 0;
4512 if (cw->update_count > UPDATE_MAX)
4514 /* this is going to get really dumb, so just update the whole thing */
4515 eina_tiler_clear(cw->updates);
4516 cw->update_count = cw->updates_full = 1;
4517 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4518 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4522 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4523 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4525 cw->updates_exist = 1;
4526 e_comp_object_render_update_add(obj);
4528 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4529 evas_object_show(cw->smart_obj);
4533 e_comp_object_damage_exists(Evas_Object *obj)
4535 API_ENTRY EINA_FALSE;
4536 return cw->updates_exist;
4540 e_comp_object_render_update_add(Evas_Object *obj)
4544 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4545 if (cw->render_update_lock.lock) return;
4546 if (e_object_is_del(E_OBJECT(cw->ec)))
4547 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4548 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4552 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4554 e_comp_render_queue();
4558 e_comp_object_render_update_del(Evas_Object *obj)
4562 if (cw->ec->input_only || (!cw->updates)) return;
4563 if (!cw->update) return;
4565 /* this gets called during comp animating to clear the update flag */
4566 if (e_comp->grabbed) return;
4567 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4568 if (!e_comp->updates)
4570 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4571 if (e_comp->render_animator)
4572 ecore_animator_freeze(e_comp->render_animator);
4577 e_comp_object_shape_apply(Evas_Object *obj)
4581 unsigned int i, *pix, *p;
4585 if (!cw->ec) return; //NYI
4586 if (cw->external_content) return;
4589 if ((cw->ec->shape_rects_num >= 1) &&
4590 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4595 ERR("BUGGER: shape with native surface? cw=%p", cw);
4598 evas_object_image_size_get(cw->obj, &w, &h);
4599 if ((w < 1) || (h < 1)) return;
4602 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4603 _e_comp_object_alpha_set(cw);
4604 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4605 evas_object_image_alpha_set(o, 1);
4607 p = pix = evas_object_image_data_get(cw->obj, 1);
4610 evas_object_image_data_set(cw->obj, pix);
4615 unsigned char *spix, *sp;
4617 spix = calloc(w * h, sizeof(unsigned char));
4619 for (i = 0; i < cw->ec->shape_rects_num; i++)
4623 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4624 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4625 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4626 sp = spix + (w * ry) + rx;
4627 for (py = 0; py < rh; py++)
4629 for (px = 0; px < rw; px++)
4637 for (py = 0; py < h; py++)
4639 for (px = 0; px < w; px++)
4641 unsigned int mask, imask;
4643 mask = ((unsigned int)(*sp)) << 24;
4645 imask |= imask >> 8;
4646 imask |= imask >> 8;
4647 *p = mask | (*p & imask);
4648 //if (*sp) *p = 0xff000000 | *p;
4649 //else *p = 0x00000000;
4658 for (py = 0; py < h; py++)
4660 for (px = 0; px < w; px++)
4664 evas_object_image_data_set(cw->obj, pix);
4665 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4666 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4668 evas_object_image_data_set(o, pix);
4669 evas_object_image_data_update_add(o, 0, 0, w, h);
4671 // don't need to fix alpha chanel as blending
4672 // should be totally off here regardless of
4673 // alpha channel content
4677 _e_comp_object_clear(E_Comp_Object *cw)
4682 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4684 if (cw->render_update_lock.lock) return;
4687 e_pixmap_clear(cw->ec->pixmap);
4689 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4690 evas_object_image_size_set(cw->obj, 1, 1);
4691 evas_object_image_data_set(cw->obj, NULL);
4692 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4694 evas_object_image_size_set(o, 1, 1);
4695 evas_object_image_data_set(o, NULL);
4698 e_comp_object_render_update_del(cw->smart_obj);
4702 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4706 API_ENTRY EINA_FALSE;
4708 if (cw->transparent.set == set)
4713 evas_object_color_get(obj, &r, &g, &b, &a);
4714 evas_object_color_set(obj, 0, 0, 0, 0);
4716 cw->transparent.user_r = r;
4717 cw->transparent.user_g = g;
4718 cw->transparent.user_b = b;
4719 cw->transparent.user_a = a;
4721 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4723 cw->transparent.user_r,
4724 cw->transparent.user_g,
4725 cw->transparent.user_b,
4726 cw->transparent.user_a);
4728 cw->transparent.set = EINA_TRUE;
4732 cw->transparent.set = EINA_FALSE;
4734 evas_object_color_set(obj,
4735 cw->transparent.user_r,
4736 cw->transparent.user_g,
4737 cw->transparent.user_b,
4738 cw->transparent.user_a);
4740 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4742 cw->transparent.user_r,
4743 cw->transparent.user_g,
4744 cw->transparent.user_b,
4745 cw->transparent.user_a);
4751 /* helper function to simplify toggling of redirection for display servers which support it */
4753 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4758 if (cw->redirected == set) return;
4759 cw->redirected = set;
4760 if (cw->external_content) return;
4762 e_comp_object_map_update(obj);
4766 if (cw->updates_exist)
4767 e_comp_object_render_update_add(obj);
4769 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4771 _e_comp_object_transparent_set(obj, EINA_FALSE);
4772 evas_object_smart_callback_call(obj, "redirected", NULL);
4776 _e_comp_object_clear(cw);
4777 _e_comp_object_transparent_set(obj, EINA_TRUE);
4778 evas_object_smart_callback_call(obj, "unredirected", NULL);
4783 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4786 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4788 if (cw->buffer_destroy_listener.notify)
4790 cw->buffer_destroy_listener.notify = NULL;
4791 wl_list_remove(&cw->buffer_destroy_listener.link);
4794 if (e_object_is_del(E_OBJECT(cw->ec)))
4796 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4801 /* if it's current displaying buffer, do not remove its content */
4802 if (!evas_object_visible_get(cw->ec->frame))
4803 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4808 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4813 if (cw->buffer_destroy_listener.notify)
4815 wl_list_remove(&cw->buffer_destroy_listener.link);
4816 cw->buffer_destroy_listener.notify = NULL;
4819 if (cw->tbm_surface)
4821 tbm_surface_internal_unref(cw->tbm_surface);
4822 cw->tbm_surface = NULL;
4827 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4829 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4830 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4832 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4834 tbm_surface_internal_ref(ns->data.tbm.buffer);
4835 cw->tbm_surface = ns->data.tbm.buffer;
4839 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4840 evas_object_image_native_surface_set(cw->obj, ns);
4844 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4846 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4847 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4848 evas_object_image_native_surface_set(o, ns);
4855 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4857 Evas_Native_Surface ns;
4860 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4861 if (cw->ec->input_only) return;
4862 if (cw->external_content) return;
4863 if (cw->render_update_lock.lock) return;
4866 memset(&ns, 0, sizeof(Evas_Native_Surface));
4870 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4871 set = (!cw->ec->shaped);
4873 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4877 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4881 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4884 if (cw->ec->input_only) return;
4887 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4888 _e_comp_object_alpha_set(cw);
4890 e_comp_object_native_surface_set(obj, cw->native);
4891 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4895 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4901 if (cw->blanked == set) return;
4903 _e_comp_object_alpha_set(cw);
4906 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4907 evas_object_image_data_set(cw->obj, NULL);
4911 e_comp_object_native_surface_set(obj, 1);
4912 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4916 _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)
4921 if (!_damage_trace) return;
4925 if (!evas_object_visible_get(cw->obj)) return;
4927 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4929 o = evas_object_rectangle_add(e_comp->evas);
4930 evas_object_layer_set(o, E_LAYER_MAX);
4931 evas_object_name_set(o, "damage_trace");
4932 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4933 evas_object_resize(o, dmg_w, dmg_h);
4934 evas_object_color_set(o, 0, 128, 0, 128);
4935 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4936 evas_object_pass_events_set(o, EINA_TRUE);
4937 evas_object_show(o);
4939 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4941 dmg_w, dmg_h, dmg_x, dmg_y,
4942 origin->w, origin->h, origin->x, origin->y);
4944 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4947 /* mark an object as dirty and setup damages */
4949 e_comp_object_dirty(Evas_Object *obj)
4952 Eina_Rectangle *rect;
4956 Eina_Bool dirty, visible;
4960 if (cw->external_content) return;
4961 if (!cw->redirected) return;
4962 if (cw->render_update_lock.lock)
4964 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4967 /* only actually dirty if pixmap is available */
4968 if (!e_pixmap_resource_get(cw->ec->pixmap))
4970 // e_pixmap_size_get returns last attached buffer size
4971 // eventhough it is destroyed
4972 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4975 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4976 visible = cw->visible;
4977 if (!dirty) w = h = 1;
4978 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4980 evas_object_image_data_set(cw->obj, NULL);
4981 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4982 evas_object_image_size_set(cw->obj, tw, th);
4983 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4984 if (cw->pending_updates)
4985 eina_tiler_area_size_set(cw->pending_updates, w, h);
4986 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4988 evas_object_image_pixels_dirty_set(o, dirty);
4990 evas_object_image_data_set(o, NULL);
4991 evas_object_image_size_set(o, tw, th);
4992 visible |= evas_object_visible_get(o);
4996 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
5000 e_comp_object_native_surface_set(obj, 1);
5002 m = _e_comp_object_map_damage_transform_get(cw->ec);
5003 it = eina_tiler_iterator_new(cw->updates);
5004 EINA_ITERATOR_FOREACH(it, rect)
5006 /* evas converts damage according to rotation of ecore_evas in damage_region_set
5007 * of evas engine and doesn't convert damage according to evas_map.
5008 * so damage of evas_object_image use surface coordinate.
5012 int damage_x, damage_y, damage_w, damage_h;
5014 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
5015 &damage_x, &damage_y, &damage_w, &damage_h);
5016 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
5017 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
5021 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
5022 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
5025 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
5026 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
5027 if (cw->pending_updates)
5028 eina_tiler_rect_add(cw->pending_updates, rect);
5030 eina_iterator_free(it);
5031 if (m) e_map_free(m);
5032 if (cw->pending_updates)
5033 eina_tiler_clear(cw->updates);
5036 cw->pending_updates = cw->updates;
5037 cw->updates = eina_tiler_new(w, h);
5038 eina_tiler_tile_size_set(cw->updates, 1, 1);
5040 cw->update_count = cw->updates_full = cw->updates_exist = 0;
5041 evas_object_smart_callback_call(obj, "dirty", NULL);
5042 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
5043 /* force render if main object is hidden but mirrors are visible */
5044 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
5045 e_comp_object_render(obj);
5049 e_comp_object_render(Evas_Object *obj)
5056 API_ENTRY EINA_FALSE;
5058 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5059 if (cw->ec->input_only) return EINA_TRUE;
5060 if (cw->external_content) return EINA_TRUE;
5061 if (cw->native) return EINA_FALSE;
5062 /* if comp object is not redirected state, comp object should not be set by newly committed data
5063 because image size of comp object is 1x1 and it should not be shown on canvas */
5064 if (!cw->redirected) return EINA_TRUE;
5065 if (cw->render_update_lock.lock)
5067 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5070 e_comp_object_render_update_del(obj);
5071 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5073 if (!cw->pending_updates)
5075 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5076 evas_object_image_data_set(cw->obj, NULL);
5077 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5078 evas_object_image_data_set(o, NULL);
5082 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5084 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5086 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5089 e_pixmap_image_refresh(cw->ec->pixmap);
5090 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5093 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5094 e_pixmap_image_data_ref(cw->ec->pixmap);
5096 /* set pixel data */
5097 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5098 _e_comp_object_alpha_set(cw);
5099 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5101 evas_object_image_data_set(o, pix);
5102 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5103 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5106 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5108 e_comp_client_post_update_add(cw->ec);
5113 /* create a duplicate of an evas object */
5114 EINTERN Evas_Object *
5115 e_comp_object_util_mirror_add(Evas_Object *obj)
5119 unsigned int *pix = NULL;
5120 Eina_Bool argb = EINA_FALSE;
5125 cw = evas_object_data_get(obj, "comp_mirror");
5128 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5129 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5130 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5131 evas_object_image_alpha_set(o, 1);
5132 evas_object_image_source_set(o, obj);
5135 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5136 if (cw->external_content)
5138 ERR("%p of client %p is external content.", obj, cw->ec);
5141 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5142 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5143 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5144 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5145 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5146 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5147 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5148 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5149 evas_object_data_set(o, "comp_mirror", cw);
5151 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5152 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5154 evas_object_image_size_set(o, tw, th);
5157 pix = evas_object_image_data_get(cw->obj, 0);
5163 evas_object_image_native_surface_set(o, cw->ns);
5166 Evas_Native_Surface ns;
5167 memset(&ns, 0, sizeof(Evas_Native_Surface));
5168 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5169 evas_object_image_native_surface_set(o, &ns);
5174 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5175 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5177 (e_pixmap_image_exists(cw->ec->pixmap)))
5178 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5180 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5187 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5188 evas_object_image_pixels_dirty_set(o, dirty);
5189 evas_object_image_data_set(o, pix);
5190 evas_object_image_data_set(cw->obj, pix);
5192 evas_object_image_data_update_add(o, 0, 0, tw, th);
5197 //////////////////////////////////////////////////////
5200 e_comp_object_effect_allowed_get(Evas_Object *obj)
5202 API_ENTRY EINA_FALSE;
5204 if (!cw->shobj) return EINA_FALSE;
5205 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5206 return !e_comp_config_get()->match.disable_borders;
5209 /* setup an api effect for a client */
5211 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5214 Eina_Stringshare *grp;
5215 E_Comp_Config *config;
5216 Eina_Bool loaded = EINA_FALSE;
5218 API_ENTRY EINA_FALSE;
5219 if (!cw->shobj) return EINA_FALSE; //input window
5221 if (!effect) effect = "none";
5222 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5224 config = e_comp_config_get();
5225 if ((config) && (config->effect_file))
5227 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5229 cw->effect_set = EINA_TRUE;
5236 edje_object_file_get(cw->effect_obj, NULL, &grp);
5237 cw->effect_set = !eina_streq(effect, "none");
5238 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5239 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5241 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5242 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5243 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5245 if (cw->effect_running)
5247 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5250 cw->effect_set = EINA_FALSE;
5251 return cw->effect_set;
5255 if (cw->effect_running)
5257 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5260 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5261 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5262 if (cw->effect_clip)
5264 evas_object_clip_unset(cw->clip);
5265 cw->effect_clip = 0;
5267 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5269 _e_comp_object_dim_update(cw);
5271 return cw->effect_set;
5274 /* set params for embryo scripts in effect */
5276 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5278 Edje_Message_Int_Set *msg;
5282 EINA_SAFETY_ON_NULL_RETURN(params);
5283 EINA_SAFETY_ON_FALSE_RETURN(count);
5284 if (!cw->effect_set) return;
5286 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5287 msg->count = (int)count;
5288 for (x = 0; x < count; x++)
5289 msg->val[x] = params[x];
5290 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5291 edje_object_message_signal_process(cw->effect_obj);
5295 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5297 Edje_Signal_Cb end_cb;
5299 E_Comp_Object *cw = data;
5301 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5302 cw->effect_running = 0;
5303 if (!_e_comp_object_animating_end(cw)) return;
5305 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5307 evas_object_data_del(cw->smart_obj, "effect_running");
5308 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5309 e_client_visibility_calculate();
5312 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5313 if (!end_cb) return;
5314 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5315 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5316 end_cb(end_data, cw->smart_obj, emission, source);
5319 /* clip effect to client's zone */
5321 e_comp_object_effect_clip(Evas_Object *obj)
5324 if (!cw->ec->zone) return;
5325 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5326 if (!cw->effect_clip_able) return;
5327 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5328 cw->effect_clip = 1;
5331 /* unclip effect from client's zone */
5333 e_comp_object_effect_unclip(Evas_Object *obj)
5336 if (!cw->effect_clip) return;
5337 evas_object_clip_unset(cw->smart_obj);
5338 cw->effect_clip = 0;
5341 /* start effect, running end_cb after */
5343 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5345 API_ENTRY EINA_FALSE;
5346 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5347 if (!cw->effect_set) return EINA_FALSE;
5349 if (cw->effect_running)
5351 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5354 e_comp_object_effect_clip(obj);
5355 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5357 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5358 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5359 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5360 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5362 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5363 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5365 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5366 _e_comp_object_animating_begin(cw);
5367 cw->effect_running = 1;
5371 /* stop a currently-running effect immediately */
5373 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5376 Edje_Signal_Cb end_cb_before = NULL;
5377 void *end_data_before = NULL;
5378 API_ENTRY EINA_FALSE;
5380 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5381 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5383 if (end_cb_before != end_cb) return EINA_TRUE;
5384 e_comp_object_effect_unclip(obj);
5385 if (cw->effect_clip)
5387 evas_object_clip_unset(cw->effect_obj);
5388 cw->effect_clip = 0;
5390 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5391 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5393 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5395 evas_object_data_del(cw->smart_obj, "effect_running");
5396 e_client_visibility_calculate();
5399 cw->effect_running = 0;
5400 ret = _e_comp_object_animating_end(cw);
5402 if ((ret) && (end_cb_before))
5404 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5405 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5412 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5414 return a->pri - b->pri;
5417 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5418 E_API E_Comp_Object_Mover *
5419 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5421 E_Comp_Object_Mover *prov;
5423 prov = E_NEW(E_Comp_Object_Mover, 1);
5424 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5425 prov->func = provider;
5426 prov->data = (void*)data;
5429 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5430 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5435 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5437 EINA_SAFETY_ON_NULL_RETURN(prov);
5438 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5443 e_comp_object_effect_object_get(Evas_Object *obj)
5447 return cw->effect_obj;
5451 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5453 API_ENTRY EINA_FALSE;
5454 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5455 if (!cw->effect_set) return EINA_FALSE;
5462 ////////////////////////////////////
5465 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5467 if (e_comp->autoclose.obj)
5469 e_comp_ungrab_input(0, 1);
5470 if (e_comp->autoclose.del_cb)
5471 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5472 else if (!already_del)
5474 evas_object_hide(e_comp->autoclose.obj);
5475 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5477 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5479 e_comp->autoclose.obj = NULL;
5480 e_comp->autoclose.data = NULL;
5481 e_comp->autoclose.del_cb = NULL;
5482 e_comp->autoclose.key_cb = NULL;
5483 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5487 _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)
5489 _e_comp_object_autoclose_cleanup(0);
5493 _e_comp_object_autoclose_setup(Evas_Object *obj)
5495 if (!e_comp->autoclose.rect)
5497 /* create rect just below autoclose object to catch mouse events */
5498 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5499 evas_object_move(e_comp->autoclose.rect, 0, 0);
5500 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5501 evas_object_show(e_comp->autoclose.rect);
5502 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5503 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5504 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5505 e_comp_grab_input(0, 1);
5507 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5508 evas_object_focus_set(obj, 1);
5512 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5514 _e_comp_object_autoclose_setup(obj);
5515 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5519 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5521 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5522 _e_comp_object_autoclose_cleanup(1);
5523 if (e_client_focused_get()) return;
5524 if (e_config->focus_policy != E_FOCUS_MOUSE)
5529 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5533 if (e_comp->autoclose.obj)
5535 if (e_comp->autoclose.obj == obj) return;
5536 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5537 e_comp->autoclose.obj = obj;
5538 e_comp->autoclose.del_cb = del_cb;
5539 e_comp->autoclose.key_cb = cb;
5540 e_comp->autoclose.data = (void*)data;
5541 if (evas_object_visible_get(obj))
5542 _e_comp_object_autoclose_setup(obj);
5544 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5545 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5548 e_comp->autoclose.obj = obj;
5549 e_comp->autoclose.del_cb = del_cb;
5550 e_comp->autoclose.key_cb = cb;
5551 e_comp->autoclose.data = (void*)data;
5552 if (evas_object_visible_get(obj))
5553 _e_comp_object_autoclose_setup(obj);
5555 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5556 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5560 e_comp_object_is_animating(Evas_Object *obj)
5564 return cw->animating;
5568 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5572 if ((cw->external_content) &&
5573 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5575 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5576 "But current external content is %d object for %p.",
5577 cw->content_type, cw->ec);
5581 cw->user_alpha_set = EINA_TRUE;
5582 cw->user_alpha = alpha;
5584 if (!cw->obj) return;
5586 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5588 evas_object_image_alpha_set(cw->obj, alpha);
5590 if ((!cw->native) && (!cw->external_content))
5591 evas_object_image_data_set(cw->obj, NULL);
5595 e_comp_object_alpha_get(Evas_Object *obj)
5597 API_ENTRY EINA_FALSE;
5599 return evas_object_image_alpha_get(cw->obj);
5603 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5605 Eina_Bool mask_set = EINA_FALSE;
5609 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5610 if (cw->ec->input_only) return;
5617 o = evas_object_rectangle_add(e_comp->evas);
5618 evas_object_color_set(o, 0, 0, 0, 0);
5619 evas_object_clip_set(o, cw->clip);
5620 evas_object_smart_member_add(o, obj);
5621 evas_object_move(o, 0, 0);
5622 evas_object_resize(o, cw->w, cw->h);
5623 /* save render op value to restore when clear a mask.
5625 * NOTE: DO NOT change the render op on ec->frame while mask object
5626 * is set. it will overwrite the changed op value. */
5627 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5628 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5629 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5630 if (cw->visible) evas_object_show(o);
5633 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5634 ELOGF("COMP", " |mask_obj", cw->ec);
5635 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5642 evas_object_smart_member_del(cw->mask.obj);
5643 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5645 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5646 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5652 e_comp_object_mask_has(Evas_Object *obj)
5654 API_ENTRY EINA_FALSE;
5656 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5660 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5665 if ((cw->external_content) &&
5666 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5668 WRN("Can set up size to ONLY evas \"image\" object. "
5669 "But current external content is %d object for %p.",
5670 cw->content_type, cw->ec);
5674 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5676 evas_object_image_size_set(cw->obj, tw, th);
5680 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5682 Eina_Bool transform_set = EINA_FALSE;
5684 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5685 if (cw->ec->input_only) return;
5687 transform_set = !!set;
5691 if (!cw->transform_bg_obj)
5693 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5694 evas_object_move(o, 0, 0);
5695 evas_object_resize(o, 1, 1);
5696 if (cw->transform_bg_color.a >= 255)
5697 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5699 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5700 evas_object_color_set(o,
5701 cw->transform_bg_color.r,
5702 cw->transform_bg_color.g,
5703 cw->transform_bg_color.b,
5704 cw->transform_bg_color.a);
5705 if (cw->visible) evas_object_show(o);
5707 cw->transform_bg_obj = o;
5708 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5710 _e_comp_object_transform_obj_stack_update(obj);
5714 if (cw->transform_bg_obj)
5716 evas_object_smart_member_del(cw->transform_bg_obj);
5717 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5723 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5727 cw->transform_bg_color.r = r;
5728 cw->transform_bg_color.g = g;
5729 cw->transform_bg_color.b = b;
5730 cw->transform_bg_color.a = a;
5732 if (cw->transform_bg_obj)
5734 evas_object_color_set(cw->transform_bg_obj,
5735 cw->transform_bg_color.r,
5736 cw->transform_bg_color.g,
5737 cw->transform_bg_color.b,
5738 cw->transform_bg_color.a);
5743 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5746 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5747 if (cw->ec->input_only) return;
5748 if (!cw->transform_bg_obj) return;
5750 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5754 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5757 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5758 if (cw->ec->input_only) return;
5759 if (!cw->transform_bg_obj) return;
5761 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5765 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5767 Eina_Bool transform_set = EINA_FALSE;
5769 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5770 if (cw->ec->input_only) return;
5772 transform_set = !!set;
5776 if (!cw->transform_tranp_obj)
5778 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5779 evas_object_move(o, 0, 0);
5780 evas_object_resize(o, 1, 1);
5781 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5782 evas_object_color_set(o, 0, 0, 0, 0);
5783 if (cw->visible) evas_object_show(o);
5785 cw->transform_tranp_obj = o;
5786 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5788 _e_comp_object_transform_obj_stack_update(obj);
5792 if (cw->transform_tranp_obj)
5794 evas_object_smart_member_del(cw->transform_tranp_obj);
5795 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5801 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5804 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5805 if (cw->ec->input_only) return;
5806 if (!cw->transform_tranp_obj) return;
5808 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5812 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5815 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5816 if (cw->ec->input_only) return;
5817 if (!cw->transform_tranp_obj) return;
5819 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5823 e_comp_object_layer_update(Evas_Object *obj,
5824 Evas_Object *above, Evas_Object *below)
5826 E_Comp_Object *cw2 = NULL;
5827 Evas_Object *o = NULL;
5832 if (cw->ec->layer_block) return;
5833 if ((above) && (below))
5835 ERR("Invalid layer update request! cw=%p", cw);
5843 layer = evas_object_layer_get(o);
5844 cw2 = evas_object_data_get(o, "comp_obj");
5847 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5849 o = evas_object_above_get(o);
5850 if ((!o) || (o == cw->smart_obj)) break;
5851 if (evas_object_layer_get(o) != layer)
5853 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5858 ec = e_client_top_get();
5859 if (ec) o = ec->frame;
5862 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5866 _e_comp_object_layers_remove(cw);
5869 if (cw2->layer > cw->layer)
5870 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5871 else if (cw2->layer == cw->layer)
5874 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5876 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5878 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5881 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5884 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5888 e_comp_object_layer_get(Evas_Object *obj)
5895 e_comp_object_content_set(Evas_Object *obj,
5896 Evas_Object *content,
5897 E_Comp_Object_Content_Type type)
5899 API_ENTRY EINA_FALSE;
5901 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5902 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5903 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5907 ERR("Can't set e.swallow.content to requested content. "
5908 "Previous comp object should not be changed at all.");
5912 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5914 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5915 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5917 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5918 type, content, cw->ec, cw->ec->pixmap);
5922 cw->external_content = EINA_TRUE;
5925 cw->content_type = type;
5926 e_util_size_debug_set(cw->obj, 1);
5927 evas_object_name_set(cw->obj, "cw->obj");
5928 _e_comp_object_alpha_set(cw);
5931 _e_comp_object_shadow_setup(cw);
5937 e_comp_object_content_unset(Evas_Object *obj)
5939 API_ENTRY EINA_FALSE;
5941 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5942 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5944 if (!cw->obj && !cw->ec->visible)
5946 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5950 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5952 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5958 if (cw->frame_object)
5959 edje_object_part_unswallow(cw->frame_object, cw->obj);
5961 edje_object_part_unswallow(cw->shobj, cw->obj);
5963 evas_object_del(cw->obj);
5964 evas_object_hide(cw->obj);
5968 cw->external_content = EINA_FALSE;
5969 if (cw->ec->is_cursor)
5972 DBG("%p is cursor surface..", cw->ec);
5973 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5975 evas_object_resize(cw->ec->frame, pw, ph);
5976 evas_object_hide(cw->ec->frame);
5981 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5982 cw->obj = evas_object_image_filled_add(e_comp->evas);
5983 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5984 e_util_size_debug_set(cw->obj, 1);
5985 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5986 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5987 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5988 evas_object_name_set(cw->obj, "cw->obj");
5989 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5990 _e_comp_object_alpha_set(cw);
5993 _e_comp_object_shadow_setup(cw);
5998 _e_comp_intercept_show_helper(cw);
6002 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
6003 e_comp_object_dirty(cw->smart_obj);
6004 e_comp_object_render(cw->smart_obj);
6005 e_comp_object_render_update_add(obj);
6010 EINTERN Evas_Object *
6011 e_comp_object_content_get(Evas_Object *obj)
6015 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
6017 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
6019 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
6026 E_API E_Comp_Object_Content_Type
6027 e_comp_object_content_type_get(Evas_Object *obj)
6029 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
6031 return cw->content_type;
6035 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
6038 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6039 E_Comp_Config *conf = e_comp_config_get();
6040 if (cw->ec->input_only) return;
6041 if (!conf->dim_rect_enable) return;
6043 cw->dim.mask_set = mask_set;
6049 if (!cw->dim.enable) return;
6050 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6054 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6056 Eina_Bool mask_set = EINA_FALSE;
6060 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6061 E_Comp_Config *conf = e_comp_config_get();
6062 if (cw->ec->input_only) return;
6063 if (!conf->dim_rect_enable) return;
6069 if (cw->dim.mask_obj)
6071 evas_object_smart_member_del(cw->dim.mask_obj);
6072 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6075 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);
6076 o = evas_object_rectangle_add(e_comp->evas);
6077 evas_object_color_set(o, 0, 0, 0, 0);
6078 evas_object_smart_member_add(o, obj);
6079 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6080 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6082 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6083 if (cw->visible) evas_object_show(o);
6085 cw->dim.mask_obj = o;
6086 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6088 evas_object_layer_set(cw->dim.mask_obj, 9998);
6092 if (cw->dim.mask_obj)
6094 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6095 evas_object_smart_member_del(cw->dim.mask_obj);
6096 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6102 e_comp_object_dim_client_set(E_Client *ec)
6104 E_Comp_Config *conf = e_comp_config_get();
6106 if (!conf->dim_rect_enable) return ;
6107 if (dim_client == ec) return;
6109 Eina_Bool prev_dim = EINA_FALSE;
6110 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6112 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6113 prev_dim = EINA_TRUE;
6115 if (prev_dim && dim_client->visible && ec)
6117 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6118 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6122 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6123 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6129 e_comp_object_dim_client_get(void)
6131 E_Comp_Config *conf = e_comp_config_get();
6133 if (!conf->dim_rect_enable ) return NULL;
6139 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6142 char emit[32] = "\0";
6143 E_Comp_Config *conf = e_comp_config_get();
6146 if (!conf->dim_rect_enable) return;
6147 if (!cw->effect_obj) return;
6148 if (enable == cw->dim.enable) return;
6150 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6151 if (noeffect || !conf->dim_rect_effect)
6153 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6157 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6160 cw->dim.enable = enable;
6162 if (cw->dim.mask_set && !enable)
6164 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6165 edje_object_signal_emit(cw->effect_obj, emit, "e");
6167 else if (cw->dim.mask_set && enable)
6169 edje_object_signal_emit(cw->effect_obj, emit, "e");
6170 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6174 edje_object_signal_emit(cw->effect_obj, emit, "e");
6179 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6181 API_ENTRY EINA_FALSE;
6182 E_Comp_Config *conf = e_comp_config_get();
6184 if (!ec) return EINA_FALSE;
6185 if (!conf->dim_rect_enable) return EINA_FALSE;
6187 if (cw->dim.enable) return EINA_TRUE;
6193 _e_comp_object_dim_update(E_Comp_Object *cw)
6195 E_Comp_Config *conf = e_comp_config_get();
6198 if (!conf->dim_rect_enable) return;
6199 if (!cw->effect_obj) return;
6202 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6203 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6205 if (cw->dim.mask_set)
6207 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6213 e_comp_object_clear(Evas_Object *obj)
6217 _e_comp_object_clear(cw);
6221 e_comp_object_hwc_update_exists(Evas_Object *obj)
6223 API_ENTRY EINA_FALSE;
6224 return cw->hwc_need_update;
6229 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6232 cw->hwc_need_update = set;
6236 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6238 API_ENTRY EINA_FALSE;
6239 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6243 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6246 if (cw->indicator.obj != indicator)
6247 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6248 cw->indicator.obj = indicator;
6249 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6253 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6256 if (cw->indicator.obj != indicator) return;
6257 cw->indicator.obj = NULL;
6258 edje_object_part_unswallow(cw->shobj, indicator);
6262 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6265 Edje_Message_Int_Set *msg;
6267 if (!cw->indicator.obj) return;
6269 cw->indicator.w = w;
6270 cw->indicator.h = h;
6272 if (!cw->shobj) return;
6274 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6278 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6279 edje_object_message_signal_process(cw->shobj);
6282 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6284 e_comp_object_map_update(Evas_Object *obj)
6287 E_Client *ec = cw->ec;
6288 E_Comp_Wl_Client_Data *cdata;
6290 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6293 int l, remain = sizeof buffer;
6296 if (e_object_is_del(E_OBJECT(ec))) return;
6297 cdata = e_client_cdata_get(ec);
6300 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6301 * when new buffer is attached.
6303 if (!cdata->buffer_ref.buffer) return;
6305 if ((!cw->redirected) ||
6306 (e_client_video_hw_composition_check(ec)) ||
6307 (!e_comp_wl_output_buffer_transform_get(ec) &&
6308 cdata->scaler.buffer_viewport.buffer.scale == 1))
6310 if (evas_object_map_enable_get(cw->effect_obj))
6312 ELOGF("TRANSFORM", "map: disable", cw->ec);
6313 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6314 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6315 evas_object_resize(cw->effect_obj, tw, th);
6322 EINA_SAFETY_ON_NULL_RETURN(map);
6324 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6330 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6332 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6333 e_map_point_image_uv_set(map, 0, 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, y1, &x, &y);
6338 e_map_point_image_uv_set(map, 1, x, y);
6339 l = snprintf(p, remain, " %d,%d", x, y);
6340 p += l, remain -= l;
6342 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6343 e_map_point_image_uv_set(map, 2, x, y);
6344 l = snprintf(p, remain, " %d,%d", x, y);
6345 p += l, remain -= l;
6347 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6348 e_map_point_image_uv_set(map, 3, x, y);
6349 l = snprintf(p, remain, " %d,%d", x, y);
6350 p += l, remain -= l;
6352 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6354 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6356 e_comp_object_map_set(cw->effect_obj, map);
6357 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6361 /* if there's screen rotation with comp mode, then ec->effect_obj and
6362 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6364 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6365 evas_object_resize(cw->effect_obj, tw, th);
6369 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6371 API_ENTRY EINA_FALSE;
6373 cw->render_trace = set;
6379 e_comp_object_native_usable_get(Evas_Object *obj)
6381 API_ENTRY EINA_FALSE;
6382 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6384 if (cw->ec->input_only) return EINA_FALSE;
6385 if (cw->external_content) return EINA_FALSE;
6386 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6388 /* just return true value, if it is normal case */
6389 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6392 Evas_Native_Surface *ns;
6393 ns = evas_object_image_native_surface_get(cw->obj);
6395 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6398 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6406 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6408 API_ENTRY EINA_FALSE;
6409 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6410 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6411 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6415 case E_COMP_IMAGE_FILTER_BLUR:
6416 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6418 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6419 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6421 case E_COMP_IMAGE_FILTER_INVERSE:
6422 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6424 case E_COMP_IMAGE_FILTER_NONE:
6426 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6430 cw->image_filter = filter;
6435 EINTERN E_Comp_Image_Filter
6436 e_comp_object_image_filter_get(Evas_Object *obj)
6438 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6439 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6440 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6441 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6443 return cw->image_filter;
6447 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6451 if (!_damage_trace) return;
6453 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6454 evas_object_del(obj);
6456 _damage_trace_post_objs = NULL;
6460 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6462 if (!_damage_trace) return;
6464 _damage_trace_post_objs = _damage_trace_objs;
6465 _damage_trace_objs = NULL;
6469 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6471 if (_damage_trace == onoff) return;
6475 evas_event_callback_add(e_comp->evas,
6476 EVAS_CALLBACK_RENDER_PRE,
6477 _e_comp_object_damage_trace_render_pre_cb,
6480 evas_event_callback_add(e_comp->evas,
6481 EVAS_CALLBACK_RENDER_POST,
6482 _e_comp_object_damage_trace_render_post_cb,
6489 EINA_LIST_FREE(_damage_trace_objs, obj)
6490 evas_object_del(obj);
6492 _damage_trace_objs = NULL;
6494 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6495 evas_object_del(obj);
6497 _damage_trace_post_objs = NULL;
6499 evas_event_callback_del(e_comp->evas,
6500 EVAS_CALLBACK_RENDER_PRE,
6501 _e_comp_object_damage_trace_render_pre_cb);
6503 evas_event_callback_del(e_comp->evas,
6504 EVAS_CALLBACK_RENDER_POST,
6505 _e_comp_object_damage_trace_render_post_cb);
6508 _damage_trace = onoff;
6512 e_comp_object_redirected_get(Evas_Object *obj)
6514 API_ENTRY EINA_FALSE;
6515 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6517 return cw->redirected;
6521 e_comp_object_color_visible_get(Evas_Object *obj)
6523 API_ENTRY EINA_FALSE;
6526 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6528 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6532 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6536 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6540 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6548 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6550 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6552 return e_map_set_to_comp_object(em, obj);
6556 e_comp_object_map_get(const Evas_Object *obj)
6558 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6560 return e_map_get_from_comp_object(obj);
6564 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6566 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6568 evas_object_map_enable_set(obj, enable);
6574 e_comp_object_render_update_lock(Evas_Object *obj)
6576 API_ENTRY EINA_FALSE;
6578 if (cw->render_update_lock.lock == 0)
6580 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6581 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6582 e_pixmap_resource_get(cw->ec->pixmap));
6583 e_comp_object_render_update_del(obj);
6584 ELOGF("COMP", "Render update lock enabled", cw->ec);
6587 cw->render_update_lock.lock++;
6593 e_comp_object_render_update_unlock(Evas_Object *obj)
6597 if (cw->render_update_lock.lock == 0)
6600 cw->render_update_lock.lock--;
6602 if (cw->render_update_lock.lock == 0)
6605 if (cw->render_update_lock.pending_move_set)
6607 evas_object_move(obj,
6608 cw->render_update_lock.pending_move_x,
6609 cw->render_update_lock.pending_move_y);
6610 cw->render_update_lock.pending_move_x = 0;
6611 cw->render_update_lock.pending_move_y = 0;
6612 cw->render_update_lock.pending_move_set = EINA_FALSE;
6615 if (cw->render_update_lock.pending_resize_set)
6617 evas_object_resize(obj,
6618 cw->render_update_lock.pending_resize_w,
6619 cw->render_update_lock.pending_resize_h);
6620 cw->render_update_lock.pending_resize_w = 0;
6621 cw->render_update_lock.pending_resize_h = 0;
6622 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6625 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6627 if ((cw->ec->exp_iconify.buffer_flush) &&
6628 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6629 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6630 e_comp_object_clear(obj);
6632 e_comp_object_render_update_add(obj);
6634 ELOGF("COMP", "Render update lock disabled", cw->ec);
6639 e_comp_object_render_update_lock_get(Evas_Object *obj)
6641 API_ENTRY EINA_FALSE;
6643 if (cw->render_update_lock.lock > 0)
6650 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6654 if (cw->transparent.set)
6656 if (r) *r = cw->transparent.user_r;
6657 if (g) *g = cw->transparent.user_g;
6658 if (b) *b = cw->transparent.user_b;
6659 if (a) *a = cw->transparent.user_a;
6663 evas_object_color_get(obj, r, g, b, a);