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);
3743 if (conf->shadow_style)
3747 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3748 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3753 ok = e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3756 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3757 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3759 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3761 evas_object_geometry_get(obj, &x, &y, &w, &h);
3762 evas_object_geometry_set(o, x, y, w, h);
3763 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3765 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, z);
3767 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, z);
3768 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, z);
3769 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, z);
3770 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, z);
3771 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, z);
3772 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, z);
3774 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3776 edje_object_part_swallow(o, "e.swallow.content", z ?: obj);
3778 _e_comp_object_event_add(o);
3781 evas_object_show(o);
3786 /* utility functions for deleting objects when their "owner" is deleted */
3788 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3793 EINA_SAFETY_ON_NULL_RETURN(to_del);
3794 l = evas_object_data_get(obj, "comp_object-to_del");
3795 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3796 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3797 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3801 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3806 EINA_SAFETY_ON_NULL_RETURN(to_del);
3807 l = evas_object_data_get(obj, "comp_object-to_del");
3809 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3812 /////////////////////////////////////////////////////////
3814 EINTERN Evas_Object *
3815 e_comp_object_client_add(E_Client *ec)
3820 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3821 if (ec->frame) return NULL;
3822 _e_comp_smart_init();
3823 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3824 cw = evas_object_smart_data_get(o);
3825 if (!cw) return NULL;
3826 evas_object_data_set(o, "E_Client", ec);
3829 evas_object_data_set(o, "comp_object", (void*)1);
3831 _e_comp_object_event_add(o);
3836 /* utility functions for getting client inset */
3838 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3841 if (!cw->client_inset.calc)
3847 if (ax) *ax = x - cw->client_inset.l;
3848 if (ay) *ay = y - cw->client_inset.t;
3852 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3855 if (!cw->client_inset.calc)
3861 if (ax) *ax = x + cw->client_inset.l;
3862 if (ay) *ay = y + cw->client_inset.t;
3866 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3869 if (!cw->client_inset.calc)
3875 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3876 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3880 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3883 if (!cw->client_inset.calc)
3889 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3890 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3894 e_comp_object_client_get(Evas_Object *obj)
3899 /* FIXME: remove this when eo is used */
3900 o = evas_object_data_get(obj, "comp_smart_obj");
3902 return e_comp_object_client_get(o);
3903 return cw ? cw->ec : NULL;
3907 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3910 if (cw->frame_extends)
3911 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3916 if (w) *w = cw->ec->w;
3917 if (h) *h = cw->ec->h;
3922 e_comp_object_util_zone_get(Evas_Object *obj)
3924 E_Zone *zone = NULL;
3928 zone = cw->ec->zone;
3933 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3934 zone = e_comp_zone_xy_get(x, y);
3940 e_comp_object_util_center(Evas_Object *obj)
3942 int x, y, w, h, ow, oh;
3947 zone = e_comp_object_util_zone_get(obj);
3948 EINA_SAFETY_ON_NULL_RETURN(zone);
3949 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3950 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3951 ow = cw->ec->w, oh = cw->ec->h;
3953 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3954 x = x + (w - ow) / 2;
3955 y = y + (h - oh) / 2;
3956 evas_object_move(obj, x, y);
3960 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3962 int x, y, w, h, ow, oh;
3965 EINA_SAFETY_ON_NULL_RETURN(on);
3966 evas_object_geometry_get(on, &x, &y, &w, &h);
3967 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3968 ow = cw->ec->w, oh = cw->ec->h;
3970 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3971 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3975 e_comp_object_util_fullscreen(Evas_Object *obj)
3980 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3983 evas_object_move(obj, 0, 0);
3984 evas_object_resize(obj, e_comp->w, e_comp->h);
3989 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3997 ow = cw->w, oh = cw->h;
3999 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4000 zone = e_comp_object_util_zone_get(obj);
4001 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4002 if (x) *x = zx + (zw - ow) / 2;
4003 if (y) *y = zy + (zh - oh) / 2;
4007 e_comp_object_input_objs_del(Evas_Object *obj)
4010 E_Input_Rect_Data *input_rect_data;
4011 E_Input_Rect_Smart_Data *input_rect_sd;
4016 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4017 if (!input_rect_sd) return;
4019 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4021 if (input_rect_data->obj)
4023 evas_object_smart_member_del(input_rect_data->obj);
4024 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4026 E_FREE(input_rect_data);
4031 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4034 E_Input_Rect_Data *input_rect_data = NULL;
4035 E_Input_Rect_Smart_Data *input_rect_sd;
4036 int client_w, client_h;
4038 if (cw->ec->client.w)
4039 client_w = cw->ec->client.w;
4041 client_w = cw->ec->w;
4043 if (cw->ec->client.h)
4044 client_h = cw->ec->client.h;
4046 client_h = cw->ec->h;
4048 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4052 _e_comp_input_obj_smart_init();
4053 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4054 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4055 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4058 input_rect_sd->cw = cw;
4061 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4064 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4065 if (input_rect_data)
4067 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4068 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4072 if ((input_rect_data) &&
4073 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4075 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4076 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4077 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4078 evas_object_clip_set(input_rect_data->obj, cw->clip);
4079 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4080 evas_object_geometry_set(input_rect_data->obj,
4081 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4082 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4083 evas_object_pass_events_set(cw->default_input_obj, 1);
4084 evas_object_pass_events_set(cw->obj, 1);
4087 evas_object_show(input_rect_data->obj);
4088 evas_object_show(cw->input_obj);
4093 evas_object_smart_member_del(cw->input_obj);
4094 E_FREE_FUNC(cw->input_obj, evas_object_del);
4095 evas_object_pass_events_set(cw->default_input_obj, 0);
4096 evas_object_pass_events_set(cw->obj, 0);
4101 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4104 E_Input_Rect_Smart_Data *input_rect_sd;
4105 E_Input_Rect_Data *input_rect_data;
4108 if (!cw->input_obj) return;
4110 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4113 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4115 *list = eina_list_append(*list, &input_rect_data->rect);
4121 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4124 if (l) *l = cw->client_inset.l;
4125 if (r) *r = cw->client_inset.r;
4126 if (t) *t = cw->client_inset.t;
4127 if (b) *b = cw->client_inset.b;
4130 /* set geometry for CSD */
4132 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4138 if (cw->frame_object)
4139 CRI("ACK! ec:%p", cw->ec);
4140 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4141 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4142 calc = cw->client_inset.calc;
4143 cw->client_inset.calc = l || r || t || b;
4144 eina_stringshare_replace(&cw->frame_theme, "borderless");
4145 if (cw->client_inset.calc)
4147 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4148 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4149 e_client_size_set(cw->ec, tw, th);
4151 else if (cw->ec->maximized || cw->ec->fullscreen)
4153 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4154 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4156 if (!cw->ec->new_client)
4158 if (calc && cw->client_inset.calc)
4160 tx = cw->ec->x - (l - cw->client_inset.l);
4161 ty = cw->ec->y - (t - cw->client_inset.t);
4162 e_client_pos_set(cw->ec, tx, ty);
4164 cw->ec->changes.pos = cw->ec->changes.size = 1;
4167 cw->client_inset.l = l;
4168 cw->client_inset.r = r;
4169 cw->client_inset.t = t;
4170 cw->client_inset.b = b;
4174 e_comp_object_frame_allowed(Evas_Object *obj)
4176 API_ENTRY EINA_FALSE;
4177 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4181 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4183 API_ENTRY EINA_FALSE;
4184 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4185 eina_stringshare_replace(&cw->frame_name, name);
4186 if (cw->frame_object)
4187 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4192 e_comp_object_frame_exists(Evas_Object *obj)
4194 API_ENTRY EINA_FALSE;
4195 return !!cw->frame_object;
4199 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4201 Evas_Object *o, *pbg;
4204 Eina_Stringshare *theme;
4206 API_ENTRY EINA_FALSE;
4208 if (!e_util_strcmp(cw->frame_theme, name))
4209 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4210 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4211 return _e_comp_object_shadow_setup(cw);
4212 pbg = cw->frame_object;
4213 theme = eina_stringshare_add(name);
4215 if (cw->frame_object)
4219 w = cw->ec->w, h = cw->ec->h;
4220 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4221 if ((cw->ec->w != w) || (cw->ec->h != h))
4223 cw->ec->changes.size = 1;
4226 E_FREE_FUNC(cw->frame_object, evas_object_del);
4227 if (!name) goto reshadow;
4229 o = edje_object_add(e_comp->evas);
4230 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4231 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4232 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4234 cw->frame_object = NULL;
4236 eina_stringshare_del(cw->frame_theme);
4237 cw->frame_theme = theme;
4242 if (theme != e_config->theme_default_border_style)
4244 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4245 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4249 ok = e_theme_edje_object_set(o, "base/theme/border",
4250 "e/widgets/border/default/border");
4251 if (ok && (theme == e_config->theme_default_border_style))
4253 /* Reset default border style to default */
4254 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4255 e_config_save_queue();
4262 cw->frame_object = o;
4263 eina_stringshare_del(cw->frame_theme);
4264 cw->frame_theme = theme;
4265 evas_object_name_set(o, "cw->frame_object");
4268 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4272 cw->ec->changes.icon = 1;
4278 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4283 _e_comp_object_shadow_setup(cw);
4286 int old_x, old_y, new_x = 0, new_y = 0;
4288 old_x = cw->x, old_y = cw->y;
4290 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4292 new_x = cw->ec->x, new_y = cw->ec->y;
4293 else if (cw->ec->placed || (!cw->ec->new_client))
4295 /* if no previous frame:
4296 * - reapply client_inset
4301 if (cw->ec->changes.size)
4308 x = cw->ec->client.x, y = cw->ec->client.y;
4309 x = MAX(cw->ec->zone->x, cw->ec->client.x - cw->client_inset.l);
4310 y = MAX(cw->ec->zone->y, cw->ec->client.y - cw->client_inset.t);
4312 new_x = x, new_y = y;
4315 if (old_x != new_x || old_y != new_y)
4317 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4318 cw->y = cw->x = -99999;
4319 evas_object_move(obj, new_x, new_y);
4323 if (cw->ec->maximized)
4325 cw->ec->changes.need_maximize = 1;
4328 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4329 if (cw->frame_object)
4331 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4334 cw->frame_extends = 0;
4335 evas_object_del(pbg);
4340 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4342 E_Comp_Object_Mover *prov;
4345 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4346 edje_object_signal_emit(cw->shobj, sig, src);
4347 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4348 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4349 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4351 /* start with highest priority callback first */
4352 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4354 if (!e_util_glob_match(sig, prov->sig)) continue;
4355 if (prov->func(prov->data, obj, sig)) break;
4360 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4362 /* FIXME: at some point I guess this should use eo to inherit
4363 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4364 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4367 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4371 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4374 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4378 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4381 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4385 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4388 Eina_Rectangle rect;
4391 if (cw->ec->input_only || (!cw->updates)) return;
4392 if (cw->nocomp) return;
4393 rect.x = x, rect.y = y;
4394 rect.w = w, rect.h = h;
4395 evas_object_smart_callback_call(obj, "damage", &rect);
4397 if (e_comp_is_on_overlay(cw->ec))
4399 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4400 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4401 * E module attempts to block screen update due to the particular policy.
4403 if (e_pixmap_resource_get(cw->ec->pixmap))
4404 cw->hwc_need_update = EINA_TRUE;
4407 /* ignore overdraw */
4408 if (cw->updates_full)
4410 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4411 e_comp_object_render_update_add(obj);
4413 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4414 evas_object_show(cw->smart_obj);
4418 /* clip rect to client surface */
4419 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4420 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4421 /* if rect is the total size of the client after clip, clear the updates
4422 * since this is guaranteed to be the whole region anyway
4424 eina_tiler_area_size_get(cw->updates, &tw, &th);
4425 if ((w > tw) || (h > th))
4427 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4428 eina_tiler_clear(cw->updates);
4429 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4431 tw = cw->ec->client.w, th = cw->ec->client.h;
4433 if ((!x) && (!y) && (w == tw) && (h == th))
4435 eina_tiler_clear(cw->updates);
4436 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4437 cw->updates_full = 1;
4438 cw->update_count = 0;
4441 if (cw->update_count > UPDATE_MAX)
4443 /* this is going to get really dumb, so just update the whole thing */
4444 eina_tiler_clear(cw->updates);
4445 cw->update_count = cw->updates_full = 1;
4446 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4447 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4451 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4452 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4454 cw->updates_exist = 1;
4455 e_comp_object_render_update_add(obj);
4457 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4458 evas_object_show(cw->smart_obj);
4462 e_comp_object_damage_exists(Evas_Object *obj)
4464 API_ENTRY EINA_FALSE;
4465 return cw->updates_exist;
4469 e_comp_object_render_update_add(Evas_Object *obj)
4473 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4474 if (cw->render_update_lock.lock) return;
4475 if (e_object_is_del(E_OBJECT(cw->ec)))
4476 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4477 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4481 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4483 e_comp_render_queue();
4487 e_comp_object_render_update_del(Evas_Object *obj)
4491 if (cw->ec->input_only || (!cw->updates)) return;
4492 if (!cw->update) return;
4494 /* this gets called during comp animating to clear the update flag */
4495 if (e_comp->grabbed) return;
4496 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4497 if (!e_comp->updates)
4499 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4500 if (e_comp->render_animator)
4501 ecore_animator_freeze(e_comp->render_animator);
4506 e_comp_object_shape_apply(Evas_Object *obj)
4510 unsigned int i, *pix, *p;
4514 if (!cw->ec) return; //NYI
4515 if (cw->external_content) return;
4518 if ((cw->ec->shape_rects_num >= 1) &&
4519 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4524 ERR("BUGGER: shape with native surface? cw=%p", cw);
4527 evas_object_image_size_get(cw->obj, &w, &h);
4528 if ((w < 1) || (h < 1)) return;
4531 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4532 _e_comp_object_alpha_set(cw);
4533 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4534 evas_object_image_alpha_set(o, 1);
4536 p = pix = evas_object_image_data_get(cw->obj, 1);
4539 evas_object_image_data_set(cw->obj, pix);
4544 unsigned char *spix, *sp;
4546 spix = calloc(w * h, sizeof(unsigned char));
4548 for (i = 0; i < cw->ec->shape_rects_num; i++)
4552 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4553 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4554 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4555 sp = spix + (w * ry) + rx;
4556 for (py = 0; py < rh; py++)
4558 for (px = 0; px < rw; px++)
4566 for (py = 0; py < h; py++)
4568 for (px = 0; px < w; px++)
4570 unsigned int mask, imask;
4572 mask = ((unsigned int)(*sp)) << 24;
4574 imask |= imask >> 8;
4575 imask |= imask >> 8;
4576 *p = mask | (*p & imask);
4577 //if (*sp) *p = 0xff000000 | *p;
4578 //else *p = 0x00000000;
4587 for (py = 0; py < h; py++)
4589 for (px = 0; px < w; px++)
4593 evas_object_image_data_set(cw->obj, pix);
4594 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4595 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4597 evas_object_image_data_set(o, pix);
4598 evas_object_image_data_update_add(o, 0, 0, w, h);
4600 // don't need to fix alpha chanel as blending
4601 // should be totally off here regardless of
4602 // alpha channel content
4606 _e_comp_object_clear(E_Comp_Object *cw)
4611 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4613 if (cw->render_update_lock.lock) return;
4616 e_pixmap_clear(cw->ec->pixmap);
4618 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4619 evas_object_image_size_set(cw->obj, 1, 1);
4620 evas_object_image_data_set(cw->obj, NULL);
4621 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4623 evas_object_image_size_set(o, 1, 1);
4624 evas_object_image_data_set(o, NULL);
4627 e_comp_object_render_update_del(cw->smart_obj);
4631 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4635 API_ENTRY EINA_FALSE;
4637 if (cw->transparent.set == set)
4642 evas_object_color_get(obj, &r, &g, &b, &a);
4643 evas_object_color_set(obj, 0, 0, 0, 0);
4645 cw->transparent.user_r = r;
4646 cw->transparent.user_g = g;
4647 cw->transparent.user_b = b;
4648 cw->transparent.user_a = a;
4650 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4652 cw->transparent.user_r,
4653 cw->transparent.user_g,
4654 cw->transparent.user_b,
4655 cw->transparent.user_a);
4657 cw->transparent.set = EINA_TRUE;
4661 cw->transparent.set = EINA_FALSE;
4663 evas_object_color_set(obj,
4664 cw->transparent.user_r,
4665 cw->transparent.user_g,
4666 cw->transparent.user_b,
4667 cw->transparent.user_a);
4669 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4671 cw->transparent.user_r,
4672 cw->transparent.user_g,
4673 cw->transparent.user_b,
4674 cw->transparent.user_a);
4680 /* helper function to simplify toggling of redirection for display servers which support it */
4682 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4687 if (cw->redirected == set) return;
4688 cw->redirected = set;
4689 if (cw->external_content) return;
4691 e_comp_object_map_update(obj);
4695 if (cw->updates_exist)
4696 e_comp_object_render_update_add(obj);
4698 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4700 _e_comp_object_transparent_set(obj, EINA_FALSE);
4701 evas_object_smart_callback_call(obj, "redirected", NULL);
4705 _e_comp_object_clear(cw);
4706 _e_comp_object_transparent_set(obj, EINA_TRUE);
4707 evas_object_smart_callback_call(obj, "unredirected", NULL);
4712 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4715 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4717 if (cw->buffer_destroy_listener.notify)
4719 cw->buffer_destroy_listener.notify = NULL;
4720 wl_list_remove(&cw->buffer_destroy_listener.link);
4723 if (e_object_is_del(E_OBJECT(cw->ec)))
4725 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4730 /* if it's current displaying buffer, do not remove its content */
4731 if (!evas_object_visible_get(cw->ec->frame))
4732 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4737 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4742 if (cw->buffer_destroy_listener.notify)
4744 wl_list_remove(&cw->buffer_destroy_listener.link);
4745 cw->buffer_destroy_listener.notify = NULL;
4748 if (cw->tbm_surface)
4750 tbm_surface_internal_unref(cw->tbm_surface);
4751 cw->tbm_surface = NULL;
4756 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4758 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4759 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4761 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4763 tbm_surface_internal_ref(ns->data.tbm.buffer);
4764 cw->tbm_surface = ns->data.tbm.buffer;
4768 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4769 evas_object_image_native_surface_set(cw->obj, ns);
4773 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4775 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4776 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4777 evas_object_image_native_surface_set(o, ns);
4784 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4786 Evas_Native_Surface ns;
4789 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4790 if (cw->ec->input_only) return;
4791 if (cw->external_content) return;
4792 if (cw->render_update_lock.lock) return;
4795 memset(&ns, 0, sizeof(Evas_Native_Surface));
4799 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4800 set = (!cw->ec->shaped);
4802 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4806 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4810 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4813 if (cw->ec->input_only) return;
4816 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4817 _e_comp_object_alpha_set(cw);
4819 e_comp_object_native_surface_set(obj, cw->native);
4820 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4824 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4830 if (cw->blanked == set) return;
4832 _e_comp_object_alpha_set(cw);
4835 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4836 evas_object_image_data_set(cw->obj, NULL);
4840 e_comp_object_native_surface_set(obj, 1);
4841 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4845 _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)
4850 if (!_damage_trace) return;
4854 if (!evas_object_visible_get(cw->obj)) return;
4856 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4858 o = evas_object_rectangle_add(e_comp->evas);
4859 evas_object_layer_set(o, E_LAYER_MAX);
4860 evas_object_name_set(o, "damage_trace");
4861 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4862 evas_object_resize(o, dmg_w, dmg_h);
4863 evas_object_color_set(o, 0, 128, 0, 128);
4864 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4865 evas_object_pass_events_set(o, EINA_TRUE);
4866 evas_object_show(o);
4868 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4870 dmg_w, dmg_h, dmg_x, dmg_y,
4871 origin->w, origin->h, origin->x, origin->y);
4873 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4876 /* mark an object as dirty and setup damages */
4878 e_comp_object_dirty(Evas_Object *obj)
4881 Eina_Rectangle *rect;
4885 Eina_Bool dirty, visible;
4889 if (cw->external_content) return;
4890 if (!cw->redirected) return;
4891 if (cw->render_update_lock.lock)
4893 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4896 /* only actually dirty if pixmap is available */
4897 if (!e_pixmap_resource_get(cw->ec->pixmap))
4899 // e_pixmap_size_get returns last attached buffer size
4900 // eventhough it is destroyed
4901 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4904 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4905 visible = cw->visible;
4906 if (!dirty) w = h = 1;
4907 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4909 evas_object_image_data_set(cw->obj, NULL);
4910 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4911 evas_object_image_size_set(cw->obj, tw, th);
4912 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4913 if (cw->pending_updates)
4914 eina_tiler_area_size_set(cw->pending_updates, w, h);
4915 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4917 evas_object_image_pixels_dirty_set(o, dirty);
4919 evas_object_image_data_set(o, NULL);
4920 evas_object_image_size_set(o, tw, th);
4921 visible |= evas_object_visible_get(o);
4925 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4929 e_comp_object_native_surface_set(obj, 1);
4931 m = _e_comp_object_map_damage_transform_get(cw->ec);
4932 it = eina_tiler_iterator_new(cw->updates);
4933 EINA_ITERATOR_FOREACH(it, rect)
4935 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4936 * of evas engine and doesn't convert damage according to evas_map.
4937 * so damage of evas_object_image use surface coordinate.
4941 int damage_x, damage_y, damage_w, damage_h;
4943 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4944 &damage_x, &damage_y, &damage_w, &damage_h);
4945 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4946 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4950 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4951 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4954 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4955 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4956 if (cw->pending_updates)
4957 eina_tiler_rect_add(cw->pending_updates, rect);
4959 eina_iterator_free(it);
4960 if (m) e_map_free(m);
4961 if (cw->pending_updates)
4962 eina_tiler_clear(cw->updates);
4965 cw->pending_updates = cw->updates;
4966 cw->updates = eina_tiler_new(w, h);
4967 eina_tiler_tile_size_set(cw->updates, 1, 1);
4969 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4970 evas_object_smart_callback_call(obj, "dirty", NULL);
4971 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4972 /* force render if main object is hidden but mirrors are visible */
4973 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4974 e_comp_object_render(obj);
4978 e_comp_object_render(Evas_Object *obj)
4985 API_ENTRY EINA_FALSE;
4987 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4988 if (cw->ec->input_only) return EINA_TRUE;
4989 if (cw->external_content) return EINA_TRUE;
4990 if (cw->native) return EINA_FALSE;
4991 /* if comp object is not redirected state, comp object should not be set by newly committed data
4992 because image size of comp object is 1x1 and it should not be shown on canvas */
4993 if (!cw->redirected) return EINA_TRUE;
4994 if (cw->render_update_lock.lock)
4996 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4999 e_comp_object_render_update_del(obj);
5000 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5002 if (!cw->pending_updates)
5004 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5005 evas_object_image_data_set(cw->obj, NULL);
5006 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5007 evas_object_image_data_set(o, NULL);
5011 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5013 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5015 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5018 e_pixmap_image_refresh(cw->ec->pixmap);
5019 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5022 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5023 e_pixmap_image_data_ref(cw->ec->pixmap);
5025 /* set pixel data */
5026 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5027 _e_comp_object_alpha_set(cw);
5028 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5030 evas_object_image_data_set(o, pix);
5031 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5032 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5035 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5037 e_comp_client_post_update_add(cw->ec);
5042 /* create a duplicate of an evas object */
5044 e_comp_object_util_mirror_add(Evas_Object *obj)
5048 unsigned int *pix = NULL;
5049 Eina_Bool argb = EINA_FALSE;
5054 cw = evas_object_data_get(obj, "comp_mirror");
5057 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5058 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5059 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5060 evas_object_image_alpha_set(o, 1);
5061 evas_object_image_source_set(o, obj);
5064 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5065 if (cw->external_content)
5067 ERR("%p of client %p is external content.", obj, cw->ec);
5070 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5071 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5072 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5073 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5074 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5075 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5076 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5077 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5078 evas_object_data_set(o, "comp_mirror", cw);
5080 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5081 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5083 evas_object_image_size_set(o, tw, th);
5086 pix = evas_object_image_data_get(cw->obj, 0);
5092 evas_object_image_native_surface_set(o, cw->ns);
5095 Evas_Native_Surface ns;
5096 memset(&ns, 0, sizeof(Evas_Native_Surface));
5097 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5098 evas_object_image_native_surface_set(o, &ns);
5103 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5104 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5106 (e_pixmap_image_exists(cw->ec->pixmap)))
5107 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5109 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5116 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5117 evas_object_image_pixels_dirty_set(o, dirty);
5118 evas_object_image_data_set(o, pix);
5119 evas_object_image_data_set(cw->obj, pix);
5121 evas_object_image_data_update_add(o, 0, 0, tw, th);
5126 //////////////////////////////////////////////////////
5129 e_comp_object_effect_allowed_get(Evas_Object *obj)
5131 API_ENTRY EINA_FALSE;
5133 if (!cw->shobj) return EINA_FALSE;
5134 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5135 return !e_comp_config_get()->match.disable_borders;
5138 /* setup an api effect for a client */
5140 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5143 Eina_Stringshare *grp;
5144 E_Comp_Config *config;
5145 Eina_Bool loaded = EINA_FALSE;
5147 API_ENTRY EINA_FALSE;
5148 if (!cw->shobj) return EINA_FALSE; //input window
5150 if (!effect) effect = "none";
5151 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5153 config = e_comp_config_get();
5154 if ((config) && (config->effect_file))
5156 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5158 cw->effect_set = EINA_TRUE;
5165 edje_object_file_get(cw->effect_obj, NULL, &grp);
5166 cw->effect_set = !eina_streq(effect, "none");
5167 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5168 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5170 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5171 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5172 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5174 if (cw->effect_running)
5176 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5179 cw->effect_set = EINA_FALSE;
5180 return cw->effect_set;
5184 if (cw->effect_running)
5186 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5189 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5190 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5191 if (cw->effect_clip)
5193 evas_object_clip_unset(cw->clip);
5194 cw->effect_clip = 0;
5196 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5198 _e_comp_object_dim_update(cw);
5200 return cw->effect_set;
5203 /* set params for embryo scripts in effect */
5205 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5207 Edje_Message_Int_Set *msg;
5211 EINA_SAFETY_ON_NULL_RETURN(params);
5212 EINA_SAFETY_ON_FALSE_RETURN(count);
5213 if (!cw->effect_set) return;
5215 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5216 msg->count = (int)count;
5217 for (x = 0; x < count; x++)
5218 msg->val[x] = params[x];
5219 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5220 edje_object_message_signal_process(cw->effect_obj);
5224 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5226 Edje_Signal_Cb end_cb;
5228 E_Comp_Object *cw = data;
5230 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5231 cw->effect_running = 0;
5232 if (!_e_comp_object_animating_end(cw)) return;
5234 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5236 evas_object_data_del(cw->smart_obj, "effect_running");
5237 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5238 e_client_visibility_calculate();
5241 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5242 if (!end_cb) return;
5243 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5244 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5245 end_cb(end_data, cw->smart_obj, emission, source);
5248 /* clip effect to client's zone */
5250 e_comp_object_effect_clip(Evas_Object *obj)
5253 if (!cw->ec->zone) return;
5254 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5255 if (!cw->effect_clip_able) return;
5256 evas_object_clip_set(cw->smart_obj, cw->ec->zone->bg_clip_object);
5257 cw->effect_clip = 1;
5260 /* unclip effect from client's zone */
5262 e_comp_object_effect_unclip(Evas_Object *obj)
5265 if (!cw->effect_clip) return;
5266 evas_object_clip_unset(cw->smart_obj);
5267 cw->effect_clip = 0;
5270 /* start effect, running end_cb after */
5272 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5274 API_ENTRY EINA_FALSE;
5275 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5276 if (!cw->effect_set) return EINA_FALSE;
5278 if (cw->effect_running)
5280 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5283 e_comp_object_effect_clip(obj);
5284 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5286 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5287 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5288 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5289 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5291 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5292 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5294 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5295 _e_comp_object_animating_begin(cw);
5296 cw->effect_running = 1;
5300 /* stop a currently-running effect immediately */
5302 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5305 Edje_Signal_Cb end_cb_before = NULL;
5306 void *end_data_before = NULL;
5307 API_ENTRY EINA_FALSE;
5309 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5310 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5312 if (end_cb_before != end_cb) return EINA_TRUE;
5313 e_comp_object_effect_unclip(obj);
5314 if (cw->effect_clip)
5316 evas_object_clip_unset(cw->effect_obj);
5317 cw->effect_clip = 0;
5319 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5320 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5322 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5324 evas_object_data_del(cw->smart_obj, "effect_running");
5325 e_client_visibility_calculate();
5328 cw->effect_running = 0;
5329 ret = _e_comp_object_animating_end(cw);
5331 if ((ret) && (end_cb_before))
5333 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5334 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5341 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5343 return a->pri - b->pri;
5346 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5347 E_API E_Comp_Object_Mover *
5348 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5350 E_Comp_Object_Mover *prov;
5352 prov = E_NEW(E_Comp_Object_Mover, 1);
5353 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5354 prov->func = provider;
5355 prov->data = (void*)data;
5358 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5359 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5364 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5366 EINA_SAFETY_ON_NULL_RETURN(prov);
5367 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5372 e_comp_object_effect_object_get(Evas_Object *obj)
5376 return cw->effect_obj;
5380 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5382 API_ENTRY EINA_FALSE;
5383 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5384 if (!cw->effect_set) return EINA_FALSE;
5391 ////////////////////////////////////
5394 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5396 if (e_comp->autoclose.obj)
5398 e_comp_ungrab_input(0, 1);
5399 if (e_comp->autoclose.del_cb)
5400 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5401 else if (!already_del)
5403 evas_object_hide(e_comp->autoclose.obj);
5404 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5406 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5408 e_comp->autoclose.obj = NULL;
5409 e_comp->autoclose.data = NULL;
5410 e_comp->autoclose.del_cb = NULL;
5411 e_comp->autoclose.key_cb = NULL;
5412 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5416 _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)
5418 _e_comp_object_autoclose_cleanup(0);
5422 _e_comp_object_autoclose_setup(Evas_Object *obj)
5424 if (!e_comp->autoclose.rect)
5426 /* create rect just below autoclose object to catch mouse events */
5427 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5428 evas_object_move(e_comp->autoclose.rect, 0, 0);
5429 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5430 evas_object_show(e_comp->autoclose.rect);
5431 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5432 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5433 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5434 e_comp_grab_input(0, 1);
5436 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5437 evas_object_focus_set(obj, 1);
5441 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5443 _e_comp_object_autoclose_setup(obj);
5444 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5448 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5450 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5451 _e_comp_object_autoclose_cleanup(1);
5452 if (e_client_focused_get()) return;
5453 if (e_config->focus_policy != E_FOCUS_MOUSE)
5458 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5462 if (e_comp->autoclose.obj)
5464 if (e_comp->autoclose.obj == obj) return;
5465 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5466 e_comp->autoclose.obj = obj;
5467 e_comp->autoclose.del_cb = del_cb;
5468 e_comp->autoclose.key_cb = cb;
5469 e_comp->autoclose.data = (void*)data;
5470 if (evas_object_visible_get(obj))
5471 _e_comp_object_autoclose_setup(obj);
5473 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5474 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5477 e_comp->autoclose.obj = obj;
5478 e_comp->autoclose.del_cb = del_cb;
5479 e_comp->autoclose.key_cb = cb;
5480 e_comp->autoclose.data = (void*)data;
5481 if (evas_object_visible_get(obj))
5482 _e_comp_object_autoclose_setup(obj);
5484 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5485 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5489 e_comp_object_is_animating(Evas_Object *obj)
5493 return cw->animating;
5497 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5501 if ((cw->external_content) &&
5502 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5504 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5505 "But current external content is %d object for %p.",
5506 cw->content_type, cw->ec);
5510 cw->user_alpha_set = EINA_TRUE;
5511 cw->user_alpha = alpha;
5513 if (!cw->obj) return;
5515 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5517 evas_object_image_alpha_set(cw->obj, alpha);
5519 if ((!cw->native) && (!cw->external_content))
5520 evas_object_image_data_set(cw->obj, NULL);
5524 e_comp_object_alpha_get(Evas_Object *obj)
5526 API_ENTRY EINA_FALSE;
5528 return evas_object_image_alpha_get(cw->obj);
5532 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5534 Eina_Bool mask_set = EINA_FALSE;
5538 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5539 if (cw->ec->input_only) return;
5546 o = evas_object_rectangle_add(e_comp->evas);
5547 evas_object_color_set(o, 0, 0, 0, 0);
5548 evas_object_clip_set(o, cw->clip);
5549 evas_object_smart_member_add(o, obj);
5550 evas_object_move(o, 0, 0);
5551 evas_object_resize(o, cw->w, cw->h);
5552 /* save render op value to restore when clear a mask.
5554 * NOTE: DO NOT change the render op on ec->frame while mask object
5555 * is set. it will overwrite the changed op value. */
5556 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5557 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5558 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5559 if (cw->visible) evas_object_show(o);
5562 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5563 ELOGF("COMP", " |mask_obj", cw->ec);
5564 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5571 evas_object_smart_member_del(cw->mask.obj);
5572 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5574 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5575 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5581 e_comp_object_mask_has(Evas_Object *obj)
5583 API_ENTRY EINA_FALSE;
5585 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5589 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5594 if ((cw->external_content) &&
5595 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5597 WRN("Can set up size to ONLY evas \"image\" object. "
5598 "But current external content is %d object for %p.",
5599 cw->content_type, cw->ec);
5603 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5605 evas_object_image_size_set(cw->obj, tw, th);
5609 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5611 Eina_Bool transform_set = EINA_FALSE;
5613 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5614 if (cw->ec->input_only) return;
5616 transform_set = !!set;
5620 if (!cw->transform_bg_obj)
5622 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5623 evas_object_move(o, 0, 0);
5624 evas_object_resize(o, 1, 1);
5625 if (cw->transform_bg_color.a >= 255)
5626 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5628 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5629 evas_object_color_set(o,
5630 cw->transform_bg_color.r,
5631 cw->transform_bg_color.g,
5632 cw->transform_bg_color.b,
5633 cw->transform_bg_color.a);
5634 if (cw->visible) evas_object_show(o);
5636 cw->transform_bg_obj = o;
5637 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5639 _e_comp_object_transform_obj_stack_update(obj);
5643 if (cw->transform_bg_obj)
5645 evas_object_smart_member_del(cw->transform_bg_obj);
5646 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5652 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5656 cw->transform_bg_color.r = r;
5657 cw->transform_bg_color.g = g;
5658 cw->transform_bg_color.b = b;
5659 cw->transform_bg_color.a = a;
5661 if (cw->transform_bg_obj)
5663 evas_object_color_set(cw->transform_bg_obj,
5664 cw->transform_bg_color.r,
5665 cw->transform_bg_color.g,
5666 cw->transform_bg_color.b,
5667 cw->transform_bg_color.a);
5672 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5675 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5676 if (cw->ec->input_only) return;
5677 if (!cw->transform_bg_obj) return;
5679 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5683 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5686 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5687 if (cw->ec->input_only) return;
5688 if (!cw->transform_bg_obj) return;
5690 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5694 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5696 Eina_Bool transform_set = EINA_FALSE;
5698 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5699 if (cw->ec->input_only) return;
5701 transform_set = !!set;
5705 if (!cw->transform_tranp_obj)
5707 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5708 evas_object_move(o, 0, 0);
5709 evas_object_resize(o, 1, 1);
5710 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5711 evas_object_color_set(o, 0, 0, 0, 0);
5712 if (cw->visible) evas_object_show(o);
5714 cw->transform_tranp_obj = o;
5715 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5717 _e_comp_object_transform_obj_stack_update(obj);
5721 if (cw->transform_tranp_obj)
5723 evas_object_smart_member_del(cw->transform_tranp_obj);
5724 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5730 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5733 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5734 if (cw->ec->input_only) return;
5735 if (!cw->transform_tranp_obj) return;
5737 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5741 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5744 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5745 if (cw->ec->input_only) return;
5746 if (!cw->transform_tranp_obj) return;
5748 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5752 e_comp_object_layer_update(Evas_Object *obj,
5753 Evas_Object *above, Evas_Object *below)
5755 E_Comp_Object *cw2 = NULL;
5756 Evas_Object *o = NULL;
5761 if (cw->ec->layer_block) return;
5762 if ((above) && (below))
5764 ERR("Invalid layer update request! cw=%p", cw);
5772 layer = evas_object_layer_get(o);
5773 cw2 = evas_object_data_get(o, "comp_obj");
5776 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5778 o = evas_object_above_get(o);
5779 if ((!o) || (o == cw->smart_obj)) break;
5780 if (evas_object_layer_get(o) != layer)
5782 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5787 ec = e_client_top_get();
5788 if (ec) o = ec->frame;
5791 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5795 _e_comp_object_layers_remove(cw);
5798 if (cw2->layer > cw->layer)
5799 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5800 else if (cw2->layer == cw->layer)
5803 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5805 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5807 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5810 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5813 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5817 e_comp_object_layer_get(Evas_Object *obj)
5824 e_comp_object_content_set(Evas_Object *obj,
5825 Evas_Object *content,
5826 E_Comp_Object_Content_Type type)
5828 API_ENTRY EINA_FALSE;
5830 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5831 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5832 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5836 ERR("Can't set e.swallow.content to requested content. "
5837 "Previous comp object should not be changed at all.");
5841 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5843 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5844 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5846 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5847 type, content, cw->ec, cw->ec->pixmap);
5851 cw->external_content = EINA_TRUE;
5854 cw->content_type = type;
5855 e_util_size_debug_set(cw->obj, 1);
5856 evas_object_name_set(cw->obj, "cw->obj");
5857 _e_comp_object_alpha_set(cw);
5860 _e_comp_object_shadow_setup(cw);
5866 e_comp_object_content_unset(Evas_Object *obj)
5868 API_ENTRY EINA_FALSE;
5870 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5871 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5873 if (!cw->obj && !cw->ec->visible)
5875 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5879 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5881 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5887 if (cw->frame_object)
5888 edje_object_part_unswallow(cw->frame_object, cw->obj);
5890 edje_object_part_unswallow(cw->shobj, cw->obj);
5892 evas_object_del(cw->obj);
5893 evas_object_hide(cw->obj);
5897 cw->external_content = EINA_FALSE;
5898 if (cw->ec->is_cursor)
5901 DBG("%p is cursor surface..", cw->ec);
5902 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5904 evas_object_resize(cw->ec->frame, pw, ph);
5905 evas_object_hide(cw->ec->frame);
5910 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5911 cw->obj = evas_object_image_filled_add(e_comp->evas);
5912 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5913 e_util_size_debug_set(cw->obj, 1);
5914 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5915 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5916 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5917 evas_object_name_set(cw->obj, "cw->obj");
5918 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5919 _e_comp_object_alpha_set(cw);
5922 _e_comp_object_shadow_setup(cw);
5927 _e_comp_intercept_show_helper(cw);
5931 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5932 e_comp_object_dirty(cw->smart_obj);
5933 e_comp_object_render(cw->smart_obj);
5934 e_comp_object_render_update_add(obj);
5939 EINTERN Evas_Object *
5940 e_comp_object_content_get(Evas_Object *obj)
5944 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5946 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5948 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5955 E_API E_Comp_Object_Content_Type
5956 e_comp_object_content_type_get(Evas_Object *obj)
5958 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5960 return cw->content_type;
5964 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5967 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5968 E_Comp_Config *conf = e_comp_config_get();
5969 if (cw->ec->input_only) return;
5970 if (!conf->dim_rect_enable) return;
5972 cw->dim.mask_set = mask_set;
5978 if (!cw->dim.enable) return;
5979 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5983 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5985 Eina_Bool mask_set = EINA_FALSE;
5989 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5990 E_Comp_Config *conf = e_comp_config_get();
5991 if (cw->ec->input_only) return;
5992 if (!conf->dim_rect_enable) return;
5998 if (cw->dim.mask_obj)
6000 evas_object_smart_member_del(cw->dim.mask_obj);
6001 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6004 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);
6005 o = evas_object_rectangle_add(e_comp->evas);
6006 evas_object_color_set(o, 0, 0, 0, 0);
6007 evas_object_smart_member_add(o, obj);
6008 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6009 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6011 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6012 if (cw->visible) evas_object_show(o);
6014 cw->dim.mask_obj = o;
6015 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6017 evas_object_layer_set(cw->dim.mask_obj, 9998);
6021 if (cw->dim.mask_obj)
6023 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6024 evas_object_smart_member_del(cw->dim.mask_obj);
6025 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6031 e_comp_object_dim_client_set(E_Client *ec)
6033 E_Comp_Config *conf = e_comp_config_get();
6035 if (!conf->dim_rect_enable) return ;
6036 if (dim_client == ec) return;
6038 Eina_Bool prev_dim = EINA_FALSE;
6039 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6041 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6042 prev_dim = EINA_TRUE;
6044 if (prev_dim && dim_client->visible && ec)
6046 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6047 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6051 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6052 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6058 e_comp_object_dim_client_get(void)
6060 E_Comp_Config *conf = e_comp_config_get();
6062 if (!conf->dim_rect_enable ) return NULL;
6068 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6071 char emit[32] = "\0";
6072 E_Comp_Config *conf = e_comp_config_get();
6075 if (!conf->dim_rect_enable) return;
6076 if (!cw->effect_obj) return;
6077 if (enable == cw->dim.enable) return;
6079 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6080 if (noeffect || !conf->dim_rect_effect)
6082 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6086 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6089 cw->dim.enable = enable;
6091 if (cw->dim.mask_set && !enable)
6093 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6094 edje_object_signal_emit(cw->effect_obj, emit, "e");
6096 else if (cw->dim.mask_set && enable)
6098 edje_object_signal_emit(cw->effect_obj, emit, "e");
6099 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6103 edje_object_signal_emit(cw->effect_obj, emit, "e");
6108 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6110 API_ENTRY EINA_FALSE;
6111 E_Comp_Config *conf = e_comp_config_get();
6113 if (!ec) return EINA_FALSE;
6114 if (!conf->dim_rect_enable) return EINA_FALSE;
6116 if (cw->dim.enable) return EINA_TRUE;
6122 _e_comp_object_dim_update(E_Comp_Object *cw)
6124 E_Comp_Config *conf = e_comp_config_get();
6127 if (!conf->dim_rect_enable) return;
6128 if (!cw->effect_obj) return;
6131 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6132 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6134 if (cw->dim.mask_set)
6136 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6142 e_comp_object_clear(Evas_Object *obj)
6146 _e_comp_object_clear(cw);
6150 e_comp_object_hwc_update_exists(Evas_Object *obj)
6152 API_ENTRY EINA_FALSE;
6153 return cw->hwc_need_update;
6158 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6161 cw->hwc_need_update = set;
6165 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6167 API_ENTRY EINA_FALSE;
6168 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6172 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6175 if (cw->indicator.obj != indicator)
6176 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6177 cw->indicator.obj = indicator;
6178 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6182 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6185 if (cw->indicator.obj != indicator) return;
6186 cw->indicator.obj = NULL;
6187 edje_object_part_unswallow(cw->shobj, indicator);
6191 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6194 Edje_Message_Int_Set *msg;
6196 if (!cw->indicator.obj) return;
6198 cw->indicator.w = w;
6199 cw->indicator.h = h;
6201 if (!cw->shobj) return;
6203 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6207 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6208 edje_object_message_signal_process(cw->shobj);
6211 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6213 e_comp_object_map_update(Evas_Object *obj)
6216 E_Client *ec = cw->ec;
6217 E_Comp_Wl_Client_Data *cdata;
6219 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6222 int l, remain = sizeof buffer;
6225 if (e_object_is_del(E_OBJECT(ec))) return;
6226 cdata = e_client_cdata_get(ec);
6229 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6230 * when new buffer is attached.
6232 if (!cdata->buffer_ref.buffer) return;
6234 if ((!cw->redirected) ||
6235 (e_client_video_hw_composition_check(ec)) ||
6236 (!e_comp_wl_output_buffer_transform_get(ec) &&
6237 cdata->scaler.buffer_viewport.buffer.scale == 1))
6239 if (evas_object_map_enable_get(cw->effect_obj))
6241 ELOGF("TRANSFORM", "map: disable", cw->ec);
6242 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6243 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6244 evas_object_resize(cw->effect_obj, tw, th);
6251 EINA_SAFETY_ON_NULL_RETURN(map);
6253 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6259 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6261 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6262 e_map_point_image_uv_set(map, 0, x, y);
6263 l = snprintf(p, remain, "%d,%d", x, y);
6264 p += l, remain -= l;
6266 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6267 e_map_point_image_uv_set(map, 1, x, y);
6268 l = snprintf(p, remain, " %d,%d", x, y);
6269 p += l, remain -= l;
6271 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6272 e_map_point_image_uv_set(map, 2, x, y);
6273 l = snprintf(p, remain, " %d,%d", x, y);
6274 p += l, remain -= l;
6276 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6277 e_map_point_image_uv_set(map, 3, x, y);
6278 l = snprintf(p, remain, " %d,%d", x, y);
6279 p += l, remain -= l;
6281 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6283 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6285 e_comp_object_map_set(cw->effect_obj, map);
6286 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6290 /* if there's screen rotation with comp mode, then ec->effect_obj and
6291 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6293 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6294 evas_object_resize(cw->effect_obj, tw, th);
6298 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6300 API_ENTRY EINA_FALSE;
6302 cw->render_trace = set;
6308 e_comp_object_native_usable_get(Evas_Object *obj)
6310 API_ENTRY EINA_FALSE;
6311 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6313 if (cw->ec->input_only) return EINA_FALSE;
6314 if (cw->external_content) return EINA_FALSE;
6315 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6317 /* just return true value, if it is normal case */
6318 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6321 Evas_Native_Surface *ns;
6322 ns = evas_object_image_native_surface_get(cw->obj);
6324 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6327 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6335 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6337 API_ENTRY EINA_FALSE;
6338 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6339 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6340 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6344 case E_COMP_IMAGE_FILTER_BLUR:
6345 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6347 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6348 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6350 case E_COMP_IMAGE_FILTER_INVERSE:
6351 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6353 case E_COMP_IMAGE_FILTER_NONE:
6355 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6359 cw->image_filter = filter;
6364 EINTERN E_Comp_Image_Filter
6365 e_comp_object_image_filter_get(Evas_Object *obj)
6367 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6368 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6369 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6370 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6372 return cw->image_filter;
6376 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6380 if (!_damage_trace) return;
6382 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6383 evas_object_del(obj);
6385 _damage_trace_post_objs = NULL;
6389 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6391 if (!_damage_trace) return;
6393 _damage_trace_post_objs = _damage_trace_objs;
6394 _damage_trace_objs = NULL;
6398 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6400 if (_damage_trace == onoff) return;
6404 evas_event_callback_add(e_comp->evas,
6405 EVAS_CALLBACK_RENDER_PRE,
6406 _e_comp_object_damage_trace_render_pre_cb,
6409 evas_event_callback_add(e_comp->evas,
6410 EVAS_CALLBACK_RENDER_POST,
6411 _e_comp_object_damage_trace_render_post_cb,
6418 EINA_LIST_FREE(_damage_trace_objs, obj)
6419 evas_object_del(obj);
6421 _damage_trace_objs = NULL;
6423 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6424 evas_object_del(obj);
6426 _damage_trace_post_objs = NULL;
6428 evas_event_callback_del(e_comp->evas,
6429 EVAS_CALLBACK_RENDER_PRE,
6430 _e_comp_object_damage_trace_render_pre_cb);
6432 evas_event_callback_del(e_comp->evas,
6433 EVAS_CALLBACK_RENDER_POST,
6434 _e_comp_object_damage_trace_render_post_cb);
6437 _damage_trace = onoff;
6441 e_comp_object_redirected_get(Evas_Object *obj)
6443 API_ENTRY EINA_FALSE;
6444 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6446 return cw->redirected;
6450 e_comp_object_color_visible_get(Evas_Object *obj)
6452 API_ENTRY EINA_FALSE;
6455 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6457 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6461 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6465 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6469 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6477 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6479 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6481 return e_map_set_to_comp_object(em, obj);
6485 e_comp_object_map_get(const Evas_Object *obj)
6487 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6489 return e_map_get_from_comp_object(obj);
6493 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6495 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6497 evas_object_map_enable_set(obj, enable);
6503 e_comp_object_render_update_lock(Evas_Object *obj)
6505 API_ENTRY EINA_FALSE;
6507 if (cw->render_update_lock.lock == 0)
6509 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6510 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
6511 e_pixmap_resource_get(cw->ec->pixmap));
6512 e_comp_object_render_update_del(obj);
6513 ELOGF("COMP", "Render update lock enabled", cw->ec);
6516 cw->render_update_lock.lock++;
6522 e_comp_object_render_update_unlock(Evas_Object *obj)
6526 if (cw->render_update_lock.lock == 0)
6529 cw->render_update_lock.lock--;
6531 if (cw->render_update_lock.lock == 0)
6534 if (cw->render_update_lock.pending_move_set)
6536 evas_object_move(obj,
6537 cw->render_update_lock.pending_move_x,
6538 cw->render_update_lock.pending_move_y);
6539 cw->render_update_lock.pending_move_x = 0;
6540 cw->render_update_lock.pending_move_y = 0;
6541 cw->render_update_lock.pending_move_set = EINA_FALSE;
6544 if (cw->render_update_lock.pending_resize_set)
6546 evas_object_resize(obj,
6547 cw->render_update_lock.pending_resize_w,
6548 cw->render_update_lock.pending_resize_h);
6549 cw->render_update_lock.pending_resize_w = 0;
6550 cw->render_update_lock.pending_resize_h = 0;
6551 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6554 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6556 if ((cw->ec->exp_iconify.buffer_flush) &&
6557 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6558 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6559 e_comp_object_clear(obj);
6561 e_comp_object_render_update_add(obj);
6563 ELOGF("COMP", "Render update lock disabled", cw->ec);
6568 e_comp_object_render_update_lock_get(Evas_Object *obj)
6570 API_ENTRY EINA_FALSE;
6572 if (cw->render_update_lock.lock > 0)
6579 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6583 if (cw->transparent.set)
6585 if (r) *r = cw->transparent.user_r;
6586 if (g) *g = cw->transparent.user_g;
6587 if (b) *b = cw->transparent.user_b;
6588 if (a) *a = cw->transparent.user_a;
6592 evas_object_color_get(obj, r, g, b, a);