5 = keys that return objects =
6 - E_Client: the client associated with the object (E_Client*)
7 - comp_smart_obj: cw->smart_obj (Evas_Object*)
8 - comp_obj: cw (E_Comp_Object*)
10 = keys that are bool flags =
11 - client_restack: client needs a protocol-level restack
12 - comp_override: object is triggering a nocomp override to force compositing
13 - comp_ref: object has a ref from visibility animations
14 - comp_showing: object is currently running its show animation
15 - comp_hiding: object is currently running its hiding animation
16 - comp_object: object is a compositor-created object
17 - comp_object_skip: object has a name which prohibits theme shadows
18 - comp_object-to_del: list of objects which will be deleted when this object is deleted
19 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
20 - effect_running: object is animating by external module
23 #define UPDATE_MAX 512 // same as evas
24 #define FAILURE_MAX 2 // seems reasonable
25 #define SMART_NAME "e_comp_object"
26 #define INPUT_OBJ_SMART_NAME "input_object"
28 /* for non-util functions */
29 #define API_ENTRY E_Comp_Object *cw; \
30 cw = evas_object_smart_data_get(obj); \
31 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
33 /* for util functions (obj may or may not be E_Comp_Object */
34 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
37 CRI("YOU PASSED NULL! ARGH!"); \
40 cw = evas_object_smart_data_get(obj); \
41 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
43 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
45 /* enable for lots of client size info in console output */
47 # define e_util_size_debug_set(x, y)
50 /* enable along with display-specific damage INF calls to enable render tracing
54 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
56 #define RENDER_DEBUG(...)
59 typedef struct _E_Comp_Object
63 int x, y, w, h; // geometry
67 E_Comp_Object_Frame client_inset;
77 Eina_Stringshare *frame_theme;
78 Eina_Stringshare *frame_name;
79 Eina_Stringshare *visibility_effect; //effect when toggling visibility
81 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
83 Evas_Object *smart_obj; // smart object
84 Evas_Object *clip; // clipper over effect object
85 Evas_Object *input_obj; // input smart object
86 Evas_Object *obj; // composite object
87 Evas_Object *frame_object; // for client frames
88 Evas_Object *shobj; // shadow object
89 Evas_Object *effect_obj; // effects object
90 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
95 Evas_Object *transform_tranp_obj;// transform transp rect obj
96 Evas_Object *default_input_obj; // default input object
97 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
98 Eina_List *obj_mirror; // extra mirror objects
99 Eina_Tiler *updates; //render update regions
100 Eina_Tiler *pending_updates; //render update regions which are about to render
102 Evas_Native_Surface *ns; //for custom gl rendering
104 struct wl_listener buffer_destroy_listener;
106 unsigned int update_count; // how many updates have happened to this obj
108 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
110 unsigned int animating; // it's busy animating
111 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
112 unsigned int force_visible; //number of visible obj_mirror objects
113 Eina_Bool delete_pending : 1; // delete pending
114 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
115 Eina_Bool showing : 1; // object is currently in "show" animation
116 Eina_Bool hiding : 1; // object is currently in "hide" animation
117 Eina_Bool visible : 1; // is visible
119 Eina_Bool shaped : 1; // is shaped
120 Eina_Bool update : 1; // has updates to fetch
121 Eina_Bool redirected : 1; // has updates to fetch
122 Eina_Bool native : 1; // native
124 Eina_Bool nocomp : 1; // nocomp applied
125 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
126 Eina_Bool real_hid : 1; // last hide was a real window unmap
128 Eina_Bool effect_set : 1; //effect_obj has a valid group
129 Eina_Bool effect_running : 1; //effect_obj is playing an animation
130 Eina_Bool effect_clip : 1; //effect_obj is clipped
131 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
133 Eina_Bool updates_exist : 1;
134 Eina_Bool updates_full : 1; // entire object will be updated
136 Eina_Bool force_move : 1;
137 Eina_Bool frame_extends : 1; //frame may extend beyond object size
138 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
139 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
140 Eina_Bool user_alpha_set : 1;
141 Eina_Bool user_alpha : 1;
145 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
146 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
153 } indicator; //indicator object for internal client
157 Evas_Object *mask_obj;
160 int mask_x, mask_y, mask_w, mask_h;
163 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
165 tbm_surface_h tbm_surface;
166 E_Comp_Image_Filter image_filter;
167 Eina_Bool set_mouse_callbacks;
172 E_Comp_Wl_Buffer_Ref buffer_ref;
173 Eina_Bool pending_move_set;
174 int pending_move_x, pending_move_y;
175 Eina_Bool pending_resize_set;
176 int pending_resize_w, pending_resize_h;
177 } render_update_lock;
189 typedef struct _E_Input_Rect_Data
195 typedef struct _E_Input_Rect_Smart_Data
197 Eina_List *input_rect_data_list;
199 } E_Input_Rect_Smart_Data;
201 struct E_Comp_Object_Mover
204 E_Comp_Object_Mover_Cb func;
210 static Eina_Inlist *_e_comp_object_movers = NULL;
211 static Evas_Smart *_e_comp_smart = NULL;
212 static Evas_Smart *_e_comp_input_obj_smart = NULL;
214 static int _e_comp_object_hooks_delete = 0;
215 static int _e_comp_object_hooks_walking = 0;
217 static Eina_Inlist *_e_comp_object_hooks[] =
219 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
220 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
221 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
222 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
223 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
225 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
226 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
229 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
230 static int _e_comp_object_intercept_hooks_delete = 0;
231 static int _e_comp_object_intercept_hooks_walking = 0;
233 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
235 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
236 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
240 static Eina_Bool _damage_trace = EINA_FALSE;
241 static Eina_List *_damage_trace_objs = NULL;
242 static Eina_List *_damage_trace_post_objs = NULL;
244 /* sekrit functionzzz */
245 EINTERN void e_client_focused_set(E_Client *ec);
247 /* emitted every time a new noteworthy comp object is added */
248 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
250 /* ecore event define */
251 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
252 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
253 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
255 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
256 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
257 static void _e_comp_object_dim_update(E_Comp_Object *cw);
258 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
259 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
261 static E_Client *dim_client = NULL;
264 _e_comp_object_hooks_clean(void)
267 E_Comp_Object_Hook *ch;
270 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
271 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
273 if (!ch->delete_me) continue;
274 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
280 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
282 E_Comp_Object_Hook *ch;
283 Eina_Bool ret = EINA_TRUE;
285 if (e_object_is_del(E_OBJECT(ec)))
287 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
288 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
289 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
290 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
294 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET))
299 e_object_ref(E_OBJECT(ec));
300 _e_comp_object_hooks_walking++;
301 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
303 if (ch->delete_me) continue;
304 if (!(ch->func(ch->data, ec)))
310 _e_comp_object_hooks_walking--;
311 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
312 _e_comp_object_hooks_clean();
314 e_object_unref(E_OBJECT(ec));
319 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
321 _e_comp_object_intercept_hooks_clean(void)
324 E_Comp_Object_Intercept_Hook *ch;
327 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
328 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
330 if (!ch->delete_me) continue;
331 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
337 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
339 E_Comp_Object_Intercept_Hook *ch;
340 Eina_Bool ret = EINA_TRUE;
342 if (e_object_is_del(E_OBJECT(ec))) return ret;
343 e_object_ref(E_OBJECT(ec));
344 _e_comp_object_intercept_hooks_walking++;
345 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
347 if (ch->delete_me) continue;
348 if (!(ch->func(ch->data, ec)))
354 _e_comp_object_intercept_hooks_walking--;
355 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
356 _e_comp_object_intercept_hooks_clean();
358 e_object_unref(E_OBJECT(ec));
365 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
367 E_Event_Comp_Object *ev = event;
370 ec = evas_object_data_get(ev->comp_object, "E_Client");
374 e_object_unref(E_OBJECT(ec));
376 evas_object_unref(ev->comp_object);
381 _e_comp_object_event_add(Evas_Object *obj)
383 E_Event_Comp_Object *ev;
386 if (stopping) return;
387 ev = E_NEW(E_Event_Comp_Object, 1);
388 EINA_SAFETY_ON_NULL_RETURN(ev);
390 evas_object_ref(obj);
391 ev->comp_object = obj;
392 ec = evas_object_data_get(ev->comp_object, "E_Client");
396 e_object_ref(E_OBJECT(ec));
398 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
402 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
404 E_Event_Comp_Object *ev = event;
407 ec = evas_object_data_get(ev->comp_object, "E_Client");
411 e_object_unref(E_OBJECT(ec));
413 evas_object_unref(ev->comp_object);
418 _e_comp_object_event_simple(Evas_Object *obj, int type)
420 E_Event_Comp_Object *ev;
423 ev = E_NEW(E_Event_Comp_Object, 1);
426 evas_object_ref(obj);
427 ev->comp_object = obj;
428 ec = evas_object_data_get(ev->comp_object, "E_Client");
432 e_object_ref(E_OBJECT(ec));
434 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
436 /////////////////////////////////////
439 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
441 E_Comp_Object *cw = data;
443 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
447 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
452 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
455 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
456 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
460 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
462 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
469 /////////////////////////////////////
472 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
477 if (cw->ec->input_only) return;
479 layer = evas_object_layer_get(obj);
481 if (cw->transform_bg_obj)
483 if (layer != evas_object_layer_get(cw->transform_bg_obj))
485 evas_object_layer_set(cw->transform_bg_obj, layer);
488 evas_object_stack_below(cw->transform_bg_obj, obj);
491 if (cw->transform_tranp_obj)
493 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
495 evas_object_layer_set(cw->transform_tranp_obj, layer);
498 evas_object_stack_below(cw->transform_tranp_obj, obj);
503 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
510 if (!map) return NULL;
512 e_map_util_points_populate_from_object_full(map, obj, 0);
513 e_map_util_points_color_set(map, 255, 255, 255, 255);
515 for (i = 0 ; i < 4 ; ++i)
520 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
521 e_map_point_coord_set(map, i, x, y, 1.0);
528 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
537 e_comp_object_map_set(obj, map);
538 e_comp_object_map_enable_set(obj, EINA_TRUE);
545 evas_object_map_enable_set(obj, EINA_FALSE);
550 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
561 e_comp_object_map_set(obj, map);
562 e_comp_object_map_enable_set(obj, EINA_TRUE);
569 evas_object_map_enable_set(obj, EINA_FALSE);
572 /////////////////////////////////////
574 static inline Eina_Bool
575 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
577 if (num > 1) return EINA_TRUE;
578 if ((rects[0].x == 0) && (rects[0].y == 0) &&
579 ((int)rects[0].w == w) && ((int)rects[0].h == h))
584 /////////////////////////////////////
586 /* add a client to the layer-client list */
588 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
590 E_Comp_Object *layer_cw = NULL;
592 /* try to get the internal data for the layer;
593 * will return NULL for fake layers (eg. wayland)
595 if (e_comp->layers[cw->layer].obj)
597 if (evas_object_smart_smart_get(e_comp->layers[cw->layer].obj))
598 layer_cw = evas_object_smart_data_get(e_comp->layers[cw->layer].obj);
600 if (layer_cw == cw) layer_cw = NULL;
602 e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
604 e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
605 if ((!above) && (!below))
608 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
610 e_comp->layers[cw->layer].clients = eina_inlist_prepend_relative(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(layer_cw->ec));
611 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
612 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
614 e_comp->layers[cw->layer].clients_count++;
615 #ifndef E_RELEASE_BUILD
618 E_Client *below_ec = e_client_below_get(cw->ec);
621 if (e_comp->layers[cw->layer].obj == below_ec->frame)
622 CRI("ACK! ec:%p", cw->ec);
629 _e_comp_object_layers_remove(E_Comp_Object *cw)
631 if (cw->ec && e_comp->layers[cw->layer].clients)
633 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
634 e_comp->layers[cw->layer].clients_count--;
637 e_comp->layers[cw->layer].objs = eina_inlist_remove(e_comp->layers[cw->layer].objs, EINA_INLIST_GET(cw));
638 e_comp->layers[cw->layer].objs_count--;
642 /////////////////////////////////////
644 _e_comp_object_alpha_set(E_Comp_Object *cw)
646 Eina_Bool alpha = cw->ec->argb;
648 if ((cw->external_content) &&
649 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
654 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
655 if (cw->user_alpha_set) alpha = cw->user_alpha;
657 evas_object_image_alpha_set(cw->obj, alpha);
661 _e_comp_object_shadow(E_Comp_Object *cw)
663 if (e_client_util_shadow_state_get(cw->ec))
664 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
666 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
667 if (cw->frame_object)
668 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
669 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
672 /* convert from the surface coordinates to the buffer coordinates */
674 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
676 E_Comp_Wl_Buffer_Viewport *vp;
677 E_Comp_Wl_Client_Data *cdata;
681 cdata = e_client_cdata_get(ec);
683 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
690 vp = &cdata->scaler.buffer_viewport;
691 transform = e_comp_wl_output_buffer_transform_get(ec);
693 e_pixmap_size_get(ec->pixmap, &bw, &bh);
695 /* for subsurface, it should be swap 90 and 270 */
696 if (e_comp_wl_subsurface_check(ec))
699 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
700 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
701 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
702 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
708 case WL_OUTPUT_TRANSFORM_NORMAL:
709 default: tx = sx, ty = sy; break;
710 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
711 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
712 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
713 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
714 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
715 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
716 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
719 tx *= vp->buffer.scale;
720 ty *= vp->buffer.scale;
727 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
735 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
736 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
743 if (dw) *dw = MAX(x1, x2) - mx;
744 if (dh) *dh = MAX(y1, y2) - my;
748 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
749 int *dx, int *dy, int *dw, int *dh)
751 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
752 E_Util_Transform_Rect_Vertex sv, dv;
756 e_pixmap_size_get(ec->pixmap, &bw, &bh);
758 sv = e_util_transform_rect_to_vertices(&rect);
760 for (i = 0; i < 4; i++)
762 double x = 0.0, y = 0.0;
764 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
766 /* if evas decide coordinate is outside of map, it returns (0, 0)
767 in this case, full damage is added.
769 if ((i != 0) && (x == 0.0) && (y == 0.0))
772 dv.vertices[i].vertex[0] = x;
773 dv.vertices[i].vertex[1] = y;
774 dv.vertices[i].vertex[2] = 1.0;
775 dv.vertices[i].vertex[3] = 1.0;
778 rect = e_util_transform_vertices_to_rect(&dv);
780 if (dx) *dx = rect.x;
781 if (dy) *dy = rect.y;
782 if (dw) *dw = rect.w;
783 if (dh) *dh = rect.h;
797 _e_comp_object_map_damage_transform_get(E_Client *ec)
804 if (!evas_object_map_enable_get(ec->frame))
807 m = e_client_map_get(ec);
811 e_pixmap_size_get(ec->pixmap, &bw, &bh);
812 if ((bw == 0) || (bh == 0))
825 e_map_point_coord_set(m2, 0, 0, 0, 0);
826 e_map_point_coord_set(m2, 1, bw, 0, 0);
827 e_map_point_coord_set(m2, 2, bw, bh, 0);
828 e_map_point_coord_set(m2, 3, 0, bh, 0);
830 for (i = 0; i < 4; i++)
834 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
835 e_map_point_image_uv_set(m2, i, map_x, map_y);
842 /////////////////////////////////////
844 /* handle evas mouse-in events on client object */
846 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
848 Evas_Event_Mouse_In *ev = event_info;
849 E_Comp_Object *cw = data;
851 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
854 /* handle evas mouse-out events on client object */
856 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
858 Evas_Event_Mouse_Out *ev = event_info;
859 E_Comp_Object *cw = data;
861 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
864 /* handle evas mouse wheel events on client object */
866 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
868 Evas_Event_Mouse_Wheel *ev = event_info;
869 E_Comp_Object *cw = data;
870 E_Binding_Event_Wheel ev2;
873 if (e_client_action_get()) return;
874 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
875 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
878 /* handle evas mouse down events on client object */
880 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
882 Evas_Event_Mouse_Down *ev = event_info;
883 E_Comp_Object *cw = data;
884 E_Binding_Event_Mouse_Button ev2;
887 if (e_client_action_get()) return;
888 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
889 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
892 /* handle evas mouse up events on client object */
894 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
896 Evas_Event_Mouse_Up *ev = event_info;
897 E_Comp_Object *cw = data;
898 E_Binding_Event_Mouse_Button ev2;
901 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
902 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
903 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
906 /* handle evas mouse movement events on client object */
908 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
910 Evas_Event_Mouse_Move *ev = event_info;
911 E_Comp_Object *cw = data;
914 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
915 e_client_mouse_move(cw->ec, &ev->cur.output);
917 /////////////////////////////////////
919 /* helper function for checking compositor themes based on user-defined matches */
921 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
923 if (((m->title) && (!ec->netwm.name)) ||
924 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
926 #if defined(__cplusplus) || defined(c_plusplus)
927 if (((m->clas) && (!ec->icccm.cpp_class)) ||
928 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
931 if (((m->clas) && (!ec->icccm.class)) ||
932 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
936 if (((m->role) && (!ec->icccm.window_role)) ||
937 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
943 if ((int)ec->netwm.type != m->primary_type)
946 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
949 if (m->borderless != 0)
953 if (e_client_util_borderless(ec))
955 if (!(((m->borderless == -1) && (!borderless)) ||
956 ((m->borderless == 1) && (borderless))))
963 if (((ec->icccm.transient_for != 0) ||
966 if (!(((m->dialog == -1) && (!dialog)) ||
967 ((m->dialog == 1) && (dialog))))
970 if (m->accepts_focus != 0)
972 int accepts_focus = 0;
974 if (ec->icccm.accepts_focus)
976 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
977 ((m->accepts_focus == 1) && (accepts_focus))))
986 if (!(((m->vkbd == -1) && (!vkbd)) ||
987 ((m->vkbd == 1) && (vkbd))))
992 if (!(((m->argb == -1) && (!ec->argb)) ||
993 ((m->argb == 1) && (ec->argb))))
996 if (m->fullscreen != 0)
998 int fullscreen = ec->fullscreen;
1000 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1001 ((m->fullscreen == 1) && (fullscreen))))
1008 if (ec->netwm.state.modal)
1010 if (!(((m->modal == -1) && (!modal)) ||
1011 ((m->modal == 1) && (modal))))
1017 /* function for setting up a client's compositor frame theme (cw->shobj) */
1019 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1023 Eina_List *list = NULL, *l;
1024 E_Input_Rect_Data *input_rect_data;
1025 E_Input_Rect_Smart_Data *input_rect_sd;
1027 Eina_Stringshare *reshadow_group = NULL;
1028 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1029 Eina_Stringshare *name, *title;
1030 E_Comp_Config *conf = e_comp_config_get();
1032 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1033 /* match correct client type */
1034 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1035 name = cw->ec->icccm.name;
1036 title = cw->ec->icccm.title;
1037 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1038 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1040 /* skipping here is mostly a hack for systray because I hate it */
1043 EINA_LIST_FOREACH(list, l, m)
1045 if (((m->name) && (!name)) ||
1046 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1048 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1052 no_shadow = m->no_shadow;
1053 if (m->shadow_style)
1055 /* fast effects are just themes with "/fast" appended and shorter effect times */
1058 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1059 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1061 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1063 /* default to non-fast style if fast not available */
1066 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1067 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1069 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1071 if (ok && m->visibility_effect)
1072 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1079 if (skip || (cw->ec->e.state.video))
1081 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1086 if (conf->shadow_style)
1090 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1091 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1093 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1097 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1098 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1107 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1109 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1120 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1125 if (cw->ec->override)
1127 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1128 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1130 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1131 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1137 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1138 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1141 _e_comp_object_shadow(cw);
1144 if (focus || cw->ec->focused || cw->ec->override)
1145 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1147 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1148 if (urgent || cw->ec->urgent)
1149 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1158 /* visibility must always be enabled for re_manage clients to prevent
1159 * pop-in animations every time the user sees a persistent client again;
1160 * applying visibility for iconic clients prevents the client from getting
1163 if (cw->visible || cw->ec->re_manage)
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1168 /* breaks animation counter */
1169 if (cw->frame_object)
1171 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1172 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1184 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1187 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1189 if (input_rect_data->obj)
1191 pass_event_flag = EINA_TRUE;
1197 if (cw->indicator.obj)
1199 Evas_Object *indicator;
1200 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1201 if (indicator != cw->indicator.obj)
1203 edje_object_part_unswallow(cw->shobj, indicator);
1204 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1205 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1209 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1210 evas_object_pass_events_set(cw->obj, pass_event_flag);
1215 /////////////////////////////////////////////
1218 _e_comp_object_animating_begin(E_Comp_Object *cw)
1221 if (cw->animating == 1)
1223 e_comp->animating++;
1225 e_object_ref(E_OBJECT(cw->ec));
1230 _e_comp_object_animating_end(E_Comp_Object *cw)
1239 if (cw->ec->launching)
1241 if (!cw->ec->extra_animating)
1243 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1244 cw->ec->launching = EINA_FALSE;
1245 if (cw->ec->first_mapped)
1247 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1248 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1251 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1255 e_comp->animating--;
1256 cw->showing = cw->hiding = 0;
1258 if (e_comp->animating == 0)
1259 e_client_visibility_calculate();
1260 /* remove ref from animation start, account for possibility of deletion from unref */
1261 return !!e_object_unref(E_OBJECT(cw->ec));
1267 /* handle the end of a compositor animation */
1269 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1271 E_Comp_Object *cw = data;
1273 /* visible clients which have never been sized are a bug */
1274 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1275 CRI("ACK! ec:%p", cw->ec);
1276 if (!_e_comp_object_animating_end(cw)) return;
1277 if (cw->animating) return;
1278 /* hide only after animation finishes to guarantee a full run of the animation */
1279 if (cw->defer_hide && ((!strcmp(emission, "e,action,hide,done")) || (!strcmp(emission, "e,action,done"))))
1280 evas_object_hide(cw->smart_obj);
1283 /* run a visibility compositor effect if available, return false if object is dead */
1285 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1290 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1291 if (!cw->effect_running)
1292 _e_comp_object_animating_begin(cw);
1293 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1294 return _e_comp_object_animating_end(cw);
1295 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1296 return _e_comp_object_animating_end(cw);
1298 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1302 zw = cw->ec->zone->w, zh = cw->ec->zone->h;
1307 zone = e_comp_object_util_zone_get(cw->smart_obj);
1308 if (!zone) zone = e_zone_current_get();
1315 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1316 cw->w, cw->h, zw, zh, x, y}, 8);
1317 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1318 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1321 /////////////////////////////////////////////
1323 /* create necessary objects for clients that e manages */
1325 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1327 if (cw->set_mouse_callbacks) return;
1328 if (!cw->smart_obj) return;
1330 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1331 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1332 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1337 cw->set_mouse_callbacks = EINA_TRUE;
1341 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1343 if (!cw->set_mouse_callbacks) return;
1344 if (!cw->smart_obj) return;
1346 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1347 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1348 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1353 cw->set_mouse_callbacks = EINA_FALSE;
1357 _e_comp_object_setup(E_Comp_Object *cw)
1359 cw->clip = evas_object_rectangle_add(e_comp->evas);
1360 evas_object_move(cw->clip, -9999, -9999);
1361 evas_object_resize(cw->clip, 999999, 999999);
1362 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1363 cw->effect_obj = edje_object_add(e_comp->evas);
1364 evas_object_move(cw->effect_obj, cw->x, cw->y);
1365 evas_object_clip_set(cw->effect_obj, cw->clip);
1366 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1367 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1368 cw->shobj = edje_object_add(e_comp->evas);
1369 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1370 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1371 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1373 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1374 if (cw->ec->override)
1376 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1377 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1378 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1380 else if (!cw->ec->input_only)
1382 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1383 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1384 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1386 cw->real_hid = !cw->ec->input_only;
1387 if (!cw->ec->input_only)
1389 e_util_size_debug_set(cw->effect_obj, 1);
1390 _e_comp_object_mouse_event_callback_set(cw);
1393 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1394 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1395 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1396 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1397 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1398 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1400 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1403 /////////////////////////////////////////////
1405 /* for fast path evas rendering; only called during render */
1407 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1409 E_Comp_Object *cw = data;
1410 E_Client *ec = cw->ec;
1412 int bx, by, bxx, byy;
1414 if (e_object_is_del(E_OBJECT(ec))) return;
1415 if (cw->external_content) return;
1416 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1417 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1420 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1421 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1423 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1425 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1426 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1430 bx = by = bxx = byy = 0;
1431 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1434 Edje_Message_Int_Set *msg;
1435 Edje_Message_Int msg2;
1436 Eina_Bool id = (bx || by || bxx || byy);
1438 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1444 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1446 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1450 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1451 e_comp_client_post_update_add(cw->ec);
1453 else if (e_comp_object_render(ec->frame))
1455 /* apply shape mask if necessary */
1456 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1457 e_comp_object_shape_apply(ec->frame);
1458 ec->shape_changed = 0;
1460 /* shaped clients get precise mouse events to handle transparent pixels */
1461 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1463 /* queue another render if client is still dirty; cannot refresh here. */
1464 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1465 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1467 if (cw->render_trace)
1469 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1475 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1477 E_Comp_Object *cw = data;
1478 E_Client *ec = cw->ec;
1480 if (e_object_is_del(E_OBJECT(ec))) return;
1481 if (cw->external_content) return;
1482 if (!e_comp->hwc) return;
1484 e_comp_client_render_list_add(cw->ec);
1486 if (!ec->hwc_window) return;
1488 e_hwc_windows_rendered_window_add(ec->hwc_window);
1491 /////////////////////////////////////////////
1494 _e_comp_object_client_pending_resize_add(E_Client *ec,
1497 unsigned int serial)
1499 E_Client_Pending_Resize *pnd;
1501 pnd = E_NEW(E_Client_Pending_Resize, 1);
1505 pnd->serial = serial;
1506 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1510 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1512 E_Comp_Object *cw = data;
1515 if (cw->render_update_lock.lock)
1517 cw->render_update_lock.pending_move_x = x;
1518 cw->render_update_lock.pending_move_y = y;
1519 cw->render_update_lock.pending_move_set = EINA_TRUE;
1523 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1524 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1525 (cw->external_content))
1527 /* delay to move until the external content is unset */
1528 cw->ec->changes.pos = 1;
1533 if (cw->ec->move_after_resize)
1535 if ((x != cw->ec->x) || (y != cw->ec->y))
1537 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1538 e_client_pos_set(cw->ec, x, y);
1539 cw->ec->changes.pos = 1;
1545 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1546 (cw->ec->manage_resize.resize_obj))
1548 e_client_pos_set(cw->ec, x, y);
1549 cw->ec->client.x = x + cw->client_inset.l;
1550 cw->ec->client.y = y + cw->client_inset.t;
1551 e_policy_visibility_client_defer_move(cw->ec);
1555 /* if frame_object does not exist, client_inset indicates CSD.
1556 * this means that ec->client matches cw->x/y, the opposite
1559 fx = (!cw->frame_object) * cw->client_inset.l;
1560 fy = (!cw->frame_object) * cw->client_inset.t;
1561 if ((cw->x == x + fx) && (cw->y == y + fy))
1563 if ((cw->ec->x != x) || (cw->ec->y != y))
1565 /* handle case where client tries to move to position and back very quickly */
1566 e_client_pos_set(cw->ec, x, y);
1567 cw->ec->client.x = x + cw->client_inset.l;
1568 cw->ec->client.y = y + cw->client_inset.t;
1572 if (!cw->ec->maximize_override)
1574 /* prevent moving in some directions while directionally maximized */
1575 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1577 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1580 ix = x + cw->client_inset.l;
1581 iy = y + cw->client_inset.t;
1582 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1583 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1584 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1586 /* prevent moving at all if move isn't allowed in current maximize state */
1587 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1588 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1589 if ((!cw->ec->shading) && (!cw->ec->shaded))
1591 cw->ec->changes.need_unmaximize = 1;
1592 cw->ec->saved.x = ix - cw->ec->zone->x;
1593 cw->ec->saved.y = iy - cw->ec->zone->y;
1594 cw->ec->saved.w = cw->ec->client.w;
1595 cw->ec->saved.h = cw->ec->client.h;
1601 /* only update during resize if triggered by resize */
1602 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1603 /* delay to move while surface waits paired commit serial*/
1604 if (e_client_pending_geometry_has(cw->ec))
1606 /* do nothing while waiting paired commit serial*/
1610 e_client_pos_set(cw->ec, x, y);
1611 if (cw->ec->new_client)
1613 /* don't actually do anything until first client idler loop */
1614 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1615 cw->ec->changes.pos = 1;
1620 /* only update xy position of client to avoid invalid
1621 * first damage region if it is not a new_client. */
1622 if (!cw->ec->shading)
1624 cw->ec->client.x = ix;
1625 cw->ec->client.y = iy;
1628 if (!cw->frame_object)
1630 evas_object_move(obj, x, y);
1635 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1637 E_Comp_Object *cw = data;
1638 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1640 if (cw->render_update_lock.lock)
1642 cw->render_update_lock.pending_resize_w = w;
1643 cw->render_update_lock.pending_resize_h = h;
1644 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1648 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1650 e_client_size_set(cw->ec, w, h);
1651 evas_object_resize(obj, w, h);
1655 /* if frame_object does not exist, client_inset indicates CSD.
1656 * this means that ec->client matches cw->w/h, the opposite
1659 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1660 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1661 if ((cw->w == w + fw) && (cw->h == h + fh))
1663 if (cw->ec->shading || cw->ec->shaded) return;
1664 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1665 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1666 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1668 /* handle case where client tries to resize itself and back very quickly */
1669 e_client_size_set(cw->ec, w, h);
1670 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1671 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1672 evas_object_smart_callback_call(obj, "client_resize", NULL);
1676 /* guarantee that fullscreen is fullscreen */
1677 if (cw->ec->fullscreen && ((w != cw->ec->zone->w) || (h != cw->ec->zone->h)))
1679 /* calculate client size */
1680 iw = w - cw->client_inset.l - cw->client_inset.r;
1681 ih = h - cw->client_inset.t - cw->client_inset.b;
1682 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1684 /* prevent resizing while maximized depending on direction and config */
1685 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1686 if ((!cw->ec->shading) && (!cw->ec->shaded))
1688 Eina_Bool reject = EINA_FALSE;
1689 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1691 if (cw->ec->client.h != ih)
1693 cw->ec->saved.h = ih;
1694 cw->ec->saved.y = cw->ec->client.y - cw->ec->zone->y;
1695 reject = cw->ec->changes.need_unmaximize = 1;
1698 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1700 if (cw->ec->client.w != iw)
1702 cw->ec->saved.w = iw;
1703 cw->ec->saved.x = cw->ec->client.x - cw->ec->zone->x;
1704 reject = cw->ec->changes.need_unmaximize = 1;
1714 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1716 /* do nothing until client idler loops */
1717 if ((cw->ec->w != w) || (cw->ec->h != h))
1719 e_client_size_set(cw->ec, w, h);
1720 cw->ec->changes.size = 1;
1725 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1726 ((cw->ec->w != w) || (cw->ec->h != h)))
1729 /* netwm sync resizes queue themselves and then trigger later on */
1730 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1732 if (e_client_pending_geometry_has(cw->ec))
1734 /* do nothing while waiting paired commit serial*/
1738 e_client_size_set(cw->ec, w, h);
1739 if ((!cw->ec->shading) && (!cw->ec->shaded))
1741 /* client geom never changes when shading since the client is never altered */
1742 cw->ec->client.w = iw;
1743 cw->ec->client.h = ih;
1744 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1747 /* The size of non-compositing window can be changed, so there is a
1748 * need to check that cw is H/W composited if cw is not redirected.
1749 * And of course we have to change size of evas object of H/W composited cw,
1750 * otherwise cw can't receive input events even if it is shown on the screen.
1752 Eina_Bool redirected = cw->redirected;
1754 redirected = e_comp_is_on_overlay(cw->ec);
1756 if ((!cw->ec->input_only) && (redirected) &&
1757 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1758 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1759 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1760 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1763 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1764 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1766 prev_w = cw->w, prev_h = cw->h;
1767 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1768 /* check shading and clamp to pixmap size for regular clients */
1769 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1770 (((w - fw != pw) || (h - fh != ph))))
1772 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1773 evas_object_smart_callback_call(obj, "client_resize", NULL);
1775 if (cw->frame_object || cw->ec->input_only)
1776 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1779 if ((cw->w == w) && (cw->h == h))
1781 /* going to be a noop resize which won't trigger smart resize */
1782 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1783 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1785 evas_object_resize(obj, w, h);
1789 evas_object_smart_callback_call(obj, "client_resize", NULL);
1792 if ((!cw->frame_object) && (!cw->ec->input_only))
1794 /* "just do it" for overrides */
1795 evas_object_resize(obj, w, h);
1797 if (!cw->ec->override)
1799 /* shape probably changed for non-overrides */
1800 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1801 cw->ec->need_shape_export |= cw->ec->shaped;
1802 if (cw->ec->shaped || cw->ec->shaped_input)
1806 /* this fixes positioning jiggles when using a resize mode
1807 * which also changes the client's position
1810 if (cw->frame_object)
1811 x = cw->x, y = cw->y;
1813 x = cw->ec->x, y = cw->ec->y;
1814 switch (cw->ec->resize_mode)
1816 case E_POINTER_RESIZE_BL:
1817 case E_POINTER_RESIZE_L:
1818 evas_object_move(obj, x + prev_w - cw->w, y);
1820 case E_POINTER_RESIZE_TL:
1821 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1823 case E_POINTER_RESIZE_T:
1824 case E_POINTER_RESIZE_TR:
1825 evas_object_move(obj, x, y + prev_h - cw->h);
1834 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1836 E_Comp_Object *cw = data;
1837 E_Comp_Wl_Client_Data *child_cdata;
1838 unsigned int l = e_comp_canvas_layer_map(layer);
1841 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1843 /* doing a compositor effect, follow directions */
1844 _e_comp_object_layer_set(obj, layer);
1845 if (layer == cw->ec->layer) //trying to put layer back
1849 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1850 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1851 if (cw->layer != l) goto layer_set;
1855 e_comp_render_queue();
1857 ec = e_client_above_get(cw->ec);
1858 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1859 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1860 ec = e_client_above_get(ec);
1861 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1863 ec = e_client_below_get(cw->ec);
1864 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1865 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1866 ec = e_client_below_get(ec);
1867 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1869 evas_object_stack_above(obj, ec->frame);
1874 if (ec && (cw->ec->parent == ec))
1876 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1877 evas_object_stack_above(obj, ec->frame);
1879 evas_object_stack_below(obj, ec->frame);
1882 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1888 if (cw->layer == l) return;
1889 if (e_comp_canvas_client_layer_map(layer) == 9999)
1890 return; //invalid layer for clients not doing comp effects
1891 if (cw->ec->fullscreen)
1893 cw->ec->saved.layer = layer;
1896 oldraise = e_config->transient.raise;
1898 /* clamp to valid client layer */
1899 layer = e_comp_canvas_client_layer_map_nearest(layer);
1900 cw->ec->layer = layer;
1901 if (e_config->transient.layer)
1904 Eina_List *list = eina_list_clone(cw->ec->transients);
1906 /* We need to set raise to one, else the child wont
1907 * follow to the new layer. It should be like this,
1908 * even if the user usually doesn't want to raise
1911 e_config->transient.raise = 1;
1912 EINA_LIST_FREE(list, child)
1914 child_cdata = e_client_cdata_get(child);
1915 if (child_cdata && !child_cdata->mapped)
1917 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1920 e_client_layer_set(child, layer);
1924 e_config->transient.raise = oldraise;
1926 _e_comp_object_layers_remove(cw);
1927 cw->layer = e_comp_canvas_layer_map(layer);
1928 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1929 //if (cw->ec->new_client)
1930 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1931 _e_comp_object_layer_set(obj, layer);
1932 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1933 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1934 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1936 /* can't stack a client above its own layer marker */
1937 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1939 if (!cw->visible) return;
1940 e_comp_render_queue();
1941 _e_comp_object_transform_obj_stack_update(obj);
1944 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1947 _e_comp_object_raise(Evas_Object *obj)
1949 evas_object_raise(obj);
1951 if (evas_object_smart_smart_get(obj))
1953 E_Client *ec = e_comp_object_client_get(obj);
1955 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1960 _e_comp_object_lower(Evas_Object *obj)
1962 evas_object_lower(obj);
1964 if (evas_object_smart_smart_get(obj))
1966 E_Client *ec = e_comp_object_client_get(obj);
1968 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1973 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1975 evas_object_stack_above(obj, target);
1977 if (evas_object_smart_smart_get(obj))
1979 E_Client *ec = e_comp_object_client_get(obj);
1981 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1986 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1988 evas_object_stack_below(obj, target);
1990 if (evas_object_smart_smart_get(obj))
1992 E_Client *ec = e_comp_object_client_get(obj);
1994 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1999 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2001 evas_object_layer_set(obj, layer);
2003 if (evas_object_smart_smart_get(obj))
2005 E_Client *ec = e_comp_object_client_get(obj);
2007 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2012 _e_comp_object_is_pending(E_Client *ec)
2016 if (!ec) return EINA_FALSE;
2018 topmost = e_comp_wl_topmost_parent_get(ec);
2020 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2024 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2026 E_Comp_Object *cw2 = NULL;
2029 Evas_Object *o = stack;
2030 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2032 /* We should consider topmost's layer_pending for subsurface */
2033 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2035 if (_e_comp_object_is_pending(cw->ec))
2036 e_comp_object_layer_update(cw->smart_obj,
2037 raising? stack : NULL,
2038 raising? NULL : stack);
2040 /* obey compositor effects! */
2041 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2042 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2043 stack_cb(cw->smart_obj, stack);
2044 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2045 evas_object_data_del(cw->smart_obj, "client_restack");
2049 cw2 = evas_object_data_get(o, "comp_obj");
2051 /* assume someone knew what they were doing during client init */
2052 if (cw->ec->new_client)
2053 layer = cw->ec->layer;
2054 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2055 layer = cw2->ec->layer;
2057 layer = evas_object_layer_get(stack);
2058 ecstack = e_client_below_get(cw->ec);
2059 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2061 /* some FOOL is trying to restack a layer marker */
2062 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2063 evas_object_layer_set(cw->smart_obj, layer);
2064 /* we got our layer wrangled, return now! */
2065 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2068 /* check if we're stacking below another client */
2071 /* check for non-client layer object */
2072 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2074 /* find an existing client to use for layering
2075 * by walking up the object stack
2077 * this is guaranteed to be pretty quick since we'll either:
2078 * - run out of client layers
2079 * - find a stacking client
2081 o = evas_object_above_get(o);
2082 if ((!o) || (o == cw->smart_obj)) break;
2083 if (evas_object_layer_get(o) != layer)
2085 /* reached the top client layer somehow
2086 * use top client object
2088 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2091 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2092 * return here since the top client layer window
2097 ec = e_client_top_get();
2102 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2105 if (cw2 && cw->layer != cw2->layer)
2108 /* remove existing layers */
2109 _e_comp_object_layers_remove(cw);
2112 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2113 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2114 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2115 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2116 else //if no stacking objects found, either raise or lower
2117 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2120 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2122 /* find new object for stacking if cw2 is on state of layer_pending */
2123 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2125 E_Client *new_stack = NULL, *current_ec = NULL;
2126 current_ec = cw2->ec;
2129 while ((new_stack = e_client_below_get(current_ec)))
2131 current_ec = new_stack;
2132 if (new_stack == cw->ec) continue;
2133 if (new_stack->layer != cw2->ec->layer) break;
2134 if (!_e_comp_object_is_pending(new_stack)) break;
2136 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2137 stack = new_stack->frame;
2140 /* stack it above layer object */
2142 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2143 stack = e_comp->layers[below_layer].obj;
2148 while ((new_stack = e_client_above_get(current_ec)))
2150 current_ec = new_stack;
2151 if (new_stack == cw->ec) continue;
2152 if (new_stack->layer != cw2->ec->layer) break;
2153 if (!_e_comp_object_is_pending(new_stack)) break;
2155 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2156 stack = new_stack->frame;
2158 stack = e_comp->layers[cw2->layer].obj;
2162 /* set restack if stacking has changed */
2163 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2164 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2165 stack_cb(cw->smart_obj, stack);
2166 if (e_comp->layers[cw->layer].obj)
2167 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2169 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2171 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2172 evas_object_data_del(cw->smart_obj, "client_restack");
2173 if (!cw->visible) return;
2174 e_comp_render_queue();
2178 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2180 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2182 if (evas_object_below_get(obj) == above)
2184 e_comp_object_layer_update(obj, above, NULL);
2188 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2189 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2190 _e_comp_object_transform_obj_stack_update(obj);
2191 _e_comp_object_transform_obj_stack_update(above);
2196 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2198 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2199 if (evas_object_above_get(obj) == below)
2201 e_comp_object_layer_update(obj, NULL, below);
2205 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2206 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2207 if (evas_object_smart_smart_get(obj))
2208 _e_comp_object_transform_obj_stack_update(obj);
2209 if (evas_object_smart_smart_get(below))
2210 _e_comp_object_transform_obj_stack_update(below);
2215 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2217 E_Comp_Object *cw = data;
2220 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2222 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2224 if (cw->ec->layer_pending)
2225 e_comp_object_layer_update(obj, NULL, obj);
2227 _e_comp_object_lower(obj);
2230 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2231 o = evas_object_below_get(obj);
2232 _e_comp_object_layers_remove(cw);
2233 /* prepend to client list since this client should be the first item now */
2234 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2235 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2236 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2237 evas_object_data_set(obj, "client_restack", (void*)1);
2238 _e_comp_object_lower(obj);
2239 evas_object_data_del(obj, "client_restack");
2240 if (!cw->visible) goto end;
2241 e_comp_render_queue();
2242 _e_comp_object_transform_obj_stack_update(obj);
2245 if (!cw->ec->post_lower)
2246 e_client_focus_stack_lower(cw->ec);
2251 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2253 E_Comp_Object *cw = data;
2256 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2258 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2260 if (cw->ec->layer_pending)
2262 int obj_layer = evas_object_layer_get(obj);
2263 if (cw->ec->layer != obj_layer)
2264 e_comp_object_layer_update(obj, NULL, NULL);
2267 _e_comp_object_raise(obj);
2270 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2271 o = evas_object_above_get(obj);
2273 E_Client *ecabove = e_client_above_get(cw->ec);
2274 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2275 (ecabove->frame == o)) goto end; //highest below marker
2277 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2278 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2279 _e_comp_object_raise(obj);
2284 /* still stack below override below the layer marker */
2285 for (op = o = e_comp->layers[cw->layer].obj;
2286 o && o != e_comp->layers[cw->layer - 1].obj;
2287 op = o, o = evas_object_below_get(o))
2289 if (evas_object_smart_smart_get(o))
2293 ec = e_comp_object_client_get(o);
2294 if (ec && (!ec->override)) break;
2297 _e_comp_object_stack_below(obj, op);
2298 e_client_focus_defer_set(cw->ec);
2300 if (!cw->visible) goto end;
2301 e_comp_render_queue();
2302 _e_comp_object_transform_obj_stack_update(obj);
2309 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2311 E_Comp_Object *cw = data;
2313 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2314 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2316 ELOGF("COMP", "Hide. intercepted", cw->ec);
2321 if (cw->ec->launching == EINA_TRUE)
2323 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2324 cw->ec->launching = EINA_FALSE;
2329 /* hidden flag = just do it */
2330 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2331 evas_object_hide(obj);
2335 if (cw->ec->input_only)
2337 /* input_only = who cares */
2338 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2339 evas_object_hide(obj);
2342 /* already hidden or currently animating */
2343 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2345 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2349 /* don't try hiding during shutdown */
2350 cw->defer_hide |= stopping;
2351 if (!cw->defer_hide)
2353 if ((!cw->ec->iconic) && (!cw->ec->override))
2354 /* unset delete requested so the client doesn't break */
2355 cw->ec->delete_requested = 0;
2356 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2358 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2359 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2362 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2365 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2367 _e_comp_object_animating_begin(cw);
2368 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2370 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2371 cw->defer_hide = !!cw->animating;
2373 e_comp_object_effect_set(obj, NULL);
2376 if (cw->animating) return;
2377 /* if we have no animations running, go ahead and hide */
2379 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2380 evas_object_hide(obj);
2384 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2386 E_Client *ec = cw->ec;
2389 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2391 if (ec->show_pending.count > 0)
2393 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2394 ec->show_pending.running = EINA_TRUE;
2398 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2399 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2401 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2406 ELOGF("COMP", "show_helper. cw(v:%d,a:%d,dh:%d,ct:%d,u:%p,s(%d,%d)), ec(i:%d(%d,%d),o:%d,g:%d,n:%d)", ec,
2407 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2408 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2411 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2414 if (ec->iconic && cw->animating)
2416 /* triggered during iconify animation */
2417 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2420 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2423 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2424 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2426 evas_object_move(cw->smart_obj, ec->x, ec->y);
2427 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2428 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2430 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2431 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2434 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2435 evas_object_show(cw->smart_obj);
2438 e_client_focus_defer_set(ec);
2442 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2446 pw = ec->client.w, ph = ec->client.h;
2448 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2450 ec->changes.visible = !ec->hidden;
2453 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2457 cw->updates = eina_tiler_new(pw, ph);
2460 ec->changes.visible = !ec->hidden;
2463 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2468 eina_tiler_tile_size_set(cw->updates, 1, 1);
2471 /* ignore until client idler first run */
2472 ec->changes.visible = !ec->hidden;
2475 ELOGF("COMP", "show_helper. return. new_client", ec);
2482 evas_object_move(cw->smart_obj, ec->x, ec->y);
2483 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2484 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2485 evas_object_show(cw->smart_obj);
2488 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2490 /* start_drag not received */
2491 ec->changes.visible = 1;
2494 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2497 /* re-set geometry */
2498 evas_object_move(cw->smart_obj, ec->x, ec->y);
2499 /* force resize in case it hasn't happened yet, or just to update size */
2500 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2501 if ((cw->w < 1) || (cw->h < 1))
2503 /* if resize didn't go through, try again */
2504 ec->visible = ec->changes.visible = 1;
2506 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2509 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2510 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2511 e_pixmap_clear(ec->pixmap);
2513 if (cw->real_hid && w && h)
2516 /* force comp theming in case it didn't happen already */
2517 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2518 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2519 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2522 /* only do the show if show is allowed */
2525 if (ec->internal) //internal clients render when they feel like it
2526 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2528 if (!e_client_is_iconified_by_client(ec)||
2529 e_policy_visibility_client_is_uniconic(ec))
2531 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2532 evas_object_show(cw->smart_obj);
2534 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2535 it is rendered in idle callback without native surface and
2536 compositor shows an empty frame if other objects aren't shown
2537 because job callback of e_comp called at the next loop.
2538 it causes a visual defect when windows are switched.
2542 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2543 e_comp_object_dirty(cw->smart_obj);
2544 e_comp_object_render(cw->smart_obj);
2548 e_policy_visibility_client_is_uniconic(ec))
2550 if (ec->exp_iconify.not_raise &&
2551 e_client_check_above_focused(ec))
2552 e_client_focus_stack_append_current_focused(ec);
2554 e_client_focus_defer_set(ec);
2561 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2563 E_Comp_Object *cw = data;
2564 E_Client *ec = cw->ec;
2566 E_Input_Rect_Data *input_rect_data;
2567 E_Input_Rect_Smart_Data *input_rect_sd;
2570 if (ec->ignored) return;
2574 //INF("SHOW2 %p", ec);
2575 _e_comp_intercept_show_helper(cw);
2578 //INF("SHOW %p", ec);
2581 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2582 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2583 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2584 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2588 if ((!cw->obj) && (cw->external_content))
2590 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2594 _e_comp_object_setup(cw);
2597 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2598 cw->obj = evas_object_image_filled_add(e_comp->evas);
2599 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2600 e_util_size_debug_set(cw->obj, 1);
2601 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2602 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2603 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2604 evas_object_name_set(cw->obj, "cw->obj");
2605 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2607 _e_comp_object_alpha_set(cw);
2610 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2613 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2614 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2617 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2620 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2622 if (input_rect_data->obj)
2624 evas_object_geometry_set(input_rect_data->obj,
2625 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2626 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2627 input_rect_data->rect.w, input_rect_data->rect.h);
2634 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2636 _e_comp_intercept_show_helper(cw);
2640 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2642 E_Comp_Object *cw = data;
2646 /* note: this is here as it seems there are enough apps that do not even
2647 * expect us to emulate a look of focus but not actually set x input
2648 * focus as we do - so simply abort any focus set on such windows */
2649 /* be strict about accepting focus hint */
2650 /* be strict about accepting focus hint */
2651 if ((!ec->icccm.accepts_focus) &&
2652 (!ec->icccm.take_focus))
2656 if (e_client_focused_get() == ec)
2657 e_client_focused_set(NULL);
2659 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2660 evas_object_focus_set(obj, focus);
2664 if (focus && ec->lock_focus_out) return;
2665 if (e_object_is_del(E_OBJECT(ec)) && focus)
2666 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2668 /* filter focus setting based on current state */
2673 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2674 evas_object_focus_set(obj, focus);
2677 if ((ec->iconic) && (!ec->deskshow))
2679 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2681 /* don't focus an iconified window. that's silly! */
2682 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2683 e_client_uniconify(ec);
2684 if (e_client_focus_track_enabled())
2685 e_client_focus_latest_set(ec);
2693 if ((!ec->sticky) && (ec->desk) && (!ec->desk->visible))
2695 if (ec->desk->animate_count) return;
2696 e_desk_show(ec->desk);
2697 if (!ec->desk->visible) return;
2705 /* not yet visible, wait till the next time... */
2706 ec->want_focus = !ec->hidden;
2711 e_client_focused_set(ec);
2715 if (e_client_focused_get() == ec)
2716 e_client_focused_set(NULL);
2720 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2722 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2724 evas_object_focus_set(obj, focus);
2728 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2730 E_Comp_Object *cw = data;
2732 if (cw->transparent.set)
2734 cw->transparent.user_r = r;
2735 cw->transparent.user_g = g;
2736 cw->transparent.user_b = b;
2737 cw->transparent.user_a = a;
2739 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2741 cw->transparent.user_r,
2742 cw->transparent.user_g,
2743 cw->transparent.user_b,
2744 cw->transparent.user_a);
2748 evas_object_color_set(obj, r, g, b, a);
2751 ////////////////////////////////////////////////////
2754 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2756 int w, h, ox, oy, ow, oh;
2758 Eina_Bool pass_event_flag = EINA_FALSE;
2759 E_Input_Rect_Data *input_rect_data;
2760 E_Input_Rect_Smart_Data *input_rect_sd;
2762 if (cw->frame_object)
2764 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2765 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2766 /* set a fixed size, force edje calc, check size difference */
2767 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2768 edje_object_message_signal_process(cw->frame_object);
2769 edje_object_calc_force(cw->frame_object);
2770 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2771 cw->client_inset.l = ox;
2772 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2773 cw->client_inset.t = oy;
2774 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2775 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2776 evas_object_resize(cw->frame_object, w, h);
2780 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2783 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2785 if (input_rect_data->obj)
2787 pass_event_flag = EINA_TRUE;
2793 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2794 evas_object_pass_events_set(cw->obj, pass_event_flag);
2798 cw->client_inset.l = 0;
2799 cw->client_inset.r = 0;
2800 cw->client_inset.t = 0;
2801 cw->client_inset.b = 0;
2803 cw->client_inset.calc = !!cw->frame_object;
2807 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2809 E_Comp_Object *cw = data;
2812 /* - get current size
2814 * - readjust for new frame size
2817 w = cw->ec->w, h = cw->ec->h;
2818 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2820 _e_comp_object_frame_recalc(cw);
2822 if (!cw->ec->fullscreen)
2823 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2825 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2826 if (cw->ec->shading || cw->ec->shaded) return;
2827 if (cw->ec->fullscreen)
2828 evas_object_resize(cw->ec->frame, cw->ec->zone->w, cw->ec->zone->h);
2829 else if (cw->ec->new_client)
2831 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2832 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2833 evas_object_resize(cw->ec->frame, w, h);
2835 else if ((w != cw->ec->w) || (h != cw->ec->h))
2836 evas_object_resize(cw->ec->frame, w, h);
2840 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2842 E_Comp_Object *cw = data;
2844 if (!cw->ec) return; //NYI
2845 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2847 cw->shade.x = cw->x;
2848 cw->shade.y = cw->y;
2849 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2853 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2855 E_Comp_Object *cw = data;
2857 if (!cw->ec) return; //NYI
2858 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2860 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2864 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2866 E_Comp_Object *cw = data;
2868 if (!cw->ec) return; //NYI
2869 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2871 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2875 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2877 E_Comp_Object *cw = data;
2879 if (!cw->ec) return; //NYI
2880 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2882 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2886 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2888 E_Comp_Object *cw = data;
2890 _e_comp_object_shadow_setup(cw);
2891 if (cw->frame_object)
2893 _e_comp_object_shadow(cw);
2894 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2895 _e_comp_object_frame_recalc(cw);
2896 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2901 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2903 E_Comp_Object *cw = data;
2905 if (_e_comp_object_shadow_setup(cw))
2906 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2907 if (cw->frame_object)
2909 _e_comp_object_shadow(cw);
2910 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2911 _e_comp_object_frame_recalc(cw);
2912 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2917 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2919 E_Comp_Object *cw = data;
2921 if (cw->frame_object)
2923 _e_comp_object_shadow(cw);
2924 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2925 _e_comp_object_frame_recalc(cw);
2926 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2931 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2933 E_Comp_Object *cw = data;
2935 if (_e_comp_object_shadow_setup(cw))
2938 cw->ec->changes.size = 1;
2940 if (cw->frame_object)
2942 _e_comp_object_shadow(cw);
2943 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2944 _e_comp_object_frame_recalc(cw);
2945 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2950 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2952 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2956 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2958 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2962 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2964 E_Comp_Object *cw = data;
2966 if (!cw->ec) return; //NYI
2967 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2971 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2973 E_Comp_Object *cw = data;
2975 if (!cw->ec) return; //NYI
2976 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2980 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2982 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2986 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2988 E_Comp_Object *cw = data;
2990 if (!e_object_is_del(E_OBJECT(cw->ec)))
2991 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2995 _e_comp_input_obj_smart_add(Evas_Object *obj)
2997 E_Input_Rect_Smart_Data *input_rect_sd;
2998 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3000 if (!input_rect_sd) return;
3001 evas_object_smart_data_set(obj, input_rect_sd);
3005 _e_comp_input_obj_smart_del(Evas_Object *obj)
3007 E_Input_Rect_Smart_Data *input_rect_sd;
3008 E_Input_Rect_Data *input_rect_data;
3010 input_rect_sd = evas_object_smart_data_get(obj);
3011 if (!input_rect_sd) return;
3013 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3015 if (input_rect_data->obj)
3017 evas_object_smart_member_del(input_rect_data->obj);
3018 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3020 E_FREE(input_rect_data);
3022 E_FREE(input_rect_sd);
3026 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3028 E_Input_Rect_Smart_Data *input_rect_sd;
3029 E_Input_Rect_Data *input_rect_data;
3033 input_rect_sd = evas_object_smart_data_get(obj);
3034 if (!input_rect_sd) return;
3036 cw = input_rect_sd->cw;
3037 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3039 if (input_rect_data->obj)
3041 evas_object_geometry_set(input_rect_data->obj,
3042 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3043 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3044 input_rect_data->rect.w, input_rect_data->rect.h);
3050 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3052 E_Input_Rect_Smart_Data *input_rect_sd;
3053 E_Input_Rect_Data *input_rect_data;
3057 input_rect_sd = evas_object_smart_data_get(obj);
3058 if (!input_rect_sd) return;
3060 cw = input_rect_sd->cw;
3061 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3063 if (input_rect_data->obj)
3065 evas_object_geometry_set(input_rect_data->obj,
3066 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3067 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3068 input_rect_data->rect.w, input_rect_data->rect.h);
3074 _e_comp_input_obj_smart_show(Evas_Object *obj)
3076 E_Input_Rect_Smart_Data *input_rect_sd;
3077 E_Input_Rect_Data *input_rect_data;
3080 input_rect_sd = evas_object_smart_data_get(obj);
3081 if (!input_rect_sd) return;
3083 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3085 if (input_rect_data->obj)
3087 evas_object_show(input_rect_data->obj);
3093 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3095 E_Input_Rect_Smart_Data *input_rect_sd;
3096 E_Input_Rect_Data *input_rect_data;
3099 input_rect_sd = evas_object_smart_data_get(obj);
3100 if (!input_rect_sd) return;
3102 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3104 if (input_rect_data->obj)
3106 evas_object_hide(input_rect_data->obj);
3112 _e_comp_input_obj_smart_init(void)
3114 if (_e_comp_input_obj_smart) return;
3116 static const Evas_Smart_Class sc =
3118 INPUT_OBJ_SMART_NAME,
3119 EVAS_SMART_CLASS_VERSION,
3120 _e_comp_input_obj_smart_add,
3121 _e_comp_input_obj_smart_del,
3122 _e_comp_input_obj_smart_move,
3123 _e_comp_input_obj_smart_resize,
3124 _e_comp_input_obj_smart_show,
3125 _e_comp_input_obj_smart_hide,
3138 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3144 _e_comp_smart_add(Evas_Object *obj)
3148 cw = E_NEW(E_Comp_Object, 1);
3149 EINA_SAFETY_ON_NULL_RETURN(cw);
3151 cw->smart_obj = obj;
3152 cw->x = cw->y = cw->w = cw->h = -1;
3153 evas_object_smart_data_set(obj, cw);
3154 cw->opacity = 255.0;
3155 cw->external_content = 0;
3156 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3157 cw->transform_bg_color.r = 0;
3158 cw->transform_bg_color.g = 0;
3159 cw->transform_bg_color.b = 0;
3160 cw->transform_bg_color.a = 255;
3161 evas_object_data_set(obj, "comp_obj", cw);
3162 evas_object_move(obj, -1, -1);
3163 /* intercept ALL the callbacks! */
3164 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3165 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3166 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3167 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3168 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3169 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3170 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3171 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3172 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3173 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3174 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3176 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3177 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3178 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3179 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3181 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3182 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3183 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3184 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3186 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3187 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3189 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3190 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3192 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3194 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3195 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3199 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3202 evas_object_color_set(cw->clip, r, g, b, a);
3203 evas_object_smart_callback_call(obj, "color_set", NULL);
3208 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3211 evas_object_clip_set(cw->clip, clip);
3215 _e_comp_smart_clip_unset(Evas_Object *obj)
3218 evas_object_clip_unset(cw->clip);
3222 _e_comp_smart_hide(Evas_Object *obj)
3224 TRACE_DS_BEGIN(COMP:SMART HIDE);
3229 evas_object_hide(cw->clip);
3230 if (cw->input_obj) evas_object_hide(cw->input_obj);
3231 evas_object_hide(cw->effect_obj);
3232 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3233 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3234 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3241 /* unset native surface if current displaying buffer was destroied */
3242 if (!cw->buffer_destroy_listener.notify)
3244 Evas_Native_Surface *ns;
3245 ns = evas_object_image_native_surface_get(cw->obj);
3246 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3247 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3250 if (!cw->ec->input_only)
3252 edje_object_freeze(cw->effect_obj);
3253 edje_object_freeze(cw->shobj);
3254 edje_object_play_set(cw->shobj, 0);
3255 if (cw->frame_object)
3256 edje_object_play_set(cw->frame_object, 0);
3258 /* ensure focus-out */
3259 if (cw->ec->focused &&
3260 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3262 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3263 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3264 e_client_focus_defer_unset(cw->ec);
3266 e_comp_render_queue(); //force nocomp recheck
3272 _e_comp_smart_show(Evas_Object *obj)
3280 if ((cw->w < 0) || (cw->h < 0))
3281 CRI("ACK! ec:%p", cw->ec);
3283 TRACE_DS_BEGIN(COMP:SMART SHOW);
3285 e_comp_object_map_update(obj);
3287 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3288 evas_object_show(tmp->frame);
3290 evas_object_show(cw->clip);
3291 if (cw->input_obj) evas_object_show(cw->input_obj);
3292 if (!cw->ec->input_only)
3294 edje_object_thaw(cw->effect_obj);
3295 edje_object_thaw(cw->shobj);
3296 edje_object_play_set(cw->shobj, 1);
3297 if (cw->frame_object)
3298 edje_object_play_set(cw->frame_object, 1);
3300 evas_object_show(cw->effect_obj);
3301 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3302 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3303 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3304 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3305 e_comp_render_queue();
3306 if (cw->ec->input_only)
3311 if (cw->ec->iconic && (!cw->ec->new_client))
3313 if (e_client_is_iconified_by_client(cw->ec))
3315 ELOGF("COMP", "Set launching flag..", cw->ec);
3316 cw->ec->launching = EINA_TRUE;
3319 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3321 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3324 ELOGF("COMP", "Set launching flag..", cw->ec);
3325 cw->ec->launching = EINA_TRUE;
3327 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3328 _e_comp_object_animating_begin(cw);
3329 if (!_e_comp_object_effect_visibility_start(cw, 1))
3335 /* ensure some random effect doesn't lock the client offscreen */
3339 e_comp_object_effect_set(obj, NULL);
3342 _e_comp_object_dim_update(cw);
3348 _e_comp_smart_del(Evas_Object *obj)
3354 if (cw->buffer_destroy_listener.notify)
3356 wl_list_remove(&cw->buffer_destroy_listener.link);
3357 cw->buffer_destroy_listener.notify = NULL;
3360 if (cw->tbm_surface)
3362 tbm_surface_internal_unref(cw->tbm_surface);
3363 cw->tbm_surface = NULL;
3366 if (cw->render_update_lock.buffer_ref.buffer)
3368 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3369 cw->ec, cw->render_update_lock.lock);
3370 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3373 e_comp_object_render_update_del(cw->smart_obj);
3374 E_FREE_FUNC(cw->updates, eina_tiler_free);
3375 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3382 EINA_LIST_FREE(cw->obj_mirror, o)
3384 evas_object_image_data_set(o, NULL);
3385 evas_object_freeze_events_set(o, 1);
3386 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3390 _e_comp_object_layers_remove(cw);
3391 l = evas_object_data_get(obj, "comp_object-to_del");
3392 E_FREE_LIST(l, evas_object_del);
3393 _e_comp_object_mouse_event_callback_unset(cw);
3394 evas_object_del(cw->clip);
3395 evas_object_del(cw->effect_obj);
3396 evas_object_del(cw->shobj);
3397 evas_object_del(cw->frame_object);
3398 evas_object_del(cw->input_obj);
3399 evas_object_del(cw->obj);
3400 evas_object_del(cw->mask.obj);
3401 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3402 evas_object_del(cw->transform_bg_obj);
3403 evas_object_del(cw->transform_tranp_obj);
3404 evas_object_del(cw->default_input_obj);
3405 eina_stringshare_del(cw->frame_theme);
3406 eina_stringshare_del(cw->frame_name);
3410 e_comp->animating--;
3412 e_object_unref(E_OBJECT(cw->ec));
3414 cw->ec->frame = NULL;
3419 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3423 cw->x = x, cw->y = y;
3424 evas_object_move(cw->effect_obj, x, y);
3425 evas_object_move(cw->default_input_obj, x, y);
3426 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3428 e_comp_object_map_update(obj);
3432 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3434 Eina_Bool first = EINA_FALSE;
3439 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3441 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3443 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3445 if (cw->w != w || cw->h != h)
3446 e_comp_object_map_update(obj);
3448 first = ((cw->w < 1) || (cw->h < 1));
3449 cw->w = w, cw->h = h;
3450 if ((!cw->ec->shading) && (!cw->ec->shaded))
3454 if (cw->frame_object)
3455 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3458 /* verify pixmap:object size */
3459 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3461 if ((ww != pw) || (hh != ph))
3462 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3464 evas_object_resize(cw->effect_obj, tw, th);
3465 evas_object_resize(cw->default_input_obj, w, h);
3467 evas_object_resize(cw->input_obj, w, h);
3469 evas_object_resize(cw->mask.obj, w, h);
3470 /* resize render update tiler */
3473 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3474 cw->updates_full = 0;
3475 if (cw->updates) eina_tiler_clear(cw->updates);
3479 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3480 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3485 evas_object_resize(cw->effect_obj, tw, th);
3486 evas_object_resize(cw->default_input_obj, w, h);
3493 e_comp_render_queue();
3499 _e_comp_smart_init(void)
3501 if (_e_comp_smart) return;
3503 static const Evas_Smart_Class sc =
3506 EVAS_SMART_CLASS_VERSION,
3510 _e_comp_smart_resize,
3513 _e_comp_smart_color_set,
3514 _e_comp_smart_clip_set,
3515 _e_comp_smart_clip_unset,
3525 _e_comp_smart = evas_smart_class_new(&sc);
3530 e_comp_object_init(void)
3532 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3533 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3534 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3535 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3539 e_comp_object_shutdown(void)
3545 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3547 API_ENTRY EINA_FALSE;
3548 return !!cw->force_visible;
3550 /////////////////////////////////////////////////////////
3553 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3556 Eina_Bool comp_object;
3558 comp_object = !!evas_object_data_get(obj, "comp_object");
3563 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3565 e_comp_render_queue();
3567 l = evas_object_data_get(obj, "comp_object-to_del");
3568 E_FREE_LIST(l, evas_object_del);
3572 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3574 if (e_comp_util_object_is_above_nocomp(obj) &&
3575 (!evas_object_data_get(obj, "comp_override")))
3577 evas_object_data_set(obj, "comp_override", (void*)1);
3578 e_comp_override_add();
3583 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3585 Eina_Bool ref = EINA_TRUE;
3586 if (evas_object_visible_get(obj))
3590 d = evas_object_data_del(obj, "comp_hiding");
3592 /* currently trying to hide */
3595 /* already visible */
3599 evas_object_show(obj);
3602 evas_object_ref(obj);
3603 evas_object_data_set(obj, "comp_ref", (void*)1);
3605 edje_object_signal_emit(obj, "e,state,visible", "e");
3606 evas_object_data_set(obj, "comp_showing", (void*)1);
3607 if (e_comp_util_object_is_above_nocomp(obj))
3609 evas_object_data_set(obj, "comp_override", (void*)1);
3610 e_comp_override_add();
3615 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3617 if (!evas_object_visible_get(obj)) return;
3618 /* already hiding */
3619 if (evas_object_data_get(obj, "comp_hiding")) return;
3620 if (!evas_object_data_del(obj, "comp_showing"))
3622 evas_object_ref(obj);
3623 evas_object_data_set(obj, "comp_ref", (void*)1);
3625 edje_object_signal_emit(obj, "e,state,hidden", "e");
3626 evas_object_data_set(obj, "comp_hiding", (void*)1);
3628 if (evas_object_data_del(obj, "comp_override"))
3629 e_comp_override_timed_pop();
3633 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3635 if (!e_util_strcmp(emission, "e,action,hide,done"))
3637 if (!evas_object_data_del(obj, "comp_hiding")) return;
3638 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3639 evas_object_hide(obj);
3640 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3643 evas_object_data_del(obj, "comp_showing");
3644 if (evas_object_data_del(obj, "comp_ref"))
3645 evas_object_unref(obj);
3649 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3655 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3659 E_API E_Comp_Object_Hook *
3660 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3662 E_Comp_Object_Hook *ch;
3664 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3665 ch = E_NEW(E_Comp_Object_Hook, 1);
3666 if (!ch) return NULL;
3667 ch->hookpoint = hookpoint;
3669 ch->data = (void*)data;
3670 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3675 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3678 if (_e_comp_object_hooks_walking == 0)
3680 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3684 _e_comp_object_hooks_delete++;
3687 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3688 E_API E_Comp_Object_Intercept_Hook *
3689 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3691 E_Comp_Object_Intercept_Hook *ch;
3693 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3694 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3695 if (!ch) return NULL;
3696 ch->hookpoint = hookpoint;
3698 ch->data = (void*)data;
3699 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3704 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3707 if (_e_comp_object_intercept_hooks_walking == 0)
3709 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3713 _e_comp_object_intercept_hooks_delete++;
3718 e_comp_object_util_add(Evas_Object *obj)
3720 Evas_Object *o, *z = NULL;
3722 E_Comp_Config *conf = e_comp_config_get();
3723 Eina_Bool skip = EINA_FALSE;
3729 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3731 name = evas_object_name_get(obj);
3732 vis = evas_object_visible_get(obj);
3733 o = edje_object_add(e_comp->evas);
3734 evas_object_data_set(o, "comp_object", (void*)1);
3736 skip = (!strncmp(name, "noshadow", 8));
3738 evas_object_data_set(o, "comp_object_skip", (void*)1);
3742 if (conf->shadow_style)
3746 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3747 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3752 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3755 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3756 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3758 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3760 evas_object_geometry_get(obj, &x, &y, &w, &h);
3761 evas_object_geometry_set(o, x, y, w, h);
3762 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3764 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3766 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3767 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3768 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3769 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3770 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3771 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3773 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3775 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3777 _e_comp_object_event_add(o);
3780 evas_object_show(o);
3785 /* utility functions for deleting objects when their "owner" is deleted */
3787 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3792 EINA_SAFETY_ON_NULL_RETURN(to_del);
3793 l = evas_object_data_get(obj, "comp_object-to_del");
3794 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3795 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3796 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3800 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3805 EINA_SAFETY_ON_NULL_RETURN(to_del);
3806 l = evas_object_data_get(obj, "comp_object-to_del");
3808 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3811 /////////////////////////////////////////////////////////
3813 EINTERN Evas_Object *
3814 e_comp_object_client_add(E_Client *ec)
3819 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3820 if (ec->frame) return NULL;
3821 _e_comp_smart_init();
3822 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3823 cw = evas_object_smart_data_get(o);
3824 if (!cw) return NULL;
3825 evas_object_data_set(o, "E_Client", ec);
3828 evas_object_data_set(o, "comp_object", (void*)1);
3830 _e_comp_object_event_add(o);
3835 /* utility functions for getting client inset */
3837 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3840 if (!cw->client_inset.calc)
3846 if (ax) *ax = x - cw->client_inset.l;
3847 if (ay) *ay = y - cw->client_inset.t;
3851 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3854 if (!cw->client_inset.calc)
3860 if (ax) *ax = x + cw->client_inset.l;
3861 if (ay) *ay = y + cw->client_inset.t;
3865 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3868 if (!cw->client_inset.calc)
3874 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3875 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3879 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3882 if (!cw->client_inset.calc)
3888 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3889 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3893 e_comp_object_client_get(Evas_Object *obj)
3898 /* FIXME: remove this when eo is used */
3899 o = evas_object_data_get(obj, "comp_smart_obj");
3901 return e_comp_object_client_get(o);
3902 return cw ? cw->ec : NULL;
3906 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3909 if (cw->frame_extends)
3910 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3915 if (w) *w = cw->ec->w;
3916 if (h) *h = cw->ec->h;
3921 e_comp_object_util_zone_get(Evas_Object *obj)
3923 E_Zone *zone = NULL;
3927 zone = cw->ec->zone;
3932 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3933 zone = e_comp_zone_xy_get(x, y);
3939 e_comp_object_util_center(Evas_Object *obj)
3941 int x, y, w, h, ow, oh;
3946 zone = e_comp_object_util_zone_get(obj);
3947 EINA_SAFETY_ON_NULL_RETURN(zone);
3948 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3949 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3950 ow = cw->ec->w, oh = cw->ec->h;
3952 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3953 x = x + (w - ow) / 2;
3954 y = y + (h - oh) / 2;
3955 evas_object_move(obj, x, y);
3959 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3961 int x, y, w, h, ow, oh;
3964 EINA_SAFETY_ON_NULL_RETURN(on);
3965 evas_object_geometry_get(on, &x, &y, &w, &h);
3966 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3967 ow = cw->ec->w, oh = cw->ec->h;
3969 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3970 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3974 e_comp_object_util_fullscreen(Evas_Object *obj)
3979 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3982 evas_object_move(obj, 0, 0);
3983 evas_object_resize(obj, e_comp->w, e_comp->h);
3988 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3996 ow = cw->w, oh = cw->h;
3998 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3999 zone = e_comp_object_util_zone_get(obj);
4000 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4001 if (x) *x = zx + (zw - ow) / 2;
4002 if (y) *y = zy + (zh - oh) / 2;
4006 e_comp_object_input_objs_del(Evas_Object *obj)
4009 E_Input_Rect_Data *input_rect_data;
4010 E_Input_Rect_Smart_Data *input_rect_sd;
4015 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4016 if (!input_rect_sd) return;
4018 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4020 if (input_rect_data->obj)
4022 evas_object_smart_member_del(input_rect_data->obj);
4023 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4025 E_FREE(input_rect_data);
4030 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4033 E_Input_Rect_Data *input_rect_data = NULL;
4034 E_Input_Rect_Smart_Data *input_rect_sd;
4035 int client_w, client_h;
4037 if (cw->ec->client.w)
4038 client_w = cw->ec->client.w;
4040 client_w = cw->ec->w;
4042 if (cw->ec->client.h)
4043 client_h = cw->ec->client.h;
4045 client_h = cw->ec->h;
4047 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4051 _e_comp_input_obj_smart_init();
4052 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4053 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4054 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4057 input_rect_sd->cw = cw;
4060 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4063 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4064 if (input_rect_data)
4066 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4067 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4071 if ((input_rect_data) &&
4072 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4074 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4075 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4076 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4077 evas_object_clip_set(input_rect_data->obj, cw->clip);
4078 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4079 evas_object_geometry_set(input_rect_data->obj,
4080 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4081 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4082 evas_object_pass_events_set(cw->default_input_obj, 1);
4083 evas_object_pass_events_set(cw->obj, 1);
4086 evas_object_show(input_rect_data->obj);
4087 evas_object_show(cw->input_obj);
4092 evas_object_smart_member_del(cw->input_obj);
4093 E_FREE_FUNC(cw->input_obj, evas_object_del);
4094 evas_object_pass_events_set(cw->default_input_obj, 0);
4095 evas_object_pass_events_set(cw->obj, 0);
4100 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4103 E_Input_Rect_Smart_Data *input_rect_sd;
4104 E_Input_Rect_Data *input_rect_data;
4107 if (!cw->input_obj) return;
4109 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4112 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4114 *list = eina_list_append(*list, &input_rect_data->rect);
4120 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4123 if (l) *l = cw->client_inset.l;
4124 if (r) *r = cw->client_inset.r;
4125 if (t) *t = cw->client_inset.t;
4126 if (b) *b = cw->client_inset.b;
4129 /* set geometry for CSD */
4131 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4137 if (cw->frame_object)
4138 CRI("ACK! ec:%p", cw->ec);
4139 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4140 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4141 calc = cw->client_inset.calc;
4142 cw->client_inset.calc = l || r || t || b;
4143 eina_stringshare_replace(&cw->frame_theme, "borderless");
4144 if (cw->client_inset.calc)
4146 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4147 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4148 e_client_size_set(cw->ec, tw, th);
4150 else if (cw->ec->maximized || cw->ec->fullscreen)
4152 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4153 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4155 if (!cw->ec->new_client)
4157 if (calc && cw->client_inset.calc)
4159 tx = cw->ec->x - (l - cw->client_inset.l);
4160 ty = cw->ec->y - (t - cw->client_inset.t);
4161 e_client_pos_set(cw->ec, tx, ty);
4163 cw->ec->changes.pos = cw->ec->changes.size = 1;
4166 cw->client_inset.l = l;
4167 cw->client_inset.r = r;
4168 cw->client_inset.t = t;
4169 cw->client_inset.b = b;
4173 e_comp_object_frame_allowed(Evas_Object *obj)
4175 API_ENTRY EINA_FALSE;
4176 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4180 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4182 API_ENTRY EINA_FALSE;
4183 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4184 eina_stringshare_replace(&cw->frame_name, name);
4185 if (cw->frame_object)
4186 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4191 e_comp_object_frame_exists(Evas_Object *obj)
4193 API_ENTRY EINA_FALSE;
4194 return !!cw->frame_object;
4198 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4200 Evas_Object *o, *pbg;
4203 Eina_Stringshare *theme;
4205 API_ENTRY EINA_FALSE;
4207 if (!e_util_strcmp(cw->frame_theme, name))
4208 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4209 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4210 return _e_comp_object_shadow_setup(cw);
4211 pbg = cw->frame_object;
4212 theme = eina_stringshare_add(name);
4214 if (cw->frame_object)
4218 w = cw->ec->w, h = cw->ec->h;
4219 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4220 if ((cw->ec->w != w) || (cw->ec->h != h))
4222 cw->ec->changes.size = 1;
4225 E_FREE_FUNC(cw->frame_object, evas_object_del);
4226 if (!name) goto reshadow;
4228 o = edje_object_add(e_comp->evas);
4229 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4230 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4231 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4233 cw->frame_object = NULL;
4235 eina_stringshare_del(cw->frame_theme);
4236 cw->frame_theme = theme;
4241 if (theme != e_config->theme_default_border_style)
4243 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4244 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4248 ok = e_theme_edje_object_set(o, "base/theme/border",
4249 "e/widgets/border/default/border");
4250 if (ok && (theme == e_config->theme_default_border_style))
4252 /* Reset default border style to default */
4253 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4254 e_config_save_queue();
4261 cw->frame_object = o;
4262 eina_stringshare_del(cw->frame_theme);
4263 cw->frame_theme = theme;
4264 evas_object_name_set(o, "cw->frame_object");
4267 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4271 cw->ec->changes.icon = 1;
4277 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4282 _e_comp_object_shadow_setup(cw);
4285 int old_x, old_y, new_x = 0, new_y = 0;
4287 old_x = cw->x, old_y = cw->y;
4289 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4291 new_x = cw->ec->x, new_y = cw->ec->y;
4292 else if (cw->ec->placed || (!cw->ec->new_client))
4294 /* if no previous frame:
4295 * - reapply client_inset
4300 if (cw->ec->changes.size)
4307 x = cw->ec->client.x, y = cw->ec->client.y;
4308 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4309 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4311 new_x = x, new_y = y;
4314 if (old_x != new_x || old_y != new_y)
4316 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4317 cw->y = cw->x = -99999;
4318 evas_object_move(obj, new_x, new_y);
4322 if (cw->ec->maximized)
4324 cw->ec->changes.need_maximize = 1;
4327 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4328 if (cw->frame_object)
4330 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4333 cw->frame_extends = 0;
4334 evas_object_del(pbg);
4339 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4341 E_Comp_Object_Mover *prov;
4344 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4345 edje_object_signal_emit(cw->shobj, sig, src);
4346 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4347 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4348 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4350 /* start with highest priority callback first */
4351 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4353 if (!e_util_glob_match(sig, prov->sig)) continue;
4354 if (prov->func(prov->data, obj, sig)) break;
4359 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4361 /* FIXME: at some point I guess this should use eo to inherit
4362 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4363 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4366 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4370 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4373 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4377 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4380 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4384 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4387 Eina_Rectangle rect;
4390 if (cw->ec->input_only || (!cw->updates)) return;
4391 if (cw->nocomp) return;
4392 rect.x = x, rect.y = y;
4393 rect.w = w, rect.h = h;
4394 evas_object_smart_callback_call(obj, "damage", &rect);
4396 if (e_comp_is_on_overlay(cw->ec))
4398 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4399 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4400 * E module attempts to block screen update due to the particular policy.
4402 if (e_pixmap_resource_get(cw->ec->pixmap))
4403 cw->hwc_need_update = EINA_TRUE;
4406 /* ignore overdraw */
4407 if (cw->updates_full)
4409 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4410 e_comp_object_render_update_add(obj);
4412 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4413 evas_object_show(cw->smart_obj);
4417 /* clip rect to client surface */
4418 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4419 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4420 /* if rect is the total size of the client after clip, clear the updates
4421 * since this is guaranteed to be the whole region anyway
4423 eina_tiler_area_size_get(cw->updates, &tw, &th);
4424 if ((w > tw) || (h > th))
4426 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4427 eina_tiler_clear(cw->updates);
4428 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4430 tw = cw->ec->client.w, th = cw->ec->client.h;
4432 if ((!x) && (!y) && (w == tw) && (h == th))
4434 eina_tiler_clear(cw->updates);
4435 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4436 cw->updates_full = 1;
4437 cw->update_count = 0;
4440 if (cw->update_count > UPDATE_MAX)
4442 /* this is going to get really dumb, so just update the whole thing */
4443 eina_tiler_clear(cw->updates);
4444 cw->update_count = cw->updates_full = 1;
4445 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4446 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4450 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4451 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4453 cw->updates_exist = 1;
4454 e_comp_object_render_update_add(obj);
4456 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4457 evas_object_show(cw->smart_obj);
4461 e_comp_object_damage_exists(Evas_Object *obj)
4463 API_ENTRY EINA_FALSE;
4464 return cw->updates_exist;
4468 e_comp_object_render_update_add(Evas_Object *obj)
4472 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4473 if (cw->render_update_lock.lock) return;
4474 if (e_object_is_del(E_OBJECT(cw->ec)))
4475 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4476 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4480 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4482 e_comp_render_queue();
4486 e_comp_object_render_update_del(Evas_Object *obj)
4490 if (cw->ec->input_only || (!cw->updates)) return;
4491 if (!cw->update) return;
4493 /* this gets called during comp animating to clear the update flag */
4494 if (e_comp->grabbed) return;
4495 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4496 if (!e_comp->updates)
4498 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4499 if (e_comp->render_animator)
4500 ecore_animator_freeze(e_comp->render_animator);
4505 e_comp_object_shape_apply(Evas_Object *obj)
4509 unsigned int i, *pix, *p;
4513 if (!cw->ec) return; //NYI
4514 if (cw->external_content) return;
4517 if ((cw->ec->shape_rects_num >= 1) &&
4518 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4523 ERR("BUGGER: shape with native surface? cw=%p", cw);
4526 evas_object_image_size_get(cw->obj, &w, &h);
4527 if ((w < 1) || (h < 1)) return;
4530 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4531 _e_comp_object_alpha_set(cw);
4532 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4533 evas_object_image_alpha_set(o, 1);
4535 p = pix = evas_object_image_data_get(cw->obj, 1);
4538 evas_object_image_data_set(cw->obj, pix);
4543 unsigned char *spix, *sp;
4545 spix = calloc(w * h, sizeof(unsigned char));
4547 for (i = 0; i < cw->ec->shape_rects_num; i++)
4551 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4552 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4553 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4554 sp = spix + (w * ry) + rx;
4555 for (py = 0; py < rh; py++)
4557 for (px = 0; px < rw; px++)
4565 for (py = 0; py < h; py++)
4567 for (px = 0; px < w; px++)
4569 unsigned int mask, imask;
4571 mask = ((unsigned int)(*sp)) << 24;
4573 imask |= imask >> 8;
4574 imask |= imask >> 8;
4575 *p = mask | (*p & imask);
4576 //if (*sp) *p = 0xff000000 | *p;
4577 //else *p = 0x00000000;
4586 for (py = 0; py < h; py++)
4588 for (px = 0; px < w; px++)
4592 evas_object_image_data_set(cw->obj, pix);
4593 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4594 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4596 evas_object_image_data_set(o, pix);
4597 evas_object_image_data_update_add(o, 0, 0, w, h);
4599 // don't need to fix alpha chanel as blending
4600 // should be totally off here regardless of
4601 // alpha channel content
4605 _e_comp_object_clear(E_Comp_Object *cw)
4610 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4612 if (cw->render_update_lock.lock) return;
4615 e_pixmap_clear(cw->ec->pixmap);
4617 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4618 evas_object_image_size_set(cw->obj, 1, 1);
4619 evas_object_image_data_set(cw->obj, NULL);
4620 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4622 evas_object_image_size_set(o, 1, 1);
4623 evas_object_image_data_set(o, NULL);
4626 e_comp_object_render_update_del(cw->smart_obj);
4630 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4634 API_ENTRY EINA_FALSE;
4636 if (cw->transparent.set == set)
4641 evas_object_color_get(obj, &r, &g, &b, &a);
4642 evas_object_color_set(obj, 0, 0, 0, 0);
4644 cw->transparent.user_r = r;
4645 cw->transparent.user_g = g;
4646 cw->transparent.user_b = b;
4647 cw->transparent.user_a = a;
4649 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4651 cw->transparent.user_r,
4652 cw->transparent.user_g,
4653 cw->transparent.user_b,
4654 cw->transparent.user_a);
4656 cw->transparent.set = EINA_TRUE;
4660 cw->transparent.set = EINA_FALSE;
4662 evas_object_color_set(obj,
4663 cw->transparent.user_r,
4664 cw->transparent.user_g,
4665 cw->transparent.user_b,
4666 cw->transparent.user_a);
4668 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4670 cw->transparent.user_r,
4671 cw->transparent.user_g,
4672 cw->transparent.user_b,
4673 cw->transparent.user_a);
4679 /* helper function to simplify toggling of redirection for display servers which support it */
4681 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4686 if (cw->redirected == set) return;
4687 cw->redirected = set;
4688 if (cw->external_content) return;
4690 e_comp_object_map_update(obj);
4694 if (cw->updates_exist)
4695 e_comp_object_render_update_add(obj);
4697 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4699 _e_comp_object_transparent_set(obj, EINA_FALSE);
4700 evas_object_smart_callback_call(obj, "redirected", NULL);
4704 _e_comp_object_clear(cw);
4705 _e_comp_object_transparent_set(obj, EINA_TRUE);
4706 evas_object_smart_callback_call(obj, "unredirected", NULL);
4711 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4714 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4716 if (cw->buffer_destroy_listener.notify)
4718 cw->buffer_destroy_listener.notify = NULL;
4719 wl_list_remove(&cw->buffer_destroy_listener.link);
4722 if (e_object_is_del(E_OBJECT(cw->ec)))
4724 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4729 /* if it's current displaying buffer, do not remove its content */
4730 if (!evas_object_visible_get(cw->ec->frame))
4731 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4736 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4741 if (cw->buffer_destroy_listener.notify)
4743 wl_list_remove(&cw->buffer_destroy_listener.link);
4744 cw->buffer_destroy_listener.notify = NULL;
4747 if (cw->tbm_surface)
4749 tbm_surface_internal_unref(cw->tbm_surface);
4750 cw->tbm_surface = NULL;
4755 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4757 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4758 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4760 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4762 tbm_surface_internal_ref(ns->data.tbm.buffer);
4763 cw->tbm_surface = ns->data.tbm.buffer;
4767 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4768 evas_object_image_native_surface_set(cw->obj, ns);
4772 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4774 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4775 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4776 evas_object_image_native_surface_set(o, ns);
4783 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4785 Evas_Native_Surface ns;
4788 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4789 if (cw->ec->input_only) return;
4790 if (cw->external_content) return;
4791 if (cw->render_update_lock.lock) return;
4794 memset(&ns, 0, sizeof(Evas_Native_Surface));
4798 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4799 set = (!cw->ec->shaped);
4801 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4805 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4809 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4812 if (cw->ec->input_only) return;
4815 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4816 _e_comp_object_alpha_set(cw);
4818 e_comp_object_native_surface_set(obj, cw->native);
4819 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4823 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4829 if (cw->blanked == set) return;
4831 _e_comp_object_alpha_set(cw);
4834 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4835 evas_object_image_data_set(cw->obj, NULL);
4839 e_comp_object_native_surface_set(obj, 1);
4840 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4844 _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)
4849 if (!_damage_trace) return;
4853 if (!evas_object_visible_get(cw->obj)) return;
4855 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4857 o = evas_object_rectangle_add(e_comp->evas);
4858 evas_object_layer_set(o, E_LAYER_MAX);
4859 evas_object_name_set(o, "damage_trace");
4860 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4861 evas_object_resize(o, dmg_w, dmg_h);
4862 evas_object_color_set(o, 0, 128, 0, 128);
4863 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4864 evas_object_pass_events_set(o, EINA_TRUE);
4865 evas_object_show(o);
4867 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4869 dmg_w, dmg_h, dmg_x, dmg_y,
4870 origin->w, origin->h, origin->x, origin->y);
4872 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4875 /* mark an object as dirty and setup damages */
4877 e_comp_object_dirty(Evas_Object *obj)
4880 Eina_Rectangle *rect;
4884 Eina_Bool dirty, visible;
4888 if (cw->external_content) return;
4889 if (!cw->redirected) return;
4890 if (cw->render_update_lock.lock)
4892 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4895 /* only actually dirty if pixmap is available */
4896 if (!e_pixmap_resource_get(cw->ec->pixmap))
4898 // e_pixmap_size_get returns last attached buffer size
4899 // eventhough it is destroyed
4900 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4903 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4904 visible = cw->visible;
4905 if (!dirty) w = h = 1;
4906 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4908 evas_object_image_data_set(cw->obj, NULL);
4909 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4910 evas_object_image_size_set(cw->obj, tw, th);
4911 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4912 if (cw->pending_updates)
4913 eina_tiler_area_size_set(cw->pending_updates, w, h);
4914 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4916 evas_object_image_pixels_dirty_set(o, dirty);
4918 evas_object_image_data_set(o, NULL);
4919 evas_object_image_size_set(o, tw, th);
4920 visible |= evas_object_visible_get(o);
4924 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4928 e_comp_object_native_surface_set(obj, 1);
4930 m = _e_comp_object_map_damage_transform_get(cw->ec);
4931 it = eina_tiler_iterator_new(cw->updates);
4932 EINA_ITERATOR_FOREACH(it, rect)
4934 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4935 * of evas engine and doesn't convert damage according to evas_map.
4936 * so damage of evas_object_image use surface coordinate.
4940 int damage_x, damage_y, damage_w, damage_h;
4942 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4943 &damage_x, &damage_y, &damage_w, &damage_h);
4944 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4945 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4949 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4950 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4953 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4954 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4955 if (cw->pending_updates)
4956 eina_tiler_rect_add(cw->pending_updates, rect);
4958 eina_iterator_free(it);
4959 if (m) e_map_free(m);
4960 if (cw->pending_updates)
4961 eina_tiler_clear(cw->updates);
4964 cw->pending_updates = cw->updates;
4965 cw->updates = eina_tiler_new(w, h);
4966 eina_tiler_tile_size_set(cw->updates, 1, 1);
4968 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4969 evas_object_smart_callback_call(obj, "dirty", NULL);
4970 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4971 /* force render if main object is hidden but mirrors are visible */
4972 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4973 e_comp_object_render(obj);
4977 e_comp_object_render(Evas_Object *obj)
4984 API_ENTRY EINA_FALSE;
4986 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4987 if (cw->ec->input_only) return EINA_TRUE;
4988 if (cw->external_content) return EINA_TRUE;
4989 if (cw->native) return EINA_FALSE;
4990 /* if comp object is not redirected state, comp object should not be set by newly committed data
4991 because image size of comp object is 1x1 and it should not be shown on canvas */
4992 if (!cw->redirected) return EINA_TRUE;
4993 if (cw->render_update_lock.lock)
4995 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4998 e_comp_object_render_update_del(obj);
4999 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5001 if (!cw->pending_updates)
5003 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5004 evas_object_image_data_set(cw->obj, NULL);
5005 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5006 evas_object_image_data_set(o, NULL);
5010 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5012 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5014 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5017 e_pixmap_image_refresh(cw->ec->pixmap);
5018 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5021 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5022 e_pixmap_image_data_ref(cw->ec->pixmap);
5024 /* set pixel data */
5025 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5026 _e_comp_object_alpha_set(cw);
5027 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5029 evas_object_image_data_set(o, pix);
5030 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5031 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5034 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5036 e_comp_client_post_update_add(cw->ec);
5041 /* create a duplicate of an evas object */
5043 e_comp_object_util_mirror_add(Evas_Object *obj)
5047 unsigned int *pix = NULL;
5048 Eina_Bool argb = EINA_FALSE;
5053 cw = evas_object_data_get(obj, "comp_mirror");
5056 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5057 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5058 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5059 evas_object_image_alpha_set(o, 1);
5060 evas_object_image_source_set(o, obj);
5063 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5064 if (cw->external_content)
5066 ERR("%p of client %p is external content.", obj, cw->ec);
5069 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5070 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5071 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5072 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5073 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5074 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5075 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5076 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5077 evas_object_data_set(o, "comp_mirror", cw);
5079 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5080 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5082 evas_object_image_size_set(o, tw, th);
5085 pix = evas_object_image_data_get(cw->obj, 0);
5091 evas_object_image_native_surface_set(o, cw->ns);
5094 Evas_Native_Surface ns;
5095 memset(&ns, 0, sizeof(Evas_Native_Surface));
5096 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5097 evas_object_image_native_surface_set(o, &ns);
5102 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5103 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5105 (e_pixmap_image_exists(cw->ec->pixmap)))
5106 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5108 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5115 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5116 evas_object_image_pixels_dirty_set(o, dirty);
5117 evas_object_image_data_set(o, pix);
5118 evas_object_image_data_set(cw->obj, pix);
5120 evas_object_image_data_update_add(o, 0, 0, tw, th);
5125 //////////////////////////////////////////////////////
5128 e_comp_object_effect_allowed_get(Evas_Object *obj)
5130 API_ENTRY EINA_FALSE;
5132 if (!cw->shobj) return EINA_FALSE;
5133 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5134 return !e_comp_config_get()->match.disable_borders;
5137 /* setup an api effect for a client */
5139 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5142 Eina_Stringshare *grp;
5143 E_Comp_Config *config;
5144 Eina_Bool loaded = EINA_FALSE;
5146 API_ENTRY EINA_FALSE;
5147 if (!cw->shobj) return EINA_FALSE; //input window
5149 if (!effect) effect = "none";
5150 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5152 config = e_comp_config_get();
5153 if ((config) && (config->effect_file))
5155 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5157 cw->effect_set = EINA_TRUE;
5164 edje_object_file_get(cw->effect_obj, NULL, &grp);
5165 cw->effect_set = !eina_streq(effect, "none");
5166 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5167 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5169 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5170 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5171 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5173 if (cw->effect_running)
5175 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5178 cw->effect_set = EINA_FALSE;
5179 return cw->effect_set;
5183 if (cw->effect_running)
5185 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5188 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5189 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5190 if (cw->effect_clip)
5192 evas_object_clip_unset(cw->clip);
5193 cw->effect_clip = 0;
5195 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5197 _e_comp_object_dim_update(cw);
5199 return cw->effect_set;
5202 /* set params for embryo scripts in effect */
5204 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5206 Edje_Message_Int_Set *msg;
5210 EINA_SAFETY_ON_NULL_RETURN(params);
5211 EINA_SAFETY_ON_FALSE_RETURN(count);
5212 if (!cw->effect_set) return;
5214 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5215 msg->count = (int)count;
5216 for (x = 0; x < count; x++)
5217 msg->val[x] = params[x];
5218 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5219 edje_object_message_signal_process(cw->effect_obj);
5223 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5225 Edje_Signal_Cb end_cb;
5227 E_Comp_Object *cw = data;
5229 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5230 cw->effect_running = 0;
5231 if (!_e_comp_object_animating_end(cw)) return;
5233 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5235 evas_object_data_del(cw->smart_obj, "effect_running");
5236 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5237 e_client_visibility_calculate();
5240 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5241 if (!end_cb) return;
5242 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5243 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5244 end_cb(end_data, cw->smart_obj, emission, source);
5247 /* clip effect to client's zone */
5249 e_comp_object_effect_clip(Evas_Object *obj)
5252 if (!cw->ec->zone) return;
5253 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5254 if (!cw->effect_clip_able) return;
5255 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5256 cw->effect_clip = 1;
5259 /* unclip effect from client's zone */
5261 e_comp_object_effect_unclip(Evas_Object *obj)
5264 if (!cw->effect_clip) return;
5265 evas_object_clip_unset(cw->smart_obj);
5266 cw->effect_clip = 0;
5269 /* start effect, running end_cb after */
5271 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5273 API_ENTRY EINA_FALSE;
5274 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5275 if (!cw->effect_set) return EINA_FALSE;
5277 if (cw->effect_running)
5279 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5282 e_comp_object_effect_clip(obj);
5283 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5285 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5286 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5287 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5288 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5290 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5291 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5293 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5294 _e_comp_object_animating_begin(cw);
5295 cw->effect_running = 1;
5299 /* stop a currently-running effect immediately */
5301 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5304 Edje_Signal_Cb end_cb_before = NULL;
5305 void *end_data_before = NULL;
5306 API_ENTRY EINA_FALSE;
5308 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5309 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5311 if (end_cb_before != end_cb) return EINA_TRUE;
5312 e_comp_object_effect_unclip(obj);
5313 if (cw->effect_clip)
5315 evas_object_clip_unset(cw->effect_obj);
5316 cw->effect_clip = 0;
5318 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5319 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5321 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5323 evas_object_data_del(cw->smart_obj, "effect_running");
5324 e_client_visibility_calculate();
5327 cw->effect_running = 0;
5328 ret = _e_comp_object_animating_end(cw);
5330 if ((ret) && (end_cb_before))
5332 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5333 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5340 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5342 return a->pri - b->pri;
5345 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5346 E_API E_Comp_Object_Mover *
5347 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5349 E_Comp_Object_Mover *prov;
5351 prov = E_NEW(E_Comp_Object_Mover, 1);
5352 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5353 prov->func = provider;
5354 prov->data = (void*)data;
5357 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5358 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5363 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5365 EINA_SAFETY_ON_NULL_RETURN(prov);
5366 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5371 e_comp_object_effect_object_get(Evas_Object *obj)
5375 return cw->effect_obj;
5379 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5381 API_ENTRY EINA_FALSE;
5382 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5383 if (!cw->effect_set) return EINA_FALSE;
5390 ////////////////////////////////////
5393 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5395 if (e_comp->autoclose.obj)
5397 e_comp_ungrab_input(0, 1);
5398 if (e_comp->autoclose.del_cb)
5399 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5400 else if (!already_del)
5402 evas_object_hide(e_comp->autoclose.obj);
5403 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5405 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5407 e_comp->autoclose.obj = NULL;
5408 e_comp->autoclose.data = NULL;
5409 e_comp->autoclose.del_cb = NULL;
5410 e_comp->autoclose.key_cb = NULL;
5411 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5415 _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)
5417 _e_comp_object_autoclose_cleanup(0);
5421 _e_comp_object_autoclose_setup(Evas_Object *obj)
5423 if (!e_comp->autoclose.rect)
5425 /* create rect just below autoclose object to catch mouse events */
5426 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5427 evas_object_move(e_comp->autoclose.rect, 0, 0);
5428 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5429 evas_object_show(e_comp->autoclose.rect);
5430 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5431 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5432 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5433 e_comp_grab_input(0, 1);
5435 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5436 evas_object_focus_set(obj, 1);
5440 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5442 _e_comp_object_autoclose_setup(obj);
5443 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5447 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5449 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5450 _e_comp_object_autoclose_cleanup(1);
5451 if (e_client_focused_get()) return;
5452 if (e_config->focus_policy != E_FOCUS_MOUSE)
5457 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5461 if (e_comp->autoclose.obj)
5463 if (e_comp->autoclose.obj == obj) return;
5464 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5465 e_comp->autoclose.obj = obj;
5466 e_comp->autoclose.del_cb = del_cb;
5467 e_comp->autoclose.key_cb = cb;
5468 e_comp->autoclose.data = (void*)data;
5469 if (evas_object_visible_get(obj))
5470 _e_comp_object_autoclose_setup(obj);
5472 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5473 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5476 e_comp->autoclose.obj = obj;
5477 e_comp->autoclose.del_cb = del_cb;
5478 e_comp->autoclose.key_cb = cb;
5479 e_comp->autoclose.data = (void*)data;
5480 if (evas_object_visible_get(obj))
5481 _e_comp_object_autoclose_setup(obj);
5483 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5484 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5488 e_comp_object_is_animating(Evas_Object *obj)
5492 return cw->animating;
5496 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5500 if ((cw->external_content) &&
5501 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5503 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5504 "But current external content is %d object for %p.",
5505 cw->content_type, cw->ec);
5509 cw->user_alpha_set = EINA_TRUE;
5510 cw->user_alpha = alpha;
5512 if (!cw->obj) return;
5514 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5516 evas_object_image_alpha_set(cw->obj, alpha);
5518 if ((!cw->native) && (!cw->external_content))
5519 evas_object_image_data_set(cw->obj, NULL);
5523 e_comp_object_alpha_get(Evas_Object *obj)
5525 API_ENTRY EINA_FALSE;
5527 return evas_object_image_alpha_get(cw->obj);
5531 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5533 Eina_Bool mask_set = EINA_FALSE;
5537 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5538 if (cw->ec->input_only) return;
5545 o = evas_object_rectangle_add(e_comp->evas);
5546 evas_object_color_set(o, 0, 0, 0, 0);
5547 evas_object_clip_set(o, cw->clip);
5548 evas_object_smart_member_add(o, obj);
5549 evas_object_move(o, 0, 0);
5550 evas_object_resize(o, cw->w, cw->h);
5551 /* save render op value to restore when clear a mask.
5553 * NOTE: DO NOT change the render op on ec->frame while mask object
5554 * is set. it will overwrite the changed op value. */
5555 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5556 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5557 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5558 if (cw->visible) evas_object_show(o);
5561 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5562 ELOGF("COMP", " |mask_obj", cw->ec);
5563 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5570 evas_object_smart_member_del(cw->mask.obj);
5571 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5573 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5574 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5580 e_comp_object_mask_has(Evas_Object *obj)
5582 API_ENTRY EINA_FALSE;
5584 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5588 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5593 if ((cw->external_content) &&
5594 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5596 WRN("Can set up size to ONLY evas \"image\" object. "
5597 "But current external content is %d object for %p.",
5598 cw->content_type, cw->ec);
5602 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5604 evas_object_image_size_set(cw->obj, tw, th);
5608 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5610 Eina_Bool transform_set = EINA_FALSE;
5612 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5613 if (cw->ec->input_only) return;
5615 transform_set = !!set;
5619 if (!cw->transform_bg_obj)
5621 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5622 evas_object_move(o, 0, 0);
5623 evas_object_resize(o, 1, 1);
5624 if (cw->transform_bg_color.a >= 255)
5625 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5627 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5628 evas_object_color_set(o,
5629 cw->transform_bg_color.r,
5630 cw->transform_bg_color.g,
5631 cw->transform_bg_color.b,
5632 cw->transform_bg_color.a);
5633 if (cw->visible) evas_object_show(o);
5635 cw->transform_bg_obj = o;
5636 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5638 _e_comp_object_transform_obj_stack_update(obj);
5642 if (cw->transform_bg_obj)
5644 evas_object_smart_member_del(cw->transform_bg_obj);
5645 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5651 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5655 cw->transform_bg_color.r = r;
5656 cw->transform_bg_color.g = g;
5657 cw->transform_bg_color.b = b;
5658 cw->transform_bg_color.a = a;
5660 if (cw->transform_bg_obj)
5662 evas_object_color_set(cw->transform_bg_obj,
5663 cw->transform_bg_color.r,
5664 cw->transform_bg_color.g,
5665 cw->transform_bg_color.b,
5666 cw->transform_bg_color.a);
5671 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5674 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5675 if (cw->ec->input_only) return;
5676 if (!cw->transform_bg_obj) return;
5678 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5682 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5685 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5686 if (cw->ec->input_only) return;
5687 if (!cw->transform_bg_obj) return;
5689 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5693 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5695 Eina_Bool transform_set = EINA_FALSE;
5697 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5698 if (cw->ec->input_only) return;
5700 transform_set = !!set;
5704 if (!cw->transform_tranp_obj)
5706 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5707 evas_object_move(o, 0, 0);
5708 evas_object_resize(o, 1, 1);
5709 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5710 evas_object_color_set(o, 0, 0, 0, 0);
5711 if (cw->visible) evas_object_show(o);
5713 cw->transform_tranp_obj = o;
5714 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5716 _e_comp_object_transform_obj_stack_update(obj);
5720 if (cw->transform_tranp_obj)
5722 evas_object_smart_member_del(cw->transform_tranp_obj);
5723 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5729 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5732 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5733 if (cw->ec->input_only) return;
5734 if (!cw->transform_tranp_obj) return;
5736 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5740 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5743 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5744 if (cw->ec->input_only) return;
5745 if (!cw->transform_tranp_obj) return;
5747 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5751 e_comp_object_layer_update(Evas_Object *obj,
5752 Evas_Object *above, Evas_Object *below)
5754 E_Comp_Object *cw2 = NULL;
5755 Evas_Object *o = NULL;
5760 if (cw->ec->layer_block) return;
5761 if ((above) && (below))
5763 ERR("Invalid layer update request! cw=%p", cw);
5771 layer = evas_object_layer_get(o);
5772 cw2 = evas_object_data_get(o, "comp_obj");
5775 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5777 o = evas_object_above_get(o);
5778 if ((!o) || (o == cw->smart_obj)) break;
5779 if (evas_object_layer_get(o) != layer)
5781 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5786 ec = e_client_top_get();
5787 if (ec) o = ec->frame;
5790 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5794 _e_comp_object_layers_remove(cw);
5797 if (cw2->layer > cw->layer)
5798 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5799 else if (cw2->layer == cw->layer)
5802 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5804 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5806 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5809 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5812 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5816 e_comp_object_layer_get(Evas_Object *obj)
5823 e_comp_object_content_set(Evas_Object *obj,
5824 Evas_Object *content,
5825 E_Comp_Object_Content_Type type)
5827 API_ENTRY EINA_FALSE;
5829 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5830 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5831 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5835 ERR("Can't set e.swallow.content to requested content. "
5836 "Previous comp object should not be changed at all.");
5840 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5842 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5843 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5845 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5846 type, content, cw->ec, cw->ec->pixmap);
5850 cw->external_content = EINA_TRUE;
5853 cw->content_type = type;
5854 e_util_size_debug_set(cw->obj, 1);
5855 evas_object_name_set(cw->obj, "cw->obj");
5856 _e_comp_object_alpha_set(cw);
5859 _e_comp_object_shadow_setup(cw);
5865 e_comp_object_content_unset(Evas_Object *obj)
5867 API_ENTRY EINA_FALSE;
5869 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5870 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5872 if (!cw->obj && !cw->ec->visible)
5874 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5878 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5880 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5886 if (cw->frame_object)
5887 edje_object_part_unswallow(cw->frame_object, cw->obj);
5889 edje_object_part_unswallow(cw->shobj, cw->obj);
5891 evas_object_del(cw->obj);
5892 evas_object_hide(cw->obj);
5896 cw->external_content = EINA_FALSE;
5897 if (cw->ec->is_cursor)
5900 DBG("%p is cursor surface..", cw->ec);
5901 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5903 evas_object_resize(cw->ec->frame, pw, ph);
5904 evas_object_hide(cw->ec->frame);
5909 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5910 cw->obj = evas_object_image_filled_add(e_comp->evas);
5911 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5912 e_util_size_debug_set(cw->obj, 1);
5913 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5914 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5915 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5916 evas_object_name_set(cw->obj, "cw->obj");
5917 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5918 _e_comp_object_alpha_set(cw);
5921 _e_comp_object_shadow_setup(cw);
5926 _e_comp_intercept_show_helper(cw);
5930 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5931 e_comp_object_dirty(cw->smart_obj);
5932 e_comp_object_render(cw->smart_obj);
5933 e_comp_object_render_update_add(obj);
5938 EINTERN Evas_Object *
5939 e_comp_object_content_get(Evas_Object *obj)
5943 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5945 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5947 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5954 E_API E_Comp_Object_Content_Type
5955 e_comp_object_content_type_get(Evas_Object *obj)
5957 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5959 return cw->content_type;
5963 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5966 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5967 E_Comp_Config *conf = e_comp_config_get();
5968 if (cw->ec->input_only) return;
5969 if (!conf->dim_rect_enable) return;
5971 cw->dim.mask_set = mask_set;
5977 if (!cw->dim.enable) return;
5978 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5982 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5984 Eina_Bool mask_set = EINA_FALSE;
5988 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5989 E_Comp_Config *conf = e_comp_config_get();
5990 if (cw->ec->input_only) return;
5991 if (!conf->dim_rect_enable) return;
5997 if (cw->dim.mask_obj)
5999 evas_object_smart_member_del(cw->dim.mask_obj);
6000 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6003 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);
6004 o = evas_object_rectangle_add(e_comp->evas);
6005 evas_object_color_set(o, 0, 0, 0, 0);
6006 evas_object_smart_member_add(o, obj);
6007 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6008 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6010 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6011 if (cw->visible) evas_object_show(o);
6013 cw->dim.mask_obj = o;
6014 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6016 evas_object_layer_set(cw->dim.mask_obj, 9998);
6020 if (cw->dim.mask_obj)
6022 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6023 evas_object_smart_member_del(cw->dim.mask_obj);
6024 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6030 e_comp_object_dim_client_set(E_Client *ec)
6032 E_Comp_Config *conf = e_comp_config_get();
6034 if (!conf->dim_rect_enable) return ;
6035 if (dim_client == ec) return;
6037 Eina_Bool prev_dim = EINA_FALSE;
6038 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6040 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6041 prev_dim = EINA_TRUE;
6043 if (prev_dim && dim_client->visible && ec)
6045 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6046 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6050 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6051 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6057 e_comp_object_dim_client_get(void)
6059 E_Comp_Config *conf = e_comp_config_get();
6061 if (!conf->dim_rect_enable ) return NULL;
6067 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6070 char emit[32] = "\0";
6071 E_Comp_Config *conf = e_comp_config_get();
6074 if (!conf->dim_rect_enable) return;
6075 if (!cw->effect_obj) return;
6076 if (enable == cw->dim.enable) return;
6078 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6079 if (noeffect || !conf->dim_rect_effect)
6081 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6085 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6088 cw->dim.enable = enable;
6090 if (cw->dim.mask_set && !enable)
6092 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6093 edje_object_signal_emit(cw->effect_obj, emit, "e");
6095 else if (cw->dim.mask_set && enable)
6097 edje_object_signal_emit(cw->effect_obj, emit, "e");
6098 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6102 edje_object_signal_emit(cw->effect_obj, emit, "e");
6107 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6109 API_ENTRY EINA_FALSE;
6110 E_Comp_Config *conf = e_comp_config_get();
6112 if (!ec) return EINA_FALSE;
6113 if (!conf->dim_rect_enable) return EINA_FALSE;
6115 if (cw->dim.enable) return EINA_TRUE;
6121 _e_comp_object_dim_update(E_Comp_Object *cw)
6123 E_Comp_Config *conf = e_comp_config_get();
6126 if (!conf->dim_rect_enable) return;
6127 if (!cw->effect_obj) return;
6130 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6131 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6133 if (cw->dim.mask_set)
6135 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6141 e_comp_object_clear(Evas_Object *obj)
6145 _e_comp_object_clear(cw);
6149 e_comp_object_hwc_update_exists(Evas_Object *obj)
6151 API_ENTRY EINA_FALSE;
6152 return cw->hwc_need_update;
6157 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6160 cw->hwc_need_update = set;
6164 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6166 API_ENTRY EINA_FALSE;
6167 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6171 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6174 if (cw->indicator.obj != indicator)
6175 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6176 cw->indicator.obj = indicator;
6177 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6181 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6184 if (cw->indicator.obj != indicator) return;
6185 cw->indicator.obj = NULL;
6186 edje_object_part_unswallow(cw->shobj, indicator);
6190 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6193 Edje_Message_Int_Set *msg;
6195 if (!cw->indicator.obj) return;
6197 cw->indicator.w = w;
6198 cw->indicator.h = h;
6200 if (!cw->shobj) return;
6202 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6206 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6207 edje_object_message_signal_process(cw->shobj);
6210 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6212 e_comp_object_map_update(Evas_Object *obj)
6215 E_Client *ec = cw->ec;
6216 E_Comp_Wl_Client_Data *cdata;
6218 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6221 int l, remain = sizeof buffer;
6224 if (e_object_is_del(E_OBJECT(ec))) return;
6225 cdata = e_client_cdata_get(ec);
6228 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6229 * when new buffer is attached.
6231 if (!cdata->buffer_ref.buffer) return;
6233 if ((!cw->redirected) ||
6234 (e_client_video_hw_composition_check(ec)) ||
6235 (!e_comp_wl_output_buffer_transform_get(ec) &&
6236 cdata->scaler.buffer_viewport.buffer.scale == 1))
6238 if (evas_object_map_enable_get(cw->effect_obj))
6240 ELOGF("TRANSFORM", "map: disable", cw->ec);
6241 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6242 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6243 evas_object_resize(cw->effect_obj, tw, th);
6250 EINA_SAFETY_ON_NULL_RETURN(map);
6252 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6258 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6260 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6261 e_map_point_image_uv_set(map, 0, x, y);
6262 l = snprintf(p, remain, "%d,%d", x, y);
6263 p += l, remain -= l;
6265 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6266 e_map_point_image_uv_set(map, 1, x, y);
6267 l = snprintf(p, remain, " %d,%d", x, y);
6268 p += l, remain -= l;
6270 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6271 e_map_point_image_uv_set(map, 2, x, y);
6272 l = snprintf(p, remain, " %d,%d", x, y);
6273 p += l, remain -= l;
6275 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6276 e_map_point_image_uv_set(map, 3, x, y);
6277 l = snprintf(p, remain, " %d,%d", x, y);
6278 p += l, remain -= l;
6280 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6282 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6284 e_comp_object_map_set(cw->effect_obj, map);
6285 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6289 /* if there's screen rotation with comp mode, then ec->effect_obj and
6290 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6292 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6293 evas_object_resize(cw->effect_obj, tw, th);
6297 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6299 API_ENTRY EINA_FALSE;
6301 cw->render_trace = set;
6307 e_comp_object_native_usable_get(Evas_Object *obj)
6309 API_ENTRY EINA_FALSE;
6310 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6312 if (cw->ec->input_only) return EINA_FALSE;
6313 if (cw->external_content) return EINA_FALSE;
6314 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6316 /* just return true value, if it is normal case */
6317 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6320 Evas_Native_Surface *ns;
6321 ns = evas_object_image_native_surface_get(cw->obj);
6323 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6326 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6334 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6336 API_ENTRY EINA_FALSE;
6337 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6338 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6339 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6343 case E_COMP_IMAGE_FILTER_BLUR:
6344 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6346 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6347 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6349 case E_COMP_IMAGE_FILTER_INVERSE:
6350 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6352 case E_COMP_IMAGE_FILTER_NONE:
6354 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6358 cw->image_filter = filter;
6363 EINTERN E_Comp_Image_Filter
6364 e_comp_object_image_filter_get(Evas_Object *obj)
6366 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6367 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6368 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6369 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6371 return cw->image_filter;
6375 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6379 if (!_damage_trace) return;
6381 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6382 evas_object_del(obj);
6384 _damage_trace_post_objs = NULL;
6388 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6390 if (!_damage_trace) return;
6392 _damage_trace_post_objs = _damage_trace_objs;
6393 _damage_trace_objs = NULL;
6397 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6399 if (_damage_trace == onoff) return;
6403 evas_event_callback_add(e_comp->evas,
6404 EVAS_CALLBACK_RENDER_PRE,
6405 _e_comp_object_damage_trace_render_pre_cb,
6408 evas_event_callback_add(e_comp->evas,
6409 EVAS_CALLBACK_RENDER_POST,
6410 _e_comp_object_damage_trace_render_post_cb,
6417 EINA_LIST_FREE(_damage_trace_objs, obj)
6418 evas_object_del(obj);
6420 _damage_trace_objs = NULL;
6422 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6423 evas_object_del(obj);
6425 _damage_trace_post_objs = NULL;
6427 evas_event_callback_del(e_comp->evas,
6428 EVAS_CALLBACK_RENDER_PRE,
6429 _e_comp_object_damage_trace_render_pre_cb);
6431 evas_event_callback_del(e_comp->evas,
6432 EVAS_CALLBACK_RENDER_POST,
6433 _e_comp_object_damage_trace_render_post_cb);
6436 _damage_trace = onoff;
6440 e_comp_object_redirected_get(Evas_Object *obj)
6442 API_ENTRY EINA_FALSE;
6443 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6445 return cw->redirected;
6449 e_comp_object_color_visible_get(Evas_Object *obj)
6451 API_ENTRY EINA_FALSE;
6454 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6456 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6460 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6464 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6468 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6476 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6478 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6480 return e_map_set_to_comp_object(em, obj);
6484 e_comp_object_map_get(const Evas_Object *obj)
6486 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6488 return e_map_get_from_comp_object(obj);
6492 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6494 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6496 evas_object_map_enable_set(obj, enable);
6502 e_comp_object_render_update_lock(Evas_Object *obj)
6504 API_ENTRY EINA_FALSE;
6506 if (cw->render_update_lock.lock == 0)
6508 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6509 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6510 e_pixmap_resource_get(cw->ec->pixmap));
6511 e_comp_object_render_update_del(obj);
6512 ELOGF("COMP", "Render update lock enabled", cw->ec);
6515 cw->render_update_lock.lock++;
6521 e_comp_object_render_update_unlock(Evas_Object *obj)
6525 if (cw->render_update_lock.lock == 0)
6528 cw->render_update_lock.lock--;
6530 if (cw->render_update_lock.lock == 0)
6533 if (cw->render_update_lock.pending_move_set)
6535 evas_object_move(obj,
6536 cw->render_update_lock.pending_move_x,
6537 cw->render_update_lock.pending_move_y);
6538 cw->render_update_lock.pending_move_x = 0;
6539 cw->render_update_lock.pending_move_y = 0;
6540 cw->render_update_lock.pending_move_set = EINA_FALSE;
6543 if (cw->render_update_lock.pending_resize_set)
6545 evas_object_resize(obj,
6546 cw->render_update_lock.pending_resize_w,
6547 cw->render_update_lock.pending_resize_h);
6548 cw->render_update_lock.pending_resize_w = 0;
6549 cw->render_update_lock.pending_resize_h = 0;
6550 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6553 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6555 if ((cw->ec->exp_iconify.buffer_flush) &&
6556 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6557 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6558 e_comp_object_clear(obj);
6560 e_comp_object_render_update_add(obj);
6562 ELOGF("COMP", "Render update lock disabled", cw->ec);
6567 e_comp_object_render_update_lock_get(Evas_Object *obj)
6569 API_ENTRY EINA_FALSE;
6571 if (cw->render_update_lock.lock > 0)
6578 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6582 if (cw->transparent.set)
6584 if (r) *r = cw->transparent.user_r;
6585 if (g) *g = cw->transparent.user_g;
6586 if (b) *b = cw->transparent.user_b;
6587 if (a) *a = cw->transparent.user_a;
6591 evas_object_color_get(obj, r, g, b, a);