2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
5 #include "e_bindings_intern.h"
6 #include "e_utils_intern.h"
7 #ifdef REFACTOR_DESK_AREA
9 #include "e_comp_canvas_intern.h"
12 #include "e_comp_cfdata_intern.h"
13 #include "e_comp_wl_subsurface_intern.h"
14 #include "e_comp_wl_tbm_intern.h"
15 #include "e_comp_intern.h"
19 = keys that return objects =
20 - E_Client: the client associated with the object (E_Client*)
21 - comp_smart_obj: cw->smart_obj (Evas_Object*)
22 - comp_obj: cw (E_Comp_Object*)
24 = keys that are bool flags =
25 - client_restack: client needs a protocol-level restack
26 - comp_override: object is triggering a nocomp override to force compositing
27 - comp_ref: object has a ref from visibility animations
28 - comp_showing: object is currently running its show animation
29 - comp_hiding: object is currently running its hiding animation
30 - comp_object: object is a compositor-created object
31 - comp_object_skip: object has a name which prohibits theme shadows
32 - comp_object-to_del: list of objects which will be deleted when this object is deleted
33 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
34 - effect_running: object is animating by external module
37 #define UPDATE_MAX 512 // same as evas
38 #define FAILURE_MAX 2 // seems reasonable
39 #define SMART_NAME "e_comp_object"
40 #define INPUT_OBJ_SMART_NAME "input_object"
42 /* for non-util functions */
43 #define API_ENTRY E_Comp_Object *cw; \
44 cw = evas_object_smart_data_get(obj); \
45 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
47 /* for util functions (obj may or may not be E_Comp_Object */
48 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
51 CRI("YOU PASSED NULL! ARGH!"); \
54 cw = evas_object_smart_data_get(obj); \
55 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
57 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
59 /* enable for lots of client size info in console output */
61 # define e_util_size_debug_set(x, y)
64 /* enable along with display-specific damage INF calls to enable render tracing
68 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
70 #define RENDER_DEBUG(...)
73 #ifdef REFACTOR_DESK_AREA
75 typedef struct _E_Comp_Object
79 int x, y, w, h; // geometry
83 E_Comp_Object_Frame client_inset;
85 Eina_Stringshare *frame_theme;
86 Eina_Stringshare *frame_name;
87 Eina_Stringshare *visibility_effect; //effect when toggling visibility
89 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
91 Evas_Object *smart_obj; // smart object
92 Evas_Object *clip; // clipper over effect object
93 Evas_Object *input_obj; // input smart object
94 Evas_Object *obj; // composite object
95 Evas_Object *frame_object; // for client frames
96 Evas_Object *shobj; // shadow object
97 Evas_Object *effect_obj; // effects object
98 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
102 } transform_bg_color;
103 Evas_Object *transform_tranp_obj;// transform transp rect obj
104 Evas_Object *default_input_obj; // default input object
105 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
106 Eina_List *obj_mirror; // extra mirror objects
107 Eina_Tiler *updates; //render update regions
108 Eina_Tiler *pending_updates; //render update regions which are about to render
110 Evas_Native_Surface *ns; //for custom gl rendering
112 struct wl_listener buffer_destroy_listener;
114 unsigned int update_count; // how many updates have happened to this obj
116 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
118 unsigned int animating; // it's busy animating
119 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
120 unsigned int force_visible; //number of visible obj_mirror objects
121 Eina_Bool delete_pending : 1; // delete pending
122 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
123 Eina_Bool showing : 1; // object is currently in "show" animation
124 Eina_Bool hiding : 1; // object is currently in "hide" animation
125 Eina_Bool visible : 1; // is visible
127 Eina_Bool shaped : 1; // is shaped
128 Eina_Bool update : 1; // has updates to fetch
129 Eina_Bool redirected : 1; // has updates to fetch
130 Eina_Bool native : 1; // native
132 Eina_Bool nocomp : 1; // nocomp applied
133 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
134 Eina_Bool real_hid : 1; // last hide was a real window unmap
136 Eina_Bool effect_set : 1; //effect_obj has a valid group
137 Eina_Bool effect_running : 1; //effect_obj is playing an animation
138 Eina_Bool effect_clip : 1; //effect_obj is clipped
139 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
141 Eina_Bool updates_exist : 1;
142 Eina_Bool updates_full : 1; // entire object will be updated
144 Eina_Bool force_move : 1;
145 Eina_Bool frame_extends : 1; //frame may extend beyond object size
146 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
147 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
148 Eina_Bool user_alpha_set : 1;
149 Eina_Bool user_alpha : 1;
153 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
154 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
161 } indicator; //indicator object for internal client
165 Evas_Object *mask_obj;
168 int mask_x, mask_y, mask_w, mask_h;
171 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
173 tbm_surface_h tbm_surface;
174 E_Comp_Image_Filter image_filter;
175 Eina_Bool set_mouse_callbacks;
180 E_Comp_Wl_Buffer_Ref buffer_ref;
181 Eina_Bool pending_move_set;
182 int pending_move_x, pending_move_y;
183 Eina_Bool pending_resize_set;
184 int pending_resize_w, pending_resize_h;
185 } render_update_lock;
198 struct wl_signal lower;
199 //#ifdef REFACTOR_DESK_AREA
200 struct wl_signal raise;
202 struct wl_signal show;
203 struct wl_signal hide;
204 //#ifdef REFACTOR_DESK_AREA
205 struct wl_signal set_layer;
206 struct wl_signal stack_above;
207 struct wl_signal stack_below;
213 typedef struct _E_Input_Rect_Data
219 typedef struct _E_Input_Rect_Smart_Data
221 Eina_List *input_rect_data_list;
223 } E_Input_Rect_Smart_Data;
225 struct E_Comp_Object_Mover
228 E_Comp_Object_Mover_Cb func;
234 static Eina_Inlist *_e_comp_object_movers = NULL;
235 static Evas_Smart *_e_comp_smart = NULL;
236 static Evas_Smart *_e_comp_input_obj_smart = NULL;
238 static int _e_comp_object_hooks_delete = 0;
239 static int _e_comp_object_hooks_walking = 0;
241 static Eina_Inlist *_e_comp_object_hooks[] =
243 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
244 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
245 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
246 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
247 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
248 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
249 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
250 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
253 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
254 static int _e_comp_object_intercept_hooks_delete = 0;
255 static int _e_comp_object_intercept_hooks_walking = 0;
257 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
259 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
260 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
264 static Eina_Bool _damage_trace = EINA_FALSE;
265 static Eina_List *_damage_trace_objs = NULL;
266 static Eina_List *_damage_trace_post_objs = NULL;
268 /* sekrit functionzzz */
269 EINTERN void e_client_focused_set(E_Client *ec);
271 /* emitted every time a new noteworthy comp object is added */
272 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
274 /* ecore event define */
275 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
276 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
277 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
279 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
280 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
281 static void _e_comp_object_dim_update(E_Comp_Object *cw);
282 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
283 #ifdef REFACTOR_DESK_AREA
285 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
288 static E_Client *dim_client = NULL;
291 _e_comp_object_hooks_clean(void)
294 E_Comp_Object_Hook *ch;
297 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
298 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
300 if (!ch->delete_me) continue;
301 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
307 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
309 E_Comp_Object_Hook *ch;
310 Eina_Bool ret = EINA_TRUE;
312 if (e_object_is_del(E_OBJECT(ec)))
314 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
315 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
316 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
317 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
318 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
319 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
320 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
321 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
327 e_object_ref(E_OBJECT(ec));
328 _e_comp_object_hooks_walking++;
329 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
331 if (ch->delete_me) continue;
332 if (!(ch->func(ch->data, ec)))
338 _e_comp_object_hooks_walking--;
339 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
340 _e_comp_object_hooks_clean();
342 e_object_unref(E_OBJECT(ec));
347 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
349 _e_comp_object_intercept_hooks_clean(void)
352 E_Comp_Object_Intercept_Hook *ch;
355 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
356 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
358 if (!ch->delete_me) continue;
359 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
365 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
367 E_Comp_Object_Intercept_Hook *ch;
368 Eina_Bool ret = EINA_TRUE;
370 if (e_object_is_del(E_OBJECT(ec))) return ret;
371 e_object_ref(E_OBJECT(ec));
372 _e_comp_object_intercept_hooks_walking++;
373 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
375 if (ch->delete_me) continue;
376 if (!(ch->func(ch->data, ec)))
382 _e_comp_object_intercept_hooks_walking--;
383 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
384 _e_comp_object_intercept_hooks_clean();
386 e_object_unref(E_OBJECT(ec));
393 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
395 E_Event_Comp_Object *ev = event;
398 ec = evas_object_data_get(ev->comp_object, "E_Client");
402 e_object_unref(E_OBJECT(ec));
404 evas_object_unref(ev->comp_object);
409 _e_comp_object_event_add(Evas_Object *obj)
411 E_Event_Comp_Object *ev;
414 if (stopping) return;
415 ev = E_NEW(E_Event_Comp_Object, 1);
416 EINA_SAFETY_ON_NULL_RETURN(ev);
418 evas_object_ref(obj);
419 ev->comp_object = obj;
420 ec = evas_object_data_get(ev->comp_object, "E_Client");
424 e_object_ref(E_OBJECT(ec));
426 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
430 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
432 E_Event_Comp_Object *ev = event;
435 ec = evas_object_data_get(ev->comp_object, "E_Client");
439 e_object_unref(E_OBJECT(ec));
441 evas_object_unref(ev->comp_object);
446 _e_comp_object_event_simple(Evas_Object *obj, int type)
448 E_Event_Comp_Object *ev;
451 ev = E_NEW(E_Event_Comp_Object, 1);
454 evas_object_ref(obj);
455 ev->comp_object = obj;
456 ec = evas_object_data_get(ev->comp_object, "E_Client");
460 e_object_ref(E_OBJECT(ec));
462 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
464 /////////////////////////////////////
467 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
469 E_Comp_Object *cw = data;
471 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
475 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
477 E_Comp_Object *cw = data;
479 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
480 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
483 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
484 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
488 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
490 E_Comp_Object *cw = data;
493 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
494 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
497 /////////////////////////////////////
499 #ifdef REFACTOR_DESK_AREA
501 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
504 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
509 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
510 if (cw->ec->input_only) return;
512 layer = evas_object_layer_get(obj);
514 if (cw->transform_bg_obj)
516 if (layer != evas_object_layer_get(cw->transform_bg_obj))
518 evas_object_layer_set(cw->transform_bg_obj, layer);
521 evas_object_stack_below(cw->transform_bg_obj, obj);
524 if (cw->transform_tranp_obj)
526 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
528 evas_object_layer_set(cw->transform_tranp_obj, layer);
531 evas_object_stack_below(cw->transform_tranp_obj, obj);
536 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
543 if (!map) return NULL;
545 e_map_util_points_populate_from_object_full(map, obj, 0);
546 e_map_util_points_color_set(map, 255, 255, 255, 255);
548 for (i = 0 ; i < 4 ; ++i)
553 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
554 e_map_point_coord_set(map, i, x, y, 1.0);
561 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
567 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
570 e_comp_object_map_set(obj, map);
571 e_comp_object_map_enable_set(obj, EINA_TRUE);
578 evas_object_map_enable_set(obj, EINA_FALSE);
583 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
589 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
592 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
594 e_comp_object_map_set(obj, map);
595 e_comp_object_map_enable_set(obj, EINA_TRUE);
602 evas_object_map_enable_set(obj, EINA_FALSE);
605 /////////////////////////////////////
607 static inline Eina_Bool
608 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
610 if (num > 1) return EINA_TRUE;
611 if ((rects[0].x == 0) && (rects[0].y == 0) &&
612 ((int)rects[0].w == w) && ((int)rects[0].h == h))
617 /////////////////////////////////////
619 /* add a client to the layer-client list */
620 #ifdef REFACTOR_DESK_AREA
623 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
625 g_rec_mutex_lock(&e_comp->ec_list_mutex);
628 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));
630 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));
631 if ((!above) && (!below))
634 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
635 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
636 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
638 e_comp->layers[cw->layer].clients_count++;
640 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
644 _e_comp_object_layers_remove(E_Comp_Object *cw)
646 g_rec_mutex_lock(&e_comp->ec_list_mutex);
648 if (cw->ec && e_comp->layers[cw->layer].clients)
650 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
651 e_comp->layers[cw->layer].clients_count--;
654 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
658 /////////////////////////////////////
660 _e_comp_object_alpha_set(E_Comp_Object *cw)
662 Eina_Bool alpha = cw->ec->argb;
664 if ((cw->external_content) &&
665 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
670 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
671 if (cw->user_alpha_set) alpha = cw->user_alpha;
673 evas_object_image_alpha_set(cw->obj, alpha);
677 _e_comp_object_shadow(E_Comp_Object *cw)
679 if (e_client_util_shadow_state_get(cw->ec))
680 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
682 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
683 if (cw->frame_object)
684 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
685 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
688 /* convert from the surface coordinates to the buffer coordinates */
690 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
692 E_Comp_Wl_Buffer_Viewport *vp;
693 E_Comp_Wl_Client_Data *cdata;
697 cdata = e_client_cdata_get(ec);
699 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
706 vp = &cdata->scaler.buffer_viewport;
707 transform = e_comp_wl_output_buffer_transform_get(ec);
709 e_pixmap_size_get(ec->pixmap, &bw, &bh);
711 /* for subsurface, it should be swap 90 and 270 */
712 if (e_comp_wl_subsurface_check(ec))
715 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
716 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
717 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
718 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
724 case WL_OUTPUT_TRANSFORM_NORMAL:
725 default: tx = sx, ty = sy; break;
726 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
727 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
728 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
729 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
730 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
731 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
732 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
735 tx *= vp->buffer.scale;
736 ty *= vp->buffer.scale;
743 _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)
751 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
752 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
759 if (dw) *dw = MAX(x1, x2) - mx;
760 if (dh) *dh = MAX(y1, y2) - my;
764 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
765 int *dx, int *dy, int *dw, int *dh)
767 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
768 E_Util_Transform_Rect_Vertex sv, dv;
772 e_pixmap_size_get(ec->pixmap, &bw, &bh);
774 sv = e_util_transform_rect_to_vertices(&rect);
776 for (i = 0; i < 4; i++)
778 double x = 0.0, y = 0.0;
780 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
782 /* if evas decide coordinate is outside of map, it returns (0, 0)
783 in this case, full damage is added.
785 if ((i != 0) && (x == 0.0) && (y == 0.0))
788 dv.vertices[i].vertex[0] = x;
789 dv.vertices[i].vertex[1] = y;
790 dv.vertices[i].vertex[2] = 1.0;
791 dv.vertices[i].vertex[3] = 1.0;
794 rect = e_util_transform_vertices_to_rect(&dv);
796 if (dx) *dx = rect.x;
797 if (dy) *dy = rect.y;
798 if (dw) *dw = rect.w;
799 if (dh) *dh = rect.h;
813 _e_comp_object_map_damage_transform_get(E_Client *ec)
820 if (!e_client_transform_core_enable_get(ec))
823 m = e_client_map_get(ec);
827 e_pixmap_size_get(ec->pixmap, &bw, &bh);
828 if ((bw == 0) || (bh == 0))
841 e_map_point_coord_set(m2, 0, 0, 0, 0);
842 e_map_point_coord_set(m2, 1, bw, 0, 0);
843 e_map_point_coord_set(m2, 2, bw, bh, 0);
844 e_map_point_coord_set(m2, 3, 0, bh, 0);
846 for (i = 0; i < 4; i++)
850 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
851 e_map_point_image_uv_set(m2, i, map_x, map_y);
858 /////////////////////////////////////
860 /* handle evas mouse-in events on client object */
862 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
864 Evas_Event_Mouse_In *ev = event_info;
865 E_Comp_Object *cw = data;
867 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
870 /* handle evas mouse-out events on client object */
872 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
874 Evas_Event_Mouse_Out *ev = event_info;
875 E_Comp_Object *cw = data;
877 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
880 /* handle evas mouse wheel events on client object */
882 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
884 Evas_Event_Mouse_Wheel *ev = event_info;
885 E_Comp_Object *cw = data;
886 E_Binding_Event_Wheel ev2;
889 if (e_client_action_get()) return;
890 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
891 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
894 /* handle evas mouse down events on client object */
896 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
898 Evas_Event_Mouse_Down *ev = event_info;
899 E_Comp_Object *cw = data;
900 E_Binding_Event_Mouse_Button ev2;
903 if (e_client_action_get()) return;
904 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
905 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
908 /* handle evas mouse up events on client object */
910 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
912 Evas_Event_Mouse_Up *ev = event_info;
913 E_Comp_Object *cw = data;
914 E_Binding_Event_Mouse_Button ev2;
917 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
918 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
919 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
922 /* handle evas mouse movement events on client object */
924 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
926 Evas_Event_Mouse_Move *ev = event_info;
927 E_Comp_Object *cw = data;
930 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
931 e_client_mouse_move(cw->ec, &ev->cur.output);
933 /////////////////////////////////////
935 /* helper function for checking compositor themes based on user-defined matches */
937 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
939 if (((m->title) && (!ec->netwm.name)) ||
940 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
942 #if defined(__cplusplus) || defined(c_plusplus)
943 if (((m->clas) && (!ec->icccm.cpp_class)) ||
944 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
947 if (((m->clas) && (!ec->icccm.class)) ||
948 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
952 if (((m->role) && (!ec->icccm.window_role)) ||
953 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
959 if ((int)ec->netwm.type != m->primary_type)
962 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
965 if (m->borderless != 0)
969 if (e_client_util_borderless(ec))
971 if (!(((m->borderless == -1) && (!borderless)) ||
972 ((m->borderless == 1) && (borderless))))
979 if (((ec->icccm.transient_for != 0) ||
982 if (!(((m->dialog == -1) && (!dialog)) ||
983 ((m->dialog == 1) && (dialog))))
986 if (m->accepts_focus != 0)
988 int accepts_focus = 0;
990 if (ec->icccm.accepts_focus)
992 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
993 ((m->accepts_focus == 1) && (accepts_focus))))
1002 if (!(((m->vkbd == -1) && (!vkbd)) ||
1003 ((m->vkbd == 1) && (vkbd))))
1008 if (!(((m->argb == -1) && (!ec->argb)) ||
1009 ((m->argb == 1) && (ec->argb))))
1012 if (m->fullscreen != 0)
1014 int fullscreen = ec->fullscreen;
1016 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1017 ((m->fullscreen == 1) && (fullscreen))))
1022 if (!(m->modal == -1))
1028 /* function for setting up a client's compositor frame theme (cw->shobj) */
1030 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1034 Eina_List *list = NULL, *l;
1035 E_Input_Rect_Data *input_rect_data;
1036 E_Input_Rect_Smart_Data *input_rect_sd;
1038 Eina_Stringshare *reshadow_group = NULL;
1039 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1040 Eina_Stringshare *name, *title;
1041 E_Comp_Config *conf = e_comp_config_get();
1043 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1044 /* match correct client type */
1045 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1046 name = cw->ec->icccm.name;
1047 title = cw->ec->icccm.title;
1048 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1049 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1051 /* skipping here is mostly a hack for systray because I hate it */
1054 EINA_LIST_FOREACH(list, l, m)
1056 if (((m->name) && (!name)) ||
1057 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1059 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1062 no_shadow = m->no_shadow;
1063 if (m->shadow_style)
1065 /* fast effects are just themes with "/fast" appended and shorter effect times */
1068 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1069 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1071 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1073 /* default to non-fast style if fast not available */
1076 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1077 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1079 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1081 if (ok && m->visibility_effect)
1082 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1089 if (skip || (cw->ec->e.state.video))
1091 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1093 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1096 if (conf->shadow_style)
1100 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1101 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1103 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1107 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1108 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1110 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1117 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1119 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1123 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1125 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1130 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1135 if (cw->ec->override)
1137 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1138 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1140 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1141 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1147 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1148 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1151 _e_comp_object_shadow(cw);
1154 if (focus || cw->ec->focused || cw->ec->override)
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1161 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1162 /* visibility must always be enabled for re_manage clients to prevent
1163 * pop-in animations every time the user sees a persistent client again;
1164 * applying visibility for iconic clients prevents the client from getting
1167 if (cw->visible || cw->ec->re_manage)
1168 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1170 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1172 /* breaks animation counter */
1173 if (cw->frame_object)
1175 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1176 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1177 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1178 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1184 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1188 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1191 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1193 if (input_rect_data->obj)
1195 pass_event_flag = EINA_TRUE;
1201 if (cw->indicator.obj)
1203 Evas_Object *indicator;
1204 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1205 if (indicator != cw->indicator.obj)
1207 edje_object_part_unswallow(cw->shobj, indicator);
1208 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1209 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1213 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1214 evas_object_pass_events_set(cw->obj, pass_event_flag);
1219 /////////////////////////////////////////////
1222 _e_comp_object_animating_begin(E_Comp_Object *cw)
1225 if (cw->animating == 1)
1227 e_comp->animating++;
1229 e_object_ref(E_OBJECT(cw->ec));
1234 _e_comp_object_animating_end(E_Comp_Object *cw)
1243 if (cw->ec->launching)
1245 if (!cw->ec->extra_animating)
1247 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1248 cw->ec->launching = EINA_FALSE;
1249 if (cw->ec->first_mapped)
1251 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1252 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1255 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1259 e_comp->animating--;
1260 cw->showing = cw->hiding = 0;
1262 if (e_comp->animating == 0)
1263 e_comp_visibility_calculation_set(EINA_TRUE);
1264 /* remove ref from animation start, account for possibility of deletion from unref */
1265 return !!e_object_unref(E_OBJECT(cw->ec));
1271 /* handle the end of a compositor animation */
1273 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1275 E_Comp_Object *cw = data;
1277 /* visible clients which have never been sized are a bug */
1278 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1279 CRI("ACK! ec:%p", cw->ec);
1280 if (!_e_comp_object_animating_end(cw)) return;
1281 if (cw->animating) return;
1282 /* hide only after animation finishes to guarantee a full run of the animation */
1283 if (!cw->defer_hide) return;
1284 if ((!strcmp(emission, "e,action,hide,done")) ||
1285 (!strcmp(emission, "e,action,done")) ||
1286 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1288 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1289 evas_object_hide(cw->smart_obj);
1293 /* run a visibility compositor effect if available, return false if object is dead */
1295 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1301 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1302 if (!cw->effect_running)
1303 _e_comp_object_animating_begin(cw);
1304 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1305 return _e_comp_object_animating_end(cw);
1306 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1307 return _e_comp_object_animating_end(cw);
1309 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1312 zone = e_comp_zone_find_by_ec(cw->ec);
1314 zw = zone->w, zh = zone->h;
1319 zone = e_comp_object_util_zone_get(cw->smart_obj);
1320 if (!zone) zone = e_zone_current_get();
1327 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1328 cw->w, cw->h, zw, zh, x, y}, 8);
1329 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1330 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1333 /////////////////////////////////////////////
1335 /* create necessary objects for clients that e manages */
1337 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1339 if (cw->set_mouse_callbacks) return;
1340 if (!cw->smart_obj) return;
1342 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1343 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1344 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1345 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1346 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1349 cw->set_mouse_callbacks = EINA_TRUE;
1353 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1355 if (!cw->set_mouse_callbacks) return;
1356 if (!cw->smart_obj) return;
1358 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1359 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1360 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1361 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1362 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1365 cw->set_mouse_callbacks = EINA_FALSE;
1369 _e_comp_object_setup(E_Comp_Object *cw)
1371 cw->clip = evas_object_rectangle_add(e_comp->evas);
1372 evas_object_move(cw->clip, -9999, -9999);
1373 evas_object_resize(cw->clip, 999999, 999999);
1374 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1375 cw->effect_obj = edje_object_add(e_comp->evas);
1376 evas_object_move(cw->effect_obj, cw->x, cw->y);
1377 evas_object_clip_set(cw->effect_obj, cw->clip);
1378 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1379 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1380 cw->shobj = edje_object_add(e_comp->evas);
1381 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1382 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1383 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1385 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1386 if (cw->ec->override)
1388 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1389 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1390 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1392 else if (!cw->ec->input_only)
1394 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1395 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1396 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1398 cw->real_hid = !cw->ec->input_only;
1399 if (!cw->ec->input_only)
1401 e_util_size_debug_set(cw->effect_obj, 1);
1402 _e_comp_object_mouse_event_callback_set(cw);
1405 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1406 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1407 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1408 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1409 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1410 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1412 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1415 /////////////////////////////////////////////
1417 /* for fast path evas rendering; only called during render */
1419 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1421 E_Comp_Object *cw = data;
1422 E_Client *ec = cw->ec;
1424 int bx, by, bxx, byy;
1426 if (e_object_is_del(E_OBJECT(ec))) return;
1427 if (cw->external_content) return;
1428 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1429 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1432 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1433 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1435 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1437 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1438 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1442 bx = by = bxx = byy = 0;
1443 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1446 Edje_Message_Int_Set *msg;
1447 Edje_Message_Int msg2;
1448 Eina_Bool id = (bx || by || bxx || byy);
1450 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1456 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1458 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1462 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1463 e_comp_client_post_update_add(cw->ec);
1465 else if (e_comp_object_render(ec->frame))
1467 /* apply shape mask if necessary */
1468 if ((!cw->native) && (ec->shaped))
1469 e_comp_object_shape_apply(ec->frame);
1471 /* shaped clients get precise mouse events to handle transparent pixels */
1472 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1474 /* queue another render if client is still dirty; cannot refresh here. */
1475 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1476 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1478 if (cw->render_trace)
1480 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1486 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1488 E_Comp_Object *cw = data;
1489 E_Client *ec = cw->ec;
1491 if (e_object_is_del(E_OBJECT(ec))) return;
1492 if (cw->external_content) return;
1493 if (!e_comp->hwc) return;
1495 e_comp_client_render_list_add(cw->ec);
1497 if (!ec->hwc_window) return;
1499 e_hwc_windows_rendered_window_add(ec->hwc_window);
1502 /////////////////////////////////////////////
1505 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1507 E_Comp_Object *cw = data;
1510 if (cw->render_update_lock.lock)
1512 cw->render_update_lock.pending_move_x = x;
1513 cw->render_update_lock.pending_move_y = y;
1514 cw->render_update_lock.pending_move_set = EINA_TRUE;
1518 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1519 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1520 (cw->external_content))
1522 /* delay to move until the external content is unset */
1523 cw->ec->changes.pos = 1;
1528 if (cw->ec->move_after_resize)
1530 if ((x != cw->ec->x) || (y != cw->ec->y))
1532 if (!cw->ec->is_cursor)
1533 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1534 e_client_pos_set(cw->ec, x, y);
1535 cw->ec->changes.pos = 1;
1541 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1542 (cw->ec->manage_resize.resize_obj))
1544 e_client_pos_set(cw->ec, x, y);
1545 cw->ec->client.x = x + cw->client_inset.l;
1546 cw->ec->client.y = y + cw->client_inset.t;
1547 e_policy_visibility_client_defer_move(cw->ec);
1551 /* if frame_object does not exist, client_inset indicates CSD.
1552 * this means that ec->client matches cw->x/y, the opposite
1555 fx = (!cw->frame_object) * cw->client_inset.l;
1556 fy = (!cw->frame_object) * cw->client_inset.t;
1557 if ((cw->x == x + fx) && (cw->y == y + fy))
1559 if ((cw->ec->x != x) || (cw->ec->y != y))
1561 /* handle case where client tries to move to position and back very quickly */
1562 e_client_pos_set(cw->ec, x, y);
1563 cw->ec->client.x = x + cw->client_inset.l;
1564 cw->ec->client.y = y + cw->client_inset.t;
1568 if (!cw->ec->maximize_override)
1570 /* prevent moving in some directions while directionally maximized */
1571 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1573 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1576 ix = x + cw->client_inset.l;
1577 iy = y + cw->client_inset.t;
1578 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1579 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1580 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1582 /* prevent moving at all if move isn't allowed in current maximize state */
1583 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1584 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1587 zone = e_comp_zone_find_by_ec(cw->ec);
1590 cw->ec->changes.need_unmaximize = 1;
1591 cw->ec->saved.x = ix - zone->x;
1592 cw->ec->saved.y = iy - zone->y;
1593 cw->ec->saved.w = cw->ec->client.w;
1594 cw->ec->saved.h = cw->ec->client.h;
1598 /* only update during resize if triggered by resize */
1599 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1600 /* delay to move while surface waits paired commit serial*/
1601 if (e_client_pending_geometry_has(cw->ec))
1603 /* do nothing while waiting paired commit serial*/
1607 e_client_pos_set(cw->ec, x, y);
1608 if (cw->ec->new_client)
1610 /* don't actually do anything until first client idler loop */
1611 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1612 cw->ec->changes.pos = 1;
1617 /* only update xy position of client to avoid invalid
1618 * first damage region if it is not a new_client. */
1619 cw->ec->client.x = ix;
1620 cw->ec->client.y = iy;
1623 if (!cw->frame_object)
1625 evas_object_move(obj, x, y);
1630 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1632 E_Comp_Object *cw = data;
1633 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1636 if (cw->render_update_lock.lock)
1638 cw->render_update_lock.pending_resize_w = w;
1639 cw->render_update_lock.pending_resize_h = h;
1640 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1644 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1646 e_client_size_set(cw->ec, w, h);
1647 evas_object_resize(obj, w, h);
1651 /* if frame_object does not exist, client_inset indicates CSD.
1652 * this means that ec->client matches cw->w/h, the opposite
1655 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1656 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1657 if ((cw->w == w + fw) && (cw->h == h + fh))
1659 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1660 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1661 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1663 /* handle case where client tries to resize itself and back very quickly */
1664 e_client_size_set(cw->ec, w, 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;
1667 evas_object_smart_callback_call(obj, "client_resize", NULL);
1671 /* guarantee that fullscreen is fullscreen */
1672 zone = e_comp_zone_find_by_ec(cw->ec);
1674 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1676 if (!e_client_transform_core_enable_get(cw->ec))
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;
1687 Eina_Bool reject = EINA_FALSE;
1688 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1690 if (cw->ec->client.h != ih)
1692 cw->ec->saved.h = ih;
1693 cw->ec->saved.y = cw->ec->client.y - zone->y;
1694 reject = cw->ec->changes.need_unmaximize = 1;
1697 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1699 if (cw->ec->client.w != iw)
1701 cw->ec->saved.w = iw;
1702 cw->ec->saved.x = cw->ec->client.x - zone->x;
1703 reject = cw->ec->changes.need_unmaximize = 1;
1712 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1714 /* do nothing until client idler loops */
1715 if ((cw->ec->w != w) || (cw->ec->h != h))
1717 e_client_size_set(cw->ec, w, h);
1718 cw->ec->changes.size = 1;
1723 if (e_client_pending_geometry_has(cw->ec))
1725 /* do nothing while waiting paired commit serial*/
1729 e_client_size_set(cw->ec, w, h);
1731 cw->ec->client.w = iw;
1732 cw->ec->client.h = ih;
1733 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1735 /* The size of non-compositing window can be changed, so there is a
1736 * need to check that cw is H/W composited if cw is not redirected.
1737 * And of course we have to change size of evas object of H/W composited cw,
1738 * otherwise cw can't receive input events even if it is shown on the screen.
1740 Eina_Bool redirected = cw->redirected;
1742 redirected = e_comp_is_on_overlay(cw->ec);
1744 if ((!cw->ec->input_only) && (redirected) &&
1745 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1746 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1747 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1748 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1751 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1752 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1754 prev_w = cw->w, prev_h = cw->h;
1755 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1756 /* check shading and clamp to pixmap size for regular clients */
1757 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1758 (((w - fw != pw) || (h - fh != ph))))
1760 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1761 evas_object_smart_callback_call(obj, "client_resize", NULL);
1763 if (cw->frame_object || cw->ec->input_only)
1764 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1767 if ((cw->w == w) && (cw->h == h))
1769 /* going to be a noop resize which won't trigger smart resize */
1770 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1771 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1773 evas_object_resize(obj, w, h);
1777 evas_object_smart_callback_call(obj, "client_resize", NULL);
1780 if ((!cw->frame_object) && (!cw->ec->input_only))
1782 /* "just do it" for overrides */
1783 evas_object_resize(obj, w, h);
1785 if (!cw->ec->override)
1787 /* shape probably changed for non-overrides */
1792 /* this fixes positioning jiggles when using a resize mode
1793 * which also changes the client's position
1796 if (cw->frame_object)
1797 x = cw->x, y = cw->y;
1799 x = cw->ec->x, y = cw->ec->y;
1800 switch (cw->ec->resize_mode)
1802 case E_POINTER_RESIZE_BL:
1803 case E_POINTER_RESIZE_L:
1804 evas_object_move(obj, x + prev_w - cw->w, y);
1806 case E_POINTER_RESIZE_TL:
1807 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1809 case E_POINTER_RESIZE_T:
1810 case E_POINTER_RESIZE_TR:
1811 evas_object_move(obj, x, y + prev_h - cw->h);
1820 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1822 #ifdef REFACTOR_DESK_AREA
1823 E_Comp_Object *cw = data;
1824 E_Comp_Object_Data_Set_Layer layer_set_data;
1826 layer_set_data.cw = cw;
1827 layer_set_data.layer = layer;
1829 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1833 e_comp_render_queue();
1834 _e_comp_object_transform_obj_stack_update(obj);
1838 E_Comp_Object *cw = data;
1839 E_Comp_Wl_Client_Data *child_cdata;
1840 unsigned int l = e_comp_canvas_layer_map(layer);
1843 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1845 /* doing a compositor effect, follow directions */
1846 _e_comp_object_layer_set(obj, layer);
1847 if (layer == cw->ec->layer) //trying to put layer back
1851 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1852 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1853 if (cw->layer != l) goto layer_set;
1857 e_comp_render_queue();
1859 ec = e_client_above_get(cw->ec);
1860 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1861 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1862 ec = e_client_above_get(ec);
1863 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1865 ec = e_client_below_get(cw->ec);
1866 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1867 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1868 ec = e_client_below_get(ec);
1869 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1871 evas_object_stack_above(obj, ec->frame);
1876 if (ec && (cw->ec->parent == ec))
1878 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1879 evas_object_stack_above(obj, ec->frame);
1881 evas_object_stack_below(obj, ec->frame);
1884 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1890 if (cw->layer == l) return;
1891 if (e_comp_canvas_client_layer_map(layer) == 9999)
1892 return; //invalid layer for clients not doing comp effects
1893 if (cw->ec->fullscreen)
1895 cw->ec->saved.layer = layer;
1898 oldraise = e_config->transient.raise;
1900 /* clamp to valid client layer */
1901 layer = e_comp_canvas_client_layer_map_nearest(layer);
1902 cw->ec->layer = layer;
1903 if (e_config->transient.layer)
1906 Eina_List *list = eina_list_clone(cw->ec->transients);
1908 /* We need to set raise to one, else the child wont
1909 * follow to the new layer. It should be like this,
1910 * even if the user usually doesn't want to raise
1913 e_config->transient.raise = 1;
1914 EINA_LIST_FREE(list, child)
1916 child_cdata = e_client_cdata_get(child);
1917 if (child_cdata && !child_cdata->mapped)
1919 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1922 e_client_layer_set(child, layer);
1926 e_config->transient.raise = oldraise;
1928 _e_comp_object_layers_remove(cw);
1929 cw->layer = e_comp_canvas_layer_map(layer);
1930 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1931 //if (cw->ec->new_client)
1932 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1933 _e_comp_object_layer_set(obj, layer);
1934 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1935 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1936 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1938 /* can't stack a client above its own layer marker */
1939 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1941 if (!cw->visible) return;
1942 e_comp_render_queue();
1943 _e_comp_object_transform_obj_stack_update(obj);
1947 #ifdef REFACTOR_DESK_AREA
1949 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1952 #ifdef REFACTOR_DESK_AREA
1954 _e_comp_object_raise(Evas_Object *obj)
1957 _e_comp_object_raise(Evas_Object *obj)
1960 evas_object_raise(obj);
1962 if (evas_object_smart_smart_get(obj))
1964 E_Client *ec = e_comp_object_client_get(obj);
1966 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1970 #ifdef REFACTOR_DESK_AREA
1972 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1975 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1978 evas_object_lower(obj);
1980 if (evas_object_smart_smart_get(obj))
1982 E_Client *ec = e_comp_object_client_get(obj);
1985 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1986 #ifdef REFACTOR_DESK_AREA
1987 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1989 wl_signal_emit_mutable(&cw->events.lower, NULL);
1995 #ifdef REFACTOR_DESK_AREA
1997 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2000 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2003 evas_object_stack_above(obj, target);
2005 if (evas_object_smart_smart_get(obj))
2007 E_Client *ec = e_comp_object_client_get(obj);
2009 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2013 #ifdef REFACTOR_DESK_AREA
2015 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2018 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2021 evas_object_stack_below(obj, target);
2023 if (evas_object_smart_smart_get(obj))
2025 E_Client *ec = e_comp_object_client_get(obj);
2027 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2031 #ifdef REFACTOR_DESK_AREA
2033 e_comp_object_layer_set(Evas_Object *obj, short layer)
2036 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2039 evas_object_layer_set(obj, layer);
2041 if (evas_object_smart_smart_get(obj))
2043 E_Client *ec = e_comp_object_client_get(obj);
2045 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2049 #ifdef REFACTOR_DESK_AREA
2052 _e_comp_object_is_pending(E_Client *ec)
2056 if (!ec) return EINA_FALSE;
2058 topmost = e_comp_wl_topmost_parent_get(ec);
2060 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2064 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2066 E_Comp_Object *cw2 = NULL;
2069 Evas_Object *o = stack;
2070 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2072 /* We should consider topmost's layer_pending for subsurface */
2073 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2075 if (_e_comp_object_is_pending(cw->ec))
2076 e_comp_object_layer_update(cw->smart_obj,
2077 raising? stack : NULL,
2078 raising? NULL : stack);
2080 /* obey compositor effects! */
2081 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2082 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2083 stack_cb(cw->smart_obj, stack);
2084 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2085 evas_object_data_del(cw->smart_obj, "client_restack");
2089 cw2 = evas_object_data_get(o, "comp_obj");
2091 /* assume someone knew what they were doing during client init */
2092 if (cw->ec->new_client)
2093 layer = cw->ec->layer;
2094 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2095 layer = cw2->ec->layer;
2097 layer = evas_object_layer_get(stack);
2098 ecstack = e_client_below_get(cw->ec);
2099 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2101 evas_object_layer_set(cw->smart_obj, layer);
2102 /* we got our layer wrangled, return now! */
2103 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2106 /* check if we're stacking below another client */
2109 /* check for non-client layer object */
2110 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2112 /* find an existing client to use for layering
2113 * by walking up the object stack
2115 * this is guaranteed to be pretty quick since we'll either:
2116 * - run out of client layers
2117 * - find a stacking client
2119 o = evas_object_above_get(o);
2120 if ((!o) || (o == cw->smart_obj)) break;
2121 if (evas_object_layer_get(o) != layer)
2123 /* reached the top client layer somehow
2124 * use top client object
2126 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2129 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2130 * return here since the top client layer window
2135 ec = e_client_top_get();
2140 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2143 if (cw2 && cw->layer != cw2->layer)
2146 /* remove existing layers */
2147 _e_comp_object_layers_remove(cw);
2150 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2151 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2152 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2153 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2154 else //if no stacking objects found, either raise or lower
2155 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2158 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2160 /* find new object for stacking if cw2 is on state of layer_pending */
2161 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2163 E_Client *new_stack = NULL, *current_ec = NULL;
2164 current_ec = cw2->ec;
2167 while ((new_stack = e_client_below_get(current_ec)))
2169 current_ec = new_stack;
2170 if (new_stack == cw->ec) continue;
2171 if (new_stack->layer != cw2->ec->layer) break;
2172 if (!_e_comp_object_is_pending(new_stack)) break;
2174 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2175 stack = new_stack->frame;
2178 /* stack it above layer object */
2180 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2181 stack = e_comp->layers[below_layer].obj;
2186 while ((new_stack = e_client_above_get(current_ec)))
2188 current_ec = new_stack;
2189 if (new_stack == cw->ec) continue;
2190 if (new_stack->layer != cw2->ec->layer) break;
2191 if (!_e_comp_object_is_pending(new_stack)) break;
2193 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2194 stack = new_stack->frame;
2196 stack = e_comp->layers[cw2->layer].obj;
2200 /* set restack if stacking has changed */
2201 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2202 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2203 stack_cb(cw->smart_obj, stack);
2204 if (e_comp->layers[cw->layer].obj)
2205 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2207 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2209 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2210 evas_object_data_del(cw->smart_obj, "client_restack");
2211 if (!cw->visible) return;
2212 e_comp_render_queue();
2217 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2219 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2221 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2223 #ifdef REFACTOR_DESK_AREA
2224 E_Comp_Object *cw = data;
2225 E_Comp_Object_Data_Stack_Above stack_above_data;
2227 stack_above_data.cw = cw;
2228 stack_above_data.above_obj = above;
2230 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2232 if (evas_object_below_get(obj) == above)
2234 e_comp_object_layer_update(obj, above, NULL);
2238 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2240 _e_comp_object_transform_obj_stack_update(obj);
2241 _e_comp_object_transform_obj_stack_update(above);
2248 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2250 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2252 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2254 #ifdef REFACTOR_DESK_AREA
2255 E_Comp_Object *cw = data;
2256 E_Comp_Object_Data_Stack_Below stack_below_data;
2258 stack_below_data.cw = cw;
2259 stack_below_data.below_obj = below;
2261 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2264 e_comp_render_queue();
2266 if (evas_object_above_get(obj) == below)
2268 e_comp_object_layer_update(obj, NULL, below);
2272 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2274 if (evas_object_smart_smart_get(obj))
2275 _e_comp_object_transform_obj_stack_update(obj);
2276 if (evas_object_smart_smart_get(below))
2277 _e_comp_object_transform_obj_stack_update(below);
2284 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2286 E_Comp_Object *cw = data;
2288 #ifdef REFACTOR_DESK_AREA
2293 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2295 #ifdef REFACTOR_DESK_AREA
2296 wl_signal_emit_mutable(&cw->events.lower, cw);
2298 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2300 if (cw->ec->layer_pending)
2301 e_comp_object_layer_update(obj, NULL, obj);
2303 _e_comp_object_lower(cw, obj);
2306 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2307 o = evas_object_below_get(obj);
2308 _e_comp_object_layers_remove(cw);
2309 /* prepend to client list since this client should be the first item now */
2310 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2311 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2312 evas_object_data_set(obj, "client_restack", (void*)1);
2313 _e_comp_object_lower(cw, obj);
2314 evas_object_data_del(obj, "client_restack");
2315 if (!cw->visible) goto end;
2316 e_comp_render_queue();
2317 _e_comp_object_transform_obj_stack_update(obj);
2325 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2327 E_Comp_Object *cw = data;
2328 #ifdef REFACTOR_DESK_AREA
2334 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2336 #ifdef REFACTOR_DESK_AREA
2337 wl_signal_emit_mutable(&cw->events.raise, cw);
2339 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2341 if (cw->ec->layer_pending)
2343 int obj_layer = evas_object_layer_get(obj);
2344 if (cw->ec->layer != obj_layer)
2345 e_comp_object_layer_update(obj, NULL, NULL);
2348 _e_comp_object_raise(obj);
2351 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2352 o = evas_object_above_get(obj);
2353 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2355 /* still stack below override below the layer marker */
2356 for (op = o = e_comp->layers[cw->layer].obj;
2357 o && o != e_comp->layers[cw->layer - 1].obj;
2358 op = o, o = evas_object_below_get(o))
2360 if (evas_object_smart_smart_get(o))
2364 ec = e_comp_object_client_get(o);
2365 if (ec && (!ec->override)) break;
2368 _e_comp_object_stack_below(obj, op);
2369 e_client_focus_defer_set(cw->ec);
2371 if (!cw->visible) goto end;
2372 e_comp_render_queue();
2373 _e_comp_object_transform_obj_stack_update(obj);
2381 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2383 E_Comp_Object *cw = data;
2385 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2386 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2388 ELOGF("COMP", "Hide. intercepted", cw->ec);
2393 if (cw->ec->launching == EINA_TRUE)
2395 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2396 cw->ec->launching = EINA_FALSE;
2401 /* hidden flag = just do it */
2402 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2403 evas_object_hide(obj);
2405 wl_signal_emit_mutable(&cw->events.hide, NULL);
2410 if (cw->ec->input_only)
2412 /* input_only = who cares */
2413 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2414 evas_object_hide(obj);
2416 wl_signal_emit_mutable(&cw->events.hide, NULL);
2420 /* already hidden or currently animating */
2421 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2423 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2427 /* don't try hiding during shutdown */
2428 cw->defer_hide |= stopping;
2429 if (!cw->defer_hide)
2431 if ((!cw->ec->iconic) && (!cw->ec->override))
2432 /* unset delete requested so the client doesn't break */
2433 cw->ec->delete_requested = 0;
2434 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2436 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2437 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2440 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2443 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2445 _e_comp_object_animating_begin(cw);
2446 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2448 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2449 cw->defer_hide = !!cw->animating;
2451 e_comp_object_effect_set(obj, NULL);
2454 if (cw->animating) return;
2455 /* if we have no animations running, go ahead and hide */
2457 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2458 evas_object_hide(obj);
2460 wl_signal_emit_mutable(&cw->events.hide, NULL);
2464 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2466 E_Client *ec = cw->ec;
2469 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2471 if (ec->show_pending.count > 0)
2473 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2474 ec->show_pending.running = EINA_TRUE;
2478 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2479 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2481 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2486 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,
2487 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2488 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2491 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2494 if (ec->iconic && cw->animating)
2496 /* triggered during iconify animation */
2497 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2500 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2503 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2504 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2506 evas_object_move(cw->smart_obj, ec->x, ec->y);
2507 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2508 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2510 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2511 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2514 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2515 evas_object_show(cw->smart_obj);
2518 e_client_focus_defer_set(ec);
2522 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2526 pw = ec->client.w, ph = ec->client.h;
2528 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2530 ec->changes.visible = !ec->hidden;
2533 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2537 cw->updates = eina_tiler_new(pw, ph);
2540 ec->changes.visible = !ec->hidden;
2543 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2548 eina_tiler_tile_size_set(cw->updates, 1, 1);
2551 /* ignore until client idler first run */
2552 ec->changes.visible = !ec->hidden;
2555 ELOGF("COMP", "show_helper. return. new_client", ec);
2562 evas_object_move(cw->smart_obj, ec->x, ec->y);
2563 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2564 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2565 evas_object_show(cw->smart_obj);
2568 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2570 /* start_drag not received */
2571 ec->changes.visible = 1;
2574 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2577 /* re-set geometry */
2578 evas_object_move(cw->smart_obj, ec->x, ec->y);
2579 /* force resize in case it hasn't happened yet, or just to update size */
2580 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2581 if ((cw->w < 1) || (cw->h < 1))
2583 /* if resize didn't go through, try again */
2584 ec->visible = ec->changes.visible = 1;
2586 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2589 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2590 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2591 e_pixmap_clear(ec->pixmap);
2593 if (cw->real_hid && w && h)
2596 /* force comp theming in case it didn't happen already */
2597 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2598 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2599 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2602 /* only do the show if show is allowed */
2605 if (ec->internal) //internal clients render when they feel like it
2606 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2608 if (!e_client_is_iconified_by_client(ec)||
2609 e_policy_visibility_client_is_uniconic(ec))
2611 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2612 evas_object_show(cw->smart_obj);
2614 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2615 it is rendered in idle callback without native surface and
2616 compositor shows an empty frame if other objects aren't shown
2617 because job callback of e_comp called at the next loop.
2618 it causes a visual defect when windows are switched.
2622 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2623 e_comp_object_dirty(cw->smart_obj);
2624 e_comp_object_render(cw->smart_obj);
2629 wl_signal_emit_mutable(&cw->events.show, NULL);
2633 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2635 E_Comp_Object *cw = data;
2636 E_Client *ec = cw->ec;
2638 E_Input_Rect_Data *input_rect_data;
2639 E_Input_Rect_Smart_Data *input_rect_sd;
2642 if (ec->ignored) return;
2646 //INF("SHOW2 %p", ec);
2647 _e_comp_intercept_show_helper(cw);
2650 //INF("SHOW %p", ec);
2653 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2654 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2655 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2656 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2660 if ((!cw->obj) && (cw->external_content))
2662 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2666 _e_comp_object_setup(cw);
2669 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2670 cw->obj = evas_object_image_filled_add(e_comp->evas);
2671 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2672 e_util_size_debug_set(cw->obj, 1);
2673 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2674 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2675 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2676 evas_object_name_set(cw->obj, "cw->obj");
2677 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2679 _e_comp_object_alpha_set(cw);
2682 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2685 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2686 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2689 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2692 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2694 if (input_rect_data->obj)
2696 evas_object_geometry_set(input_rect_data->obj,
2697 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2698 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2699 input_rect_data->rect.w, input_rect_data->rect.h);
2706 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2708 _e_comp_intercept_show_helper(cw);
2712 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2714 E_Comp_Object *cw = data;
2718 /* note: this is here as it seems there are enough apps that do not even
2719 * expect us to emulate a look of focus but not actually set x input
2720 * focus as we do - so simply abort any focus set on such windows */
2721 /* be strict about accepting focus hint */
2722 /* be strict about accepting focus hint */
2723 if ((!ec->icccm.accepts_focus) &&
2724 (!ec->icccm.take_focus))
2728 if (e_client_focused_get() == ec)
2729 e_client_focused_set(NULL);
2731 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2732 evas_object_focus_set(obj, focus);
2736 if (focus && ec->lock_focus_out) return;
2737 if (e_object_is_del(E_OBJECT(ec)) && focus)
2738 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2740 /* filter focus setting based on current state */
2745 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2746 evas_object_focus_set(obj, focus);
2749 if ((ec->iconic) && (!ec->deskshow))
2751 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2753 /* don't focus an iconified window. that's silly! */
2754 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2755 e_client_uniconify(ec);
2756 e_client_focus_latest_set(ec);
2770 /* not yet visible, wait till the next time... */
2771 ec->want_focus = !ec->hidden;
2776 e_client_focused_set(ec);
2780 if (e_client_focused_get() == ec)
2781 e_client_focused_set(NULL);
2785 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2787 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2789 evas_object_focus_set(obj, focus);
2793 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2795 E_Comp_Object *cw = data;
2797 if (cw->transparent.set)
2799 cw->transparent.user_r = r;
2800 cw->transparent.user_g = g;
2801 cw->transparent.user_b = b;
2802 cw->transparent.user_a = a;
2804 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2806 cw->transparent.user_r,
2807 cw->transparent.user_g,
2808 cw->transparent.user_b,
2809 cw->transparent.user_a);
2813 evas_object_color_set(obj, r, g, b, a);
2816 ////////////////////////////////////////////////////
2819 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2821 int w, h, ox, oy, ow, oh;
2823 Eina_Bool pass_event_flag = EINA_FALSE;
2824 E_Input_Rect_Data *input_rect_data;
2825 E_Input_Rect_Smart_Data *input_rect_sd;
2827 if (cw->frame_object)
2829 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2830 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2831 /* set a fixed size, force edje calc, check size difference */
2832 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2833 edje_object_message_signal_process(cw->frame_object);
2834 edje_object_calc_force(cw->frame_object);
2835 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2836 cw->client_inset.l = ox;
2837 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2838 cw->client_inset.t = oy;
2839 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2840 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2841 evas_object_resize(cw->frame_object, w, h);
2845 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2848 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2850 if (input_rect_data->obj)
2852 pass_event_flag = EINA_TRUE;
2858 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2859 evas_object_pass_events_set(cw->obj, pass_event_flag);
2863 cw->client_inset.l = 0;
2864 cw->client_inset.r = 0;
2865 cw->client_inset.t = 0;
2866 cw->client_inset.b = 0;
2868 cw->client_inset.calc = !!cw->frame_object;
2872 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2874 E_Comp_Object *cw = data;
2878 /* - get current size
2880 * - readjust for new frame size
2883 w = cw->ec->w, h = cw->ec->h;
2884 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2886 _e_comp_object_frame_recalc(cw);
2888 if (!cw->ec->fullscreen)
2889 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2891 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2892 if (cw->ec->fullscreen)
2894 zone = e_comp_zone_find_by_ec(cw->ec);
2896 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2898 else if (cw->ec->new_client)
2900 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2901 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2902 evas_object_resize(cw->ec->frame, w, h);
2904 else if ((w != cw->ec->w) || (h != cw->ec->h))
2905 evas_object_resize(cw->ec->frame, w, h);
2909 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2911 E_Comp_Object *cw = data;
2913 _e_comp_object_shadow_setup(cw);
2914 if (cw->frame_object)
2916 _e_comp_object_shadow(cw);
2917 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2918 _e_comp_object_frame_recalc(cw);
2919 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2924 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2926 E_Comp_Object *cw = data;
2928 if (_e_comp_object_shadow_setup(cw))
2929 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2930 if (cw->frame_object)
2932 _e_comp_object_shadow(cw);
2933 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2934 _e_comp_object_frame_recalc(cw);
2935 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2940 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2942 E_Comp_Object *cw = data;
2944 if (cw->frame_object)
2946 _e_comp_object_shadow(cw);
2947 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2948 _e_comp_object_frame_recalc(cw);
2949 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2954 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2956 E_Comp_Object *cw = data;
2958 if (_e_comp_object_shadow_setup(cw))
2961 cw->ec->changes.size = 1;
2963 if (cw->frame_object)
2965 _e_comp_object_shadow(cw);
2966 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2967 _e_comp_object_frame_recalc(cw);
2968 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2973 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2975 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2979 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2981 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2985 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2987 E_Comp_Object *cw = data;
2989 if (!cw->ec) return; //NYI
2990 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2994 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2996 E_Comp_Object *cw = data;
2998 if (!cw->ec) return; //NYI
2999 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3003 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3005 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3009 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3011 E_Comp_Object *cw = data;
3013 if (!e_object_is_del(E_OBJECT(cw->ec)))
3014 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3018 _e_comp_input_obj_smart_add(Evas_Object *obj)
3020 E_Input_Rect_Smart_Data *input_rect_sd;
3021 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3023 if (!input_rect_sd) return;
3024 evas_object_smart_data_set(obj, input_rect_sd);
3028 _e_comp_input_obj_smart_del(Evas_Object *obj)
3030 E_Input_Rect_Smart_Data *input_rect_sd;
3031 E_Input_Rect_Data *input_rect_data;
3033 input_rect_sd = evas_object_smart_data_get(obj);
3034 if (!input_rect_sd) return;
3036 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3038 if (input_rect_data->obj)
3040 evas_object_smart_member_del(input_rect_data->obj);
3041 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3043 E_FREE(input_rect_data);
3045 E_FREE(input_rect_sd);
3049 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3051 E_Input_Rect_Smart_Data *input_rect_sd;
3052 E_Input_Rect_Data *input_rect_data;
3056 input_rect_sd = evas_object_smart_data_get(obj);
3057 if (!input_rect_sd) return;
3059 cw = input_rect_sd->cw;
3060 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3062 if (input_rect_data->obj)
3064 evas_object_geometry_set(input_rect_data->obj,
3065 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3066 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3067 input_rect_data->rect.w, input_rect_data->rect.h);
3073 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3075 E_Input_Rect_Smart_Data *input_rect_sd;
3076 E_Input_Rect_Data *input_rect_data;
3080 input_rect_sd = evas_object_smart_data_get(obj);
3081 if (!input_rect_sd) return;
3083 cw = input_rect_sd->cw;
3084 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3086 if (input_rect_data->obj)
3088 evas_object_geometry_set(input_rect_data->obj,
3089 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3090 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3091 input_rect_data->rect.w, input_rect_data->rect.h);
3097 _e_comp_input_obj_smart_show(Evas_Object *obj)
3099 E_Input_Rect_Smart_Data *input_rect_sd;
3100 E_Input_Rect_Data *input_rect_data;
3103 input_rect_sd = evas_object_smart_data_get(obj);
3104 if (!input_rect_sd) return;
3106 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3108 if (input_rect_data->obj)
3110 evas_object_show(input_rect_data->obj);
3116 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3118 E_Input_Rect_Smart_Data *input_rect_sd;
3119 E_Input_Rect_Data *input_rect_data;
3122 input_rect_sd = evas_object_smart_data_get(obj);
3123 if (!input_rect_sd) return;
3125 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3127 if (input_rect_data->obj)
3129 evas_object_hide(input_rect_data->obj);
3135 _e_comp_input_obj_smart_init(void)
3137 if (_e_comp_input_obj_smart) return;
3139 static const Evas_Smart_Class sc =
3141 INPUT_OBJ_SMART_NAME,
3142 EVAS_SMART_CLASS_VERSION,
3143 _e_comp_input_obj_smart_add,
3144 _e_comp_input_obj_smart_del,
3145 _e_comp_input_obj_smart_move,
3146 _e_comp_input_obj_smart_resize,
3147 _e_comp_input_obj_smart_show,
3148 _e_comp_input_obj_smart_hide,
3161 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3167 _e_comp_smart_add(Evas_Object *obj)
3171 cw = E_NEW(E_Comp_Object, 1);
3172 EINA_SAFETY_ON_NULL_RETURN(cw);
3174 wl_signal_init(&cw->events.lower);
3175 #ifdef REFACTOR_DESK_AREA
3176 wl_signal_init(&cw->events.lower_done);
3177 wl_signal_init(&cw->events.raise);
3179 wl_signal_init(&cw->events.show);
3180 wl_signal_init(&cw->events.hide);
3181 #ifdef REFACTOR_DESK_AREA
3182 wl_signal_init(&cw->events.set_layer);
3183 wl_signal_init(&cw->events.stack_above);
3184 wl_signal_init(&cw->events.stack_below);
3187 cw->smart_obj = obj;
3188 cw->x = cw->y = cw->w = cw->h = -1;
3189 evas_object_smart_data_set(obj, cw);
3190 cw->opacity = 255.0;
3191 cw->external_content = 0;
3192 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3193 cw->transform_bg_color.r = 0;
3194 cw->transform_bg_color.g = 0;
3195 cw->transform_bg_color.b = 0;
3196 cw->transform_bg_color.a = 255;
3197 evas_object_data_set(obj, "comp_obj", cw);
3198 evas_object_move(obj, -1, -1);
3199 /* intercept ALL the callbacks! */
3200 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3201 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3202 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3203 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3204 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3205 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3206 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3207 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3208 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3209 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3210 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3212 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3213 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3214 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3215 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3217 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3218 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3220 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3221 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3223 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3225 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3226 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3230 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3233 evas_object_color_set(cw->clip, r, g, b, a);
3234 evas_object_smart_callback_call(obj, "color_set", NULL);
3239 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3242 evas_object_clip_set(cw->clip, clip);
3246 _e_comp_smart_clip_unset(Evas_Object *obj)
3249 evas_object_clip_unset(cw->clip);
3253 _e_comp_smart_hide(Evas_Object *obj)
3255 TRACE_DS_BEGIN(COMP:SMART HIDE);
3260 evas_object_hide(cw->clip);
3261 if (cw->input_obj) evas_object_hide(cw->input_obj);
3262 evas_object_hide(cw->effect_obj);
3263 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3264 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3265 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3272 /* unset native surface if current displaying buffer was destroied */
3273 if (!cw->buffer_destroy_listener.notify)
3275 Evas_Native_Surface *ns;
3276 ns = evas_object_image_native_surface_get(cw->obj);
3277 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3278 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3281 if (!cw->ec->input_only)
3283 edje_object_freeze(cw->effect_obj);
3284 edje_object_freeze(cw->shobj);
3285 edje_object_play_set(cw->shobj, 0);
3286 if (cw->frame_object)
3287 edje_object_play_set(cw->frame_object, 0);
3290 e_comp_render_queue(); //force nocomp recheck
3296 _e_comp_smart_show(Evas_Object *obj)
3304 if ((cw->w < 0) || (cw->h < 0))
3305 CRI("ACK! ec:%p", cw->ec);
3307 TRACE_DS_BEGIN(COMP:SMART SHOW);
3309 e_comp_object_map_update(obj);
3311 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3312 evas_object_show(tmp->frame);
3314 evas_object_show(cw->clip);
3315 if (cw->input_obj) evas_object_show(cw->input_obj);
3316 if (!cw->ec->input_only)
3318 edje_object_thaw(cw->effect_obj);
3319 edje_object_thaw(cw->shobj);
3320 edje_object_play_set(cw->shobj, 1);
3321 if (cw->frame_object)
3322 edje_object_play_set(cw->frame_object, 1);
3324 evas_object_show(cw->effect_obj);
3325 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3326 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3327 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3328 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3329 e_comp_render_queue();
3330 if (cw->ec->input_only)
3335 if (cw->ec->iconic && (!cw->ec->new_client))
3337 if (e_client_is_iconified_by_client(cw->ec))
3339 ELOGF("COMP", "Set launching flag..", cw->ec);
3340 cw->ec->launching = EINA_TRUE;
3343 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3345 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3348 ELOGF("COMP", "Set launching flag..", cw->ec);
3349 cw->ec->launching = EINA_TRUE;
3351 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3352 _e_comp_object_animating_begin(cw);
3353 if (!_e_comp_object_effect_visibility_start(cw, 1))
3359 /* ensure some random effect doesn't lock the client offscreen */
3363 e_comp_object_effect_set(obj, NULL);
3366 _e_comp_object_dim_update(cw);
3372 _e_comp_smart_del(Evas_Object *obj)
3378 if (cw->buffer_destroy_listener.notify)
3380 wl_list_remove(&cw->buffer_destroy_listener.link);
3381 cw->buffer_destroy_listener.notify = NULL;
3384 if (cw->tbm_surface)
3386 tbm_surface_internal_unref(cw->tbm_surface);
3387 cw->tbm_surface = NULL;
3390 if (cw->render_update_lock.buffer_ref.buffer)
3392 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3393 cw->ec, cw->render_update_lock.lock);
3394 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3397 e_comp_object_render_update_del(cw->smart_obj);
3398 E_FREE_FUNC(cw->updates, eina_tiler_free);
3399 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3406 EINA_LIST_FREE(cw->obj_mirror, o)
3408 evas_object_image_data_set(o, NULL);
3409 evas_object_freeze_events_set(o, 1);
3410 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3414 #ifdef REFACTOR_DESK_AREA
3416 _e_comp_object_layers_remove(cw);
3418 l = evas_object_data_get(obj, "comp_object-to_del");
3419 E_FREE_LIST(l, evas_object_del);
3420 _e_comp_object_mouse_event_callback_unset(cw);
3421 evas_object_del(cw->clip);
3422 evas_object_del(cw->obj);
3423 evas_object_del(cw->shobj);
3424 evas_object_del(cw->effect_obj);
3425 evas_object_del(cw->frame_object);
3426 evas_object_del(cw->input_obj);
3427 evas_object_del(cw->mask.obj);
3428 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3429 evas_object_del(cw->transform_bg_obj);
3430 evas_object_del(cw->transform_tranp_obj);
3431 evas_object_del(cw->default_input_obj);
3432 eina_stringshare_del(cw->frame_theme);
3433 eina_stringshare_del(cw->frame_name);
3437 e_comp->animating--;
3439 e_object_unref(E_OBJECT(cw->ec));
3441 cw->ec->frame = NULL;
3446 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3450 cw->x = x, cw->y = y;
3451 evas_object_move(cw->effect_obj, x, y);
3452 evas_object_move(cw->default_input_obj, x, y);
3453 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3455 e_comp_object_map_update(obj);
3459 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3461 Eina_Bool first = EINA_FALSE;
3466 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3468 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3470 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3472 if (cw->w != w || cw->h != h)
3473 e_comp_object_map_update(obj);
3475 first = ((cw->w < 1) || (cw->h < 1));
3476 cw->w = w, cw->h = h;
3480 if (cw->frame_object)
3481 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3484 /* verify pixmap:object size */
3485 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3487 if ((ww != pw) || (hh != ph))
3488 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3490 evas_object_resize(cw->effect_obj, tw, th);
3491 evas_object_resize(cw->default_input_obj, w, h);
3493 evas_object_resize(cw->input_obj, w, h);
3495 evas_object_resize(cw->mask.obj, w, h);
3496 /* resize render update tiler */
3499 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3500 cw->updates_full = 0;
3501 if (cw->updates) eina_tiler_clear(cw->updates);
3505 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3506 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3514 e_comp_render_queue();
3520 _e_comp_smart_init(void)
3522 if (_e_comp_smart) return;
3524 static const Evas_Smart_Class sc =
3527 EVAS_SMART_CLASS_VERSION,
3531 _e_comp_smart_resize,
3534 _e_comp_smart_color_set,
3535 _e_comp_smart_clip_set,
3536 _e_comp_smart_clip_unset,
3546 _e_comp_smart = evas_smart_class_new(&sc);
3551 e_comp_object_init(void)
3553 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3554 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3555 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3556 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3560 e_comp_object_shutdown(void)
3566 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3568 API_ENTRY EINA_FALSE;
3569 return !!cw->force_visible;
3571 /////////////////////////////////////////////////////////
3574 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3577 Eina_Bool comp_object;
3579 comp_object = !!evas_object_data_get(obj, "comp_object");
3584 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3586 e_comp_render_queue();
3588 l = evas_object_data_get(obj, "comp_object-to_del");
3589 E_FREE_LIST(l, evas_object_del);
3593 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3595 if (e_comp_util_object_is_above_nocomp(obj) &&
3596 (!evas_object_data_get(obj, "comp_override")))
3598 evas_object_data_set(obj, "comp_override", (void*)1);
3599 e_comp_override_add();
3604 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3606 Eina_Bool ref = EINA_TRUE;
3607 if (evas_object_visible_get(obj))
3611 d = evas_object_data_del(obj, "comp_hiding");
3613 /* currently trying to hide */
3616 /* already visible */
3620 evas_object_show(obj);
3623 evas_object_ref(obj);
3624 evas_object_data_set(obj, "comp_ref", (void*)1);
3626 edje_object_signal_emit(obj, "e,state,visible", "e");
3627 evas_object_data_set(obj, "comp_showing", (void*)1);
3628 if (e_comp_util_object_is_above_nocomp(obj))
3630 evas_object_data_set(obj, "comp_override", (void*)1);
3631 e_comp_override_add();
3636 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3638 if (!evas_object_visible_get(obj)) return;
3639 /* already hiding */
3640 if (evas_object_data_get(obj, "comp_hiding")) return;
3641 if (!evas_object_data_del(obj, "comp_showing"))
3643 evas_object_ref(obj);
3644 evas_object_data_set(obj, "comp_ref", (void*)1);
3646 edje_object_signal_emit(obj, "e,state,hidden", "e");
3647 evas_object_data_set(obj, "comp_hiding", (void*)1);
3649 if (evas_object_data_del(obj, "comp_override"))
3650 e_comp_override_timed_pop();
3654 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3656 if (!e_util_strcmp(emission, "e,action,hide,done"))
3658 if (!evas_object_data_del(obj, "comp_hiding")) return;
3659 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3660 evas_object_hide(obj);
3661 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3664 evas_object_data_del(obj, "comp_showing");
3665 if (evas_object_data_del(obj, "comp_ref"))
3666 evas_object_unref(obj);
3670 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3676 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3680 E_API E_Comp_Object_Hook *
3681 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3683 E_Comp_Object_Hook *ch;
3685 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3686 ch = E_NEW(E_Comp_Object_Hook, 1);
3687 if (!ch) return NULL;
3688 ch->hookpoint = hookpoint;
3690 ch->data = (void*)data;
3691 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3696 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3699 if (_e_comp_object_hooks_walking == 0)
3701 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3705 _e_comp_object_hooks_delete++;
3708 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3709 E_API E_Comp_Object_Intercept_Hook *
3710 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3712 E_Comp_Object_Intercept_Hook *ch;
3714 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3715 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3716 if (!ch) return NULL;
3717 ch->hookpoint = hookpoint;
3719 ch->data = (void*)data;
3720 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3725 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3728 if (_e_comp_object_intercept_hooks_walking == 0)
3730 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3734 _e_comp_object_intercept_hooks_delete++;
3739 e_comp_object_util_add(Evas_Object *obj)
3743 E_Comp_Config *conf = e_comp_config_get();
3744 Eina_Bool skip = EINA_FALSE;
3750 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3752 name = evas_object_name_get(obj);
3753 vis = evas_object_visible_get(obj);
3754 o = edje_object_add(e_comp->evas);
3755 evas_object_data_set(o, "comp_object", (void*)1);
3757 skip = (!strncmp(name, "noshadow", 8));
3759 evas_object_data_set(o, "comp_object_skip", (void*)1);
3761 if (conf->shadow_style)
3763 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3764 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3767 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3768 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3769 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3771 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3773 evas_object_geometry_get(obj, &x, &y, &w, &h);
3774 evas_object_geometry_set(o, x, y, w, h);
3775 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3777 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3779 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3780 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3781 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3782 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3783 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3784 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3786 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3788 edje_object_part_swallow(o, "e.swallow.content", obj);
3790 _e_comp_object_event_add(o);
3793 evas_object_show(o);
3798 /* utility functions for deleting objects when their "owner" is deleted */
3800 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3805 EINA_SAFETY_ON_NULL_RETURN(to_del);
3806 l = evas_object_data_get(obj, "comp_object-to_del");
3807 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3808 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3809 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3813 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3818 EINA_SAFETY_ON_NULL_RETURN(to_del);
3819 l = evas_object_data_get(obj, "comp_object-to_del");
3821 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3824 /////////////////////////////////////////////////////////
3826 EINTERN Evas_Object *
3827 e_comp_object_client_add(E_Client *ec)
3832 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3833 if (ec->frame) return NULL;
3834 _e_comp_smart_init();
3835 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3836 cw = evas_object_smart_data_get(o);
3837 if (!cw) return NULL;
3838 evas_object_data_set(o, "E_Client", ec);
3841 evas_object_data_set(o, "comp_object", (void*)1);
3843 _e_comp_object_event_add(o);
3848 /* utility functions for getting client inset */
3850 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3853 if (!cw->client_inset.calc)
3859 if (ax) *ax = x - cw->client_inset.l;
3860 if (ay) *ay = y - cw->client_inset.t;
3864 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3867 if (!cw->client_inset.calc)
3873 if (ax) *ax = x + cw->client_inset.l;
3874 if (ay) *ay = y + cw->client_inset.t;
3878 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3881 if (!cw->client_inset.calc)
3887 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3888 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3892 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3895 if (!cw->client_inset.calc)
3901 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3902 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3906 e_comp_object_client_get(Evas_Object *obj)
3911 /* FIXME: remove this when eo is used */
3912 o = evas_object_data_get(obj, "comp_smart_obj");
3914 return e_comp_object_client_get(o);
3915 return cw ? cw->ec : NULL;
3919 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3922 if (cw->frame_extends)
3923 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3928 if (w) *w = cw->ec->w;
3929 if (h) *h = cw->ec->h;
3934 e_comp_object_util_zone_get(Evas_Object *obj)
3936 E_Zone *zone = NULL;
3940 zone = e_comp_zone_find_by_ec(cw->ec);
3945 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3946 zone = e_comp_zone_xy_get(x, y);
3952 e_comp_object_util_center(Evas_Object *obj)
3954 int x, y, w, h, ow, oh;
3959 zone = e_comp_object_util_zone_get(obj);
3960 EINA_SAFETY_ON_NULL_RETURN(zone);
3961 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3962 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3963 ow = cw->ec->w, oh = cw->ec->h;
3965 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3966 x = x + (w - ow) / 2;
3967 y = y + (h - oh) / 2;
3968 evas_object_move(obj, x, y);
3972 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3974 int x, y, w, h, ow, oh;
3977 EINA_SAFETY_ON_NULL_RETURN(on);
3978 evas_object_geometry_get(on, &x, &y, &w, &h);
3979 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3980 ow = cw->ec->w, oh = cw->ec->h;
3982 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3983 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3987 e_comp_object_util_fullscreen(Evas_Object *obj)
3992 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3995 evas_object_move(obj, 0, 0);
3996 evas_object_resize(obj, e_comp->w, e_comp->h);
4001 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4009 ow = cw->w, oh = cw->h;
4011 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4012 zone = e_comp_object_util_zone_get(obj);
4013 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4014 if (x) *x = zx + (zw - ow) / 2;
4015 if (y) *y = zy + (zh - oh) / 2;
4019 e_comp_object_input_objs_del(Evas_Object *obj)
4022 E_Input_Rect_Data *input_rect_data;
4023 E_Input_Rect_Smart_Data *input_rect_sd;
4028 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4029 if (!input_rect_sd) return;
4031 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4033 if (input_rect_data->obj)
4035 evas_object_smart_member_del(input_rect_data->obj);
4036 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4038 E_FREE(input_rect_data);
4043 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4046 E_Input_Rect_Data *input_rect_data = NULL;
4047 E_Input_Rect_Smart_Data *input_rect_sd;
4048 int client_w, client_h;
4050 if (cw->ec->client.w)
4051 client_w = cw->ec->client.w;
4053 client_w = cw->ec->w;
4055 if (cw->ec->client.h)
4056 client_h = cw->ec->client.h;
4058 client_h = cw->ec->h;
4060 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4064 _e_comp_input_obj_smart_init();
4065 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4066 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4067 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4070 input_rect_sd->cw = cw;
4073 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4076 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4077 if (input_rect_data)
4079 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4080 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4084 if ((input_rect_data) &&
4085 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4087 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4088 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4089 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4090 evas_object_clip_set(input_rect_data->obj, cw->clip);
4091 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4092 evas_object_geometry_set(input_rect_data->obj,
4093 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4094 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4095 evas_object_pass_events_set(cw->default_input_obj, 1);
4096 evas_object_pass_events_set(cw->obj, 1);
4099 evas_object_show(input_rect_data->obj);
4100 evas_object_show(cw->input_obj);
4105 evas_object_smart_member_del(cw->input_obj);
4106 E_FREE_FUNC(cw->input_obj, evas_object_del);
4107 evas_object_pass_events_set(cw->default_input_obj, 0);
4108 evas_object_pass_events_set(cw->obj, 0);
4113 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4116 E_Input_Rect_Smart_Data *input_rect_sd;
4117 E_Input_Rect_Data *input_rect_data;
4120 if (!cw->input_obj) return;
4122 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4125 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4127 *list = eina_list_append(*list, &input_rect_data->rect);
4133 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4136 if (l) *l = cw->client_inset.l;
4137 if (r) *r = cw->client_inset.r;
4138 if (t) *t = cw->client_inset.t;
4139 if (b) *b = cw->client_inset.b;
4142 /* set geometry for CSD */
4144 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4150 if (cw->frame_object)
4151 CRI("ACK! ec:%p", cw->ec);
4152 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4153 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4154 calc = cw->client_inset.calc;
4155 cw->client_inset.calc = l || r || t || b;
4156 eina_stringshare_replace(&cw->frame_theme, "borderless");
4157 if (cw->client_inset.calc)
4159 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4160 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4161 e_client_size_set(cw->ec, tw, th);
4163 else if (cw->ec->maximized || cw->ec->fullscreen)
4165 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4166 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4168 if (!cw->ec->new_client)
4170 if (calc && cw->client_inset.calc)
4172 tx = cw->ec->x - (l - cw->client_inset.l);
4173 ty = cw->ec->y - (t - cw->client_inset.t);
4174 e_client_pos_set(cw->ec, tx, ty);
4176 cw->ec->changes.pos = cw->ec->changes.size = 1;
4179 cw->client_inset.l = l;
4180 cw->client_inset.r = r;
4181 cw->client_inset.t = t;
4182 cw->client_inset.b = b;
4186 e_comp_object_frame_allowed(Evas_Object *obj)
4188 API_ENTRY EINA_FALSE;
4189 return (cw->frame_object || (!cw->client_inset.calc));
4193 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4195 API_ENTRY EINA_FALSE;
4196 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4197 eina_stringshare_replace(&cw->frame_name, name);
4198 if (cw->frame_object)
4199 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4204 e_comp_object_frame_exists(Evas_Object *obj)
4206 API_ENTRY EINA_FALSE;
4207 return !!cw->frame_object;
4211 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4213 Evas_Object *o, *pbg;
4216 Eina_Stringshare *theme;
4218 API_ENTRY EINA_FALSE;
4220 if (!e_util_strcmp(cw->frame_theme, name))
4221 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4222 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4223 return _e_comp_object_shadow_setup(cw);
4224 pbg = cw->frame_object;
4225 theme = eina_stringshare_add(name);
4227 if (cw->frame_object)
4231 w = cw->ec->w, h = cw->ec->h;
4232 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4233 if ((cw->ec->w != w) || (cw->ec->h != h))
4235 cw->ec->changes.size = 1;
4238 E_FREE_FUNC(cw->frame_object, evas_object_del);
4239 if (!name) goto reshadow;
4241 o = edje_object_add(e_comp->evas);
4242 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4243 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4244 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4246 cw->frame_object = NULL;
4248 eina_stringshare_del(cw->frame_theme);
4249 cw->frame_theme = theme;
4254 if (theme != e_config->theme_default_border_style)
4256 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4257 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4261 ok = e_theme_edje_object_set(o, "base/theme/border",
4262 "e/widgets/border/default/border");
4263 if (ok && (theme == e_config->theme_default_border_style))
4265 /* Reset default border style to default */
4266 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4267 e_config_save_queue();
4274 cw->frame_object = o;
4275 eina_stringshare_del(cw->frame_theme);
4276 cw->frame_theme = theme;
4277 evas_object_name_set(o, "cw->frame_object");
4280 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4284 cw->ec->changes.icon = 1;
4290 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4295 _e_comp_object_shadow_setup(cw);
4298 int old_x, old_y, new_x = 0, new_y = 0;
4300 old_x = cw->x, old_y = cw->y;
4302 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4304 new_x = cw->ec->x, new_y = cw->ec->y;
4305 else if (cw->ec->placed || (!cw->ec->new_client))
4307 /* if no previous frame:
4308 * - reapply client_inset
4313 if (cw->ec->changes.size)
4321 zone = e_comp_zone_find_by_ec(cw->ec);
4324 x = cw->ec->client.x, y = cw->ec->client.y;
4325 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4326 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4328 new_x = x, new_y = y;
4331 if (old_x != new_x || old_y != new_y)
4333 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4334 cw->y = cw->x = -99999;
4335 evas_object_move(obj, new_x, new_y);
4339 if (cw->ec->maximized)
4341 cw->ec->changes.need_maximize = 1;
4344 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4345 if (cw->frame_object)
4347 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4350 cw->frame_extends = 0;
4351 evas_object_del(pbg);
4356 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4358 E_Comp_Object_Mover *prov;
4361 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4362 edje_object_signal_emit(cw->shobj, sig, src);
4363 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4364 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4365 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4367 /* start with highest priority callback first */
4368 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4370 if (!e_util_glob_match(sig, prov->sig)) continue;
4371 if (prov->func(prov->data, obj, sig)) break;
4376 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4378 /* FIXME: at some point I guess this should use eo to inherit
4379 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4380 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4383 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4387 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4390 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4394 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4397 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4401 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4404 Eina_Rectangle rect;
4407 if (cw->ec->input_only || (!cw->updates)) return;
4408 if (cw->nocomp) return;
4409 rect.x = x, rect.y = y;
4410 rect.w = w, rect.h = h;
4411 evas_object_smart_callback_call(obj, "damage", &rect);
4413 if (e_comp_is_on_overlay(cw->ec))
4415 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4416 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4417 * E module attempts to block screen update due to the particular policy.
4419 if (e_pixmap_resource_get(cw->ec->pixmap))
4420 cw->hwc_need_update = EINA_TRUE;
4423 /* ignore overdraw */
4424 if (cw->updates_full)
4426 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4427 e_comp_object_render_update_add(obj);
4429 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4430 evas_object_show(cw->smart_obj);
4434 /* clip rect to client surface */
4435 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4436 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4437 /* if rect is the total size of the client after clip, clear the updates
4438 * since this is guaranteed to be the whole region anyway
4440 eina_tiler_area_size_get(cw->updates, &tw, &th);
4441 if ((w > tw) || (h > th))
4443 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4444 eina_tiler_clear(cw->updates);
4445 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4447 tw = cw->ec->client.w, th = cw->ec->client.h;
4449 if ((!x) && (!y) && (w == tw) && (h == th))
4451 eina_tiler_clear(cw->updates);
4452 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4453 cw->updates_full = 1;
4454 cw->update_count = 0;
4457 if (cw->update_count > UPDATE_MAX)
4459 /* this is going to get really dumb, so just update the whole thing */
4460 eina_tiler_clear(cw->updates);
4461 cw->update_count = cw->updates_full = 1;
4462 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4463 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4467 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4468 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4470 cw->updates_exist = 1;
4471 e_comp_object_render_update_add(obj);
4473 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4474 evas_object_show(cw->smart_obj);
4478 e_comp_object_damage_exists(Evas_Object *obj)
4480 API_ENTRY EINA_FALSE;
4481 return cw->updates_exist;
4485 e_comp_object_render_update_add(Evas_Object *obj)
4489 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4490 if (cw->render_update_lock.lock) return;
4491 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4495 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4497 e_comp_render_queue();
4501 e_comp_object_render_update_del(Evas_Object *obj)
4505 if (cw->ec->input_only || (!cw->updates)) return;
4506 if (!cw->update) return;
4508 /* this gets called during comp animating to clear the update flag */
4509 if (e_comp->grabbed) return;
4510 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4511 if (!e_comp->updates)
4513 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4514 if (e_comp->render_animator)
4515 ecore_animator_freeze(e_comp->render_animator);
4520 e_comp_object_shape_apply(Evas_Object *obj)
4524 unsigned int i, *pix, *p;
4528 if (!cw->ec) return; //NYI
4529 if (cw->external_content) return;
4532 if ((cw->ec->shape_rects_num >= 1) &&
4533 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4538 ERR("BUGGER: shape with native surface? cw=%p", cw);
4541 evas_object_image_size_get(cw->obj, &w, &h);
4542 if ((w < 1) || (h < 1)) return;
4545 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4546 _e_comp_object_alpha_set(cw);
4547 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4548 evas_object_image_alpha_set(o, 1);
4550 p = pix = evas_object_image_data_get(cw->obj, 1);
4553 evas_object_image_data_set(cw->obj, pix);
4558 unsigned char *spix, *sp;
4560 spix = calloc(w * h, sizeof(unsigned char));
4562 for (i = 0; i < cw->ec->shape_rects_num; i++)
4566 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4567 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4568 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4569 sp = spix + (w * ry) + rx;
4570 for (py = 0; py < rh; py++)
4572 for (px = 0; px < rw; px++)
4580 for (py = 0; py < h; py++)
4582 for (px = 0; px < w; px++)
4584 unsigned int mask, imask;
4586 mask = ((unsigned int)(*sp)) << 24;
4588 imask |= imask >> 8;
4589 imask |= imask >> 8;
4590 *p = mask | (*p & imask);
4591 //if (*sp) *p = 0xff000000 | *p;
4592 //else *p = 0x00000000;
4601 for (py = 0; py < h; py++)
4603 for (px = 0; px < w; px++)
4607 evas_object_image_data_set(cw->obj, pix);
4608 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4609 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4611 evas_object_image_data_set(o, pix);
4612 evas_object_image_data_update_add(o, 0, 0, w, h);
4614 // don't need to fix alpha chanel as blending
4615 // should be totally off here regardless of
4616 // alpha channel content
4620 _e_comp_object_clear(E_Comp_Object *cw)
4625 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4627 if (cw->render_update_lock.lock) return;
4630 e_pixmap_clear(cw->ec->pixmap);
4632 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4633 evas_object_image_size_set(cw->obj, 1, 1);
4634 evas_object_image_data_set(cw->obj, NULL);
4635 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4637 evas_object_image_size_set(o, 1, 1);
4638 evas_object_image_data_set(o, NULL);
4641 e_comp_object_render_update_del(cw->smart_obj);
4645 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4649 API_ENTRY EINA_FALSE;
4651 if (cw->transparent.set == set)
4656 evas_object_color_get(obj, &r, &g, &b, &a);
4657 evas_object_color_set(obj, 0, 0, 0, 0);
4659 cw->transparent.user_r = r;
4660 cw->transparent.user_g = g;
4661 cw->transparent.user_b = b;
4662 cw->transparent.user_a = a;
4664 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4666 cw->transparent.user_r,
4667 cw->transparent.user_g,
4668 cw->transparent.user_b,
4669 cw->transparent.user_a);
4671 cw->transparent.set = EINA_TRUE;
4675 cw->transparent.set = EINA_FALSE;
4677 evas_object_color_set(obj,
4678 cw->transparent.user_r,
4679 cw->transparent.user_g,
4680 cw->transparent.user_b,
4681 cw->transparent.user_a);
4683 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4685 cw->transparent.user_r,
4686 cw->transparent.user_g,
4687 cw->transparent.user_b,
4688 cw->transparent.user_a);
4694 /* helper function to simplify toggling of redirection for display servers which support it */
4696 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4701 if (cw->redirected == set) return;
4702 cw->redirected = set;
4703 if (cw->external_content) return;
4705 e_comp_object_map_update(obj);
4709 if (cw->updates_exist)
4710 e_comp_object_render_update_add(obj);
4712 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4714 _e_comp_object_transparent_set(obj, EINA_FALSE);
4715 evas_object_smart_callback_call(obj, "redirected", NULL);
4719 _e_comp_object_clear(cw);
4720 _e_comp_object_transparent_set(obj, EINA_TRUE);
4721 evas_object_smart_callback_call(obj, "unredirected", NULL);
4726 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4729 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4731 if (cw->buffer_destroy_listener.notify)
4733 cw->buffer_destroy_listener.notify = NULL;
4734 wl_list_remove(&cw->buffer_destroy_listener.link);
4737 if (e_object_is_del(E_OBJECT(cw->ec)))
4739 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4744 /* if it's current displaying buffer, do not remove its content */
4745 if (!evas_object_visible_get(cw->ec->frame))
4746 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4751 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4756 if (cw->buffer_destroy_listener.notify)
4758 wl_list_remove(&cw->buffer_destroy_listener.link);
4759 cw->buffer_destroy_listener.notify = NULL;
4762 if (cw->tbm_surface)
4764 tbm_surface_internal_unref(cw->tbm_surface);
4765 cw->tbm_surface = NULL;
4770 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4772 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4773 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4775 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4777 tbm_surface_internal_ref(ns->data.tbm.buffer);
4778 cw->tbm_surface = ns->data.tbm.buffer;
4782 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4783 evas_object_image_native_surface_set(cw->obj, ns);
4787 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4789 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4790 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4791 evas_object_image_native_surface_set(o, ns);
4798 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4800 Evas_Native_Surface ns;
4803 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4804 if (cw->ec->input_only) return;
4805 if (cw->external_content) return;
4806 if (cw->render_update_lock.lock) return;
4809 memset(&ns, 0, sizeof(Evas_Native_Surface));
4813 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4814 set = (!cw->ec->shaped);
4816 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4820 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4824 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4827 if (cw->ec->input_only) return;
4830 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4831 _e_comp_object_alpha_set(cw);
4833 e_comp_object_native_surface_set(obj, cw->native);
4834 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4838 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4844 if (cw->blanked == set) return;
4846 _e_comp_object_alpha_set(cw);
4849 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4850 evas_object_image_data_set(cw->obj, NULL);
4854 e_comp_object_native_surface_set(obj, 1);
4855 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4859 _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)
4864 if (!_damage_trace) return;
4868 if (!evas_object_visible_get(cw->obj)) return;
4870 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4872 o = evas_object_rectangle_add(e_comp->evas);
4873 evas_object_layer_set(o, E_LAYER_MAX);
4874 evas_object_name_set(o, "damage_trace");
4875 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4876 evas_object_resize(o, dmg_w, dmg_h);
4877 evas_object_color_set(o, 0, 128, 0, 128);
4878 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4879 evas_object_pass_events_set(o, EINA_TRUE);
4880 evas_object_show(o);
4882 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4884 dmg_w, dmg_h, dmg_x, dmg_y,
4885 origin->w, origin->h, origin->x, origin->y);
4887 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4890 /* mark an object as dirty and setup damages */
4892 e_comp_object_dirty(Evas_Object *obj)
4895 Eina_Rectangle *rect;
4899 Eina_Bool dirty, visible;
4903 if (cw->external_content) return;
4904 if (!cw->redirected) return;
4905 if (cw->render_update_lock.lock)
4907 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4910 /* only actually dirty if pixmap is available */
4911 if (!e_pixmap_resource_get(cw->ec->pixmap))
4913 // e_pixmap_size_get returns last attached buffer size
4914 // eventhough it is destroyed
4915 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4918 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4919 visible = cw->visible;
4920 if (!dirty) w = h = 1;
4921 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4923 evas_object_image_data_set(cw->obj, NULL);
4924 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4925 evas_object_image_size_set(cw->obj, tw, th);
4926 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4927 if (cw->pending_updates)
4928 eina_tiler_area_size_set(cw->pending_updates, w, h);
4929 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4931 evas_object_image_pixels_dirty_set(o, dirty);
4933 evas_object_image_data_set(o, NULL);
4934 evas_object_image_size_set(o, tw, th);
4935 visible |= evas_object_visible_get(o);
4939 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4943 e_comp_object_native_surface_set(obj, 1);
4945 m = _e_comp_object_map_damage_transform_get(cw->ec);
4946 it = eina_tiler_iterator_new(cw->updates);
4947 EINA_ITERATOR_FOREACH(it, rect)
4949 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4950 * of evas engine and doesn't convert damage according to evas_map.
4951 * so damage of evas_object_image use surface coordinate.
4955 int damage_x, damage_y, damage_w, damage_h;
4957 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4958 &damage_x, &damage_y, &damage_w, &damage_h);
4959 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4960 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4964 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4965 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4968 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4969 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4970 if (cw->pending_updates)
4971 eina_tiler_rect_add(cw->pending_updates, rect);
4973 eina_iterator_free(it);
4974 if (m) e_map_free(m);
4975 if (cw->pending_updates)
4976 eina_tiler_clear(cw->updates);
4979 cw->pending_updates = cw->updates;
4980 cw->updates = eina_tiler_new(w, h);
4981 eina_tiler_tile_size_set(cw->updates, 1, 1);
4983 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4984 evas_object_smart_callback_call(obj, "dirty", NULL);
4985 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4986 /* force render if main object is hidden but mirrors are visible */
4987 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4988 e_comp_object_render(obj);
4992 e_comp_object_render(Evas_Object *obj)
4999 API_ENTRY EINA_FALSE;
5001 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5002 if (cw->ec->input_only) return EINA_TRUE;
5003 if (cw->external_content) return EINA_TRUE;
5004 if (cw->native) return EINA_FALSE;
5005 /* if comp object is not redirected state, comp object should not be set by newly committed data
5006 because image size of comp object is 1x1 and it should not be shown on canvas */
5007 if (!cw->redirected) return EINA_TRUE;
5008 if (cw->render_update_lock.lock)
5010 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5013 e_comp_object_render_update_del(obj);
5014 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5016 if (!cw->pending_updates)
5018 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5019 evas_object_image_data_set(cw->obj, NULL);
5020 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5021 evas_object_image_data_set(o, NULL);
5025 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5027 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5029 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5032 e_pixmap_image_refresh(cw->ec->pixmap);
5033 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5036 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5037 e_pixmap_image_data_ref(cw->ec->pixmap);
5039 /* set pixel data */
5040 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5041 _e_comp_object_alpha_set(cw);
5042 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5044 evas_object_image_data_set(o, pix);
5045 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5046 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5049 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5051 e_comp_client_post_update_add(cw->ec);
5056 /* create a duplicate of an evas object */
5058 e_comp_object_util_mirror_add(Evas_Object *obj)
5062 unsigned int *pix = NULL;
5063 Eina_Bool argb = EINA_FALSE;
5068 cw = evas_object_data_get(obj, "comp_mirror");
5071 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5072 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5073 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5074 evas_object_image_alpha_set(o, 1);
5075 evas_object_image_source_set(o, obj);
5078 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5079 if (cw->external_content)
5081 ERR("%p of client %p is external content.", obj, cw->ec);
5084 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5085 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5086 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5087 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5088 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5089 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5090 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5091 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5092 evas_object_data_set(o, "comp_mirror", cw);
5094 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5095 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5097 evas_object_image_size_set(o, tw, th);
5100 pix = evas_object_image_data_get(cw->obj, 0);
5106 evas_object_image_native_surface_set(o, cw->ns);
5109 Evas_Native_Surface ns;
5110 memset(&ns, 0, sizeof(Evas_Native_Surface));
5111 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5112 evas_object_image_native_surface_set(o, &ns);
5117 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5118 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5120 (e_pixmap_image_exists(cw->ec->pixmap)))
5121 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5123 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5130 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5131 evas_object_image_pixels_dirty_set(o, dirty);
5132 evas_object_image_data_set(o, pix);
5133 evas_object_image_data_set(cw->obj, pix);
5135 evas_object_image_data_update_add(o, 0, 0, tw, th);
5140 //////////////////////////////////////////////////////
5143 e_comp_object_effect_allowed_get(Evas_Object *obj)
5145 API_ENTRY EINA_FALSE;
5147 if (!cw->shobj) return EINA_FALSE;
5148 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5149 return !e_comp_config_get()->match.disable_borders;
5152 /* setup an api effect for a client */
5154 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5157 Eina_Stringshare *grp;
5158 E_Comp_Config *config;
5159 Eina_Bool loaded = EINA_FALSE;
5161 API_ENTRY EINA_FALSE;
5162 if (!cw->shobj) return EINA_FALSE; //input window
5164 if (!effect) effect = "none";
5165 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5167 config = e_comp_config_get();
5168 if ((config) && (config->effect_file))
5170 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5172 cw->effect_set = EINA_TRUE;
5179 edje_object_file_get(cw->effect_obj, NULL, &grp);
5180 cw->effect_set = !eina_streq(effect, "none");
5181 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5182 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5184 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5185 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5186 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5188 if (cw->effect_running)
5190 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5193 cw->effect_set = EINA_FALSE;
5194 return cw->effect_set;
5198 if (cw->effect_running)
5200 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5203 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5204 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5205 if (cw->effect_clip)
5207 evas_object_clip_unset(cw->clip);
5208 cw->effect_clip = 0;
5210 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5212 _e_comp_object_dim_update(cw);
5214 return cw->effect_set;
5217 /* set params for embryo scripts in effect */
5219 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5221 Edje_Message_Int_Set *msg;
5225 EINA_SAFETY_ON_NULL_RETURN(params);
5226 EINA_SAFETY_ON_FALSE_RETURN(count);
5227 if (!cw->effect_set) return;
5229 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5230 msg->count = (int)count;
5231 for (x = 0; x < count; x++)
5232 msg->val[x] = params[x];
5233 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5234 edje_object_message_signal_process(cw->effect_obj);
5238 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5240 Edje_Signal_Cb end_cb;
5242 E_Comp_Object *cw = data;
5244 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5245 cw->effect_running = 0;
5246 if (!_e_comp_object_animating_end(cw)) return;
5248 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5250 evas_object_data_del(cw->smart_obj, "effect_running");
5251 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5252 e_comp_visibility_calculation_set(EINA_TRUE);
5255 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5256 if (!end_cb) return;
5257 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5258 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5259 end_cb(end_data, cw->smart_obj, emission, source);
5262 /* clip effect to client's zone */
5264 e_comp_object_effect_clip(Evas_Object *obj)
5268 zone = e_comp_zone_find_by_ec(cw->ec);
5270 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5271 if (!cw->effect_clip_able) return;
5272 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5273 cw->effect_clip = 1;
5276 /* unclip effect from client's zone */
5278 e_comp_object_effect_unclip(Evas_Object *obj)
5281 if (!cw->effect_clip) return;
5282 evas_object_clip_unset(cw->smart_obj);
5283 cw->effect_clip = 0;
5286 /* start effect, running end_cb after */
5288 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5290 API_ENTRY EINA_FALSE;
5291 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5292 if (!cw->effect_set) return EINA_FALSE;
5294 if (cw->effect_running)
5296 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5299 e_comp_object_effect_clip(obj);
5300 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5302 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5303 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5304 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5305 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5307 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5308 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5310 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5311 _e_comp_object_animating_begin(cw);
5312 cw->effect_running = 1;
5316 /* stop a currently-running effect immediately */
5318 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5321 Edje_Signal_Cb end_cb_before = NULL;
5322 void *end_data_before = NULL;
5323 API_ENTRY EINA_FALSE;
5325 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5326 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5328 if (end_cb_before != end_cb) return EINA_TRUE;
5329 e_comp_object_effect_unclip(obj);
5330 if (cw->effect_clip)
5332 evas_object_clip_unset(cw->effect_obj);
5333 cw->effect_clip = 0;
5335 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5336 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5338 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5340 evas_object_data_del(cw->smart_obj, "effect_running");
5341 e_comp_visibility_calculation_set(EINA_TRUE);
5344 cw->effect_running = 0;
5345 ret = _e_comp_object_animating_end(cw);
5347 if ((ret) && (end_cb_before))
5349 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5350 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5357 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5359 return a->pri - b->pri;
5362 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5363 E_API E_Comp_Object_Mover *
5364 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5366 E_Comp_Object_Mover *prov;
5368 prov = E_NEW(E_Comp_Object_Mover, 1);
5369 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5370 prov->func = provider;
5371 prov->data = (void*)data;
5374 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5375 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5380 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5382 EINA_SAFETY_ON_NULL_RETURN(prov);
5383 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5388 e_comp_object_effect_object_get(Evas_Object *obj)
5392 return cw->effect_obj;
5396 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5398 API_ENTRY EINA_FALSE;
5399 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5400 if (!cw->effect_set) return EINA_FALSE;
5407 ////////////////////////////////////
5410 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5412 if (e_comp->autoclose.obj)
5414 e_comp_ungrab_input(0, 1);
5415 if (e_comp->autoclose.del_cb)
5416 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5417 else if (!already_del)
5419 evas_object_hide(e_comp->autoclose.obj);
5420 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5422 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5424 e_comp->autoclose.obj = NULL;
5425 e_comp->autoclose.data = NULL;
5426 e_comp->autoclose.del_cb = NULL;
5427 e_comp->autoclose.key_cb = NULL;
5428 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5432 _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)
5434 _e_comp_object_autoclose_cleanup(0);
5438 _e_comp_object_autoclose_setup(Evas_Object *obj)
5440 if (!e_comp->autoclose.rect)
5442 /* create rect just below autoclose object to catch mouse events */
5443 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5444 evas_object_move(e_comp->autoclose.rect, 0, 0);
5445 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5446 evas_object_show(e_comp->autoclose.rect);
5447 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5448 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5449 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5450 e_comp_grab_input(0, 1);
5452 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5453 evas_object_focus_set(obj, 1);
5457 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5459 _e_comp_object_autoclose_setup(obj);
5460 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5464 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5466 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5467 _e_comp_object_autoclose_cleanup(1);
5468 if (e_client_focused_get()) return;
5470 E_Zone *zone = e_zone_current_get();
5473 e_zone_focus_reset(zone);
5477 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5481 if (e_comp->autoclose.obj)
5483 if (e_comp->autoclose.obj == obj) return;
5484 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5485 e_comp->autoclose.obj = obj;
5486 e_comp->autoclose.del_cb = del_cb;
5487 e_comp->autoclose.key_cb = cb;
5488 e_comp->autoclose.data = (void*)data;
5489 if (evas_object_visible_get(obj))
5490 _e_comp_object_autoclose_setup(obj);
5492 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5493 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5496 e_comp->autoclose.obj = obj;
5497 e_comp->autoclose.del_cb = del_cb;
5498 e_comp->autoclose.key_cb = cb;
5499 e_comp->autoclose.data = (void*)data;
5500 if (evas_object_visible_get(obj))
5501 _e_comp_object_autoclose_setup(obj);
5503 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5504 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5508 e_comp_object_is_animating(Evas_Object *obj)
5512 return cw->animating;
5516 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5520 if ((cw->external_content) &&
5521 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5523 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5524 "But current external content is %d object for %p.",
5525 cw->content_type, cw->ec);
5529 cw->user_alpha_set = EINA_TRUE;
5530 cw->user_alpha = alpha;
5532 if (!cw->obj) return;
5534 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5536 evas_object_image_alpha_set(cw->obj, alpha);
5538 if ((!cw->native) && (!cw->external_content))
5539 evas_object_image_data_set(cw->obj, NULL);
5543 e_comp_object_alpha_get(Evas_Object *obj)
5545 API_ENTRY EINA_FALSE;
5547 return evas_object_image_alpha_get(cw->obj);
5551 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5553 Eina_Bool mask_set = EINA_FALSE;
5557 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5558 if (cw->ec->input_only) return;
5565 o = evas_object_rectangle_add(e_comp->evas);
5566 evas_object_color_set(o, 0, 0, 0, 0);
5567 evas_object_clip_set(o, cw->clip);
5568 evas_object_smart_member_add(o, obj);
5569 evas_object_move(o, 0, 0);
5570 evas_object_resize(o, cw->w, cw->h);
5571 /* save render op value to restore when clear a mask.
5573 * NOTE: DO NOT change the render op on ec->frame while mask object
5574 * is set. it will overwrite the changed op value. */
5575 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5576 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5577 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5578 if (cw->visible) evas_object_show(o);
5581 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5582 ELOGF("COMP", " |mask_obj", cw->ec);
5583 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5590 evas_object_smart_member_del(cw->mask.obj);
5591 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5593 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5594 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5600 e_comp_object_mask_has(Evas_Object *obj)
5602 API_ENTRY EINA_FALSE;
5604 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5608 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5613 if ((cw->external_content) &&
5614 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5616 WRN("Can set up size to ONLY evas \"image\" object. "
5617 "But current external content is %d object for %p.",
5618 cw->content_type, cw->ec);
5622 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5624 evas_object_image_size_set(cw->obj, tw, th);
5628 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5630 Eina_Bool transform_set = EINA_FALSE;
5632 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5633 if (cw->ec->input_only) return;
5635 transform_set = !!set;
5639 if (!cw->transform_bg_obj)
5641 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5642 evas_object_move(o, 0, 0);
5643 evas_object_resize(o, 1, 1);
5644 if (cw->transform_bg_color.a >= 255)
5645 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5647 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5648 evas_object_color_set(o,
5649 cw->transform_bg_color.r,
5650 cw->transform_bg_color.g,
5651 cw->transform_bg_color.b,
5652 cw->transform_bg_color.a);
5653 if (cw->visible) evas_object_show(o);
5655 cw->transform_bg_obj = o;
5656 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5658 _e_comp_object_transform_obj_stack_update(obj);
5662 if (cw->transform_bg_obj)
5664 evas_object_smart_member_del(cw->transform_bg_obj);
5665 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5671 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5675 cw->transform_bg_color.r = r;
5676 cw->transform_bg_color.g = g;
5677 cw->transform_bg_color.b = b;
5678 cw->transform_bg_color.a = a;
5680 if (cw->transform_bg_obj)
5682 evas_object_color_set(cw->transform_bg_obj,
5683 cw->transform_bg_color.r,
5684 cw->transform_bg_color.g,
5685 cw->transform_bg_color.b,
5686 cw->transform_bg_color.a);
5691 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5694 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5695 if (cw->ec->input_only) return;
5696 if (!cw->transform_bg_obj) return;
5698 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5702 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5705 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5706 if (cw->ec->input_only) return;
5707 if (!cw->transform_bg_obj) return;
5709 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5713 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5715 Eina_Bool transform_set = EINA_FALSE;
5717 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5718 if (cw->ec->input_only) return;
5720 transform_set = !!set;
5724 if (!cw->transform_tranp_obj)
5726 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5727 evas_object_move(o, 0, 0);
5728 evas_object_resize(o, 1, 1);
5729 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5730 evas_object_color_set(o, 0, 0, 0, 0);
5731 if (cw->visible) evas_object_show(o);
5733 cw->transform_tranp_obj = o;
5734 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5735 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5736 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5738 _e_comp_object_transform_obj_stack_update(obj);
5742 if (cw->transform_tranp_obj)
5744 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5745 evas_object_smart_member_del(cw->transform_tranp_obj);
5746 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5752 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5755 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5756 if (cw->ec->input_only) return;
5757 if (!cw->transform_tranp_obj) return;
5759 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5763 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5766 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5767 if (cw->ec->input_only) return;
5768 if (!cw->transform_tranp_obj) return;
5770 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5773 #ifdef REFACTOR_DESK_AREA
5776 e_comp_object_layer_update(Evas_Object *obj,
5777 Evas_Object *above, Evas_Object *below)
5779 E_Comp_Object *cw2 = NULL;
5780 Evas_Object *o = NULL;
5785 if (cw->ec->layer_block) return;
5786 if ((above) && (below))
5788 ERR("Invalid layer update request! cw=%p", cw);
5796 layer = evas_object_layer_get(o);
5797 cw2 = evas_object_data_get(o, "comp_obj");
5800 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5802 o = evas_object_above_get(o);
5803 if ((!o) || (o == cw->smart_obj)) break;
5804 if (evas_object_layer_get(o) != layer)
5806 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5811 ec = e_client_top_get();
5812 if (ec) o = ec->frame;
5815 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5819 _e_comp_object_layers_remove(cw);
5822 if (cw2->layer > cw->layer)
5823 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5824 else if (cw2->layer == cw->layer)
5827 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5829 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5831 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5834 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5837 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5842 e_comp_object_layer_get(Evas_Object *obj)
5849 e_comp_object_content_set(Evas_Object *obj,
5850 Evas_Object *content,
5851 E_Comp_Object_Content_Type type)
5853 API_ENTRY EINA_FALSE;
5855 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5856 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5857 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5861 ERR("Can't set e.swallow.content to requested content. "
5862 "Previous comp object should not be changed at all.");
5866 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5868 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5869 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5871 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5872 type, content, cw->ec, cw->ec->pixmap);
5876 cw->external_content = EINA_TRUE;
5879 cw->content_type = type;
5880 e_util_size_debug_set(cw->obj, 1);
5881 evas_object_name_set(cw->obj, "cw->obj");
5882 _e_comp_object_alpha_set(cw);
5885 _e_comp_object_shadow_setup(cw);
5891 e_comp_object_content_unset(Evas_Object *obj)
5893 API_ENTRY EINA_FALSE;
5895 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5896 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5898 if (!cw->obj && !cw->ec->visible)
5900 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5904 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5906 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5912 if (cw->frame_object)
5913 edje_object_part_unswallow(cw->frame_object, cw->obj);
5915 edje_object_part_unswallow(cw->shobj, cw->obj);
5917 evas_object_del(cw->obj);
5918 evas_object_hide(cw->obj);
5922 cw->external_content = EINA_FALSE;
5923 if (cw->ec->is_cursor)
5926 DBG("%p is cursor surface..", cw->ec);
5927 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5929 evas_object_resize(cw->ec->frame, pw, ph);
5930 evas_object_hide(cw->ec->frame);
5935 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5936 cw->obj = evas_object_image_filled_add(e_comp->evas);
5937 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5938 e_util_size_debug_set(cw->obj, 1);
5939 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5940 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5941 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5942 evas_object_name_set(cw->obj, "cw->obj");
5943 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5944 _e_comp_object_alpha_set(cw);
5947 _e_comp_object_shadow_setup(cw);
5952 _e_comp_intercept_show_helper(cw);
5956 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5957 e_comp_object_dirty(cw->smart_obj);
5958 e_comp_object_render(cw->smart_obj);
5959 e_comp_object_render_update_add(obj);
5964 EINTERN Evas_Object *
5965 e_comp_object_content_get(Evas_Object *obj)
5969 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5971 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5973 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5980 E_API E_Comp_Object_Content_Type
5981 e_comp_object_content_type_get(Evas_Object *obj)
5983 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5985 return cw->content_type;
5989 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5992 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5993 E_Comp_Config *conf = e_comp_config_get();
5994 if (cw->ec->input_only) return;
5995 if (!conf->dim_rect_enable) return;
5997 cw->dim.mask_set = mask_set;
6003 if (!cw->dim.enable) return;
6004 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6008 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6010 Eina_Bool mask_set = EINA_FALSE;
6014 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6015 E_Comp_Config *conf = e_comp_config_get();
6016 if (cw->ec->input_only) return;
6017 if (!conf->dim_rect_enable) return;
6023 if (cw->dim.mask_obj)
6025 evas_object_smart_member_del(cw->dim.mask_obj);
6026 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6029 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);
6030 o = evas_object_rectangle_add(e_comp->evas);
6031 evas_object_color_set(o, 0, 0, 0, 0);
6032 evas_object_smart_member_add(o, obj);
6033 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6034 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6036 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6037 if (cw->visible) evas_object_show(o);
6039 cw->dim.mask_obj = o;
6040 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6042 evas_object_layer_set(cw->dim.mask_obj, 9998);
6046 if (cw->dim.mask_obj)
6048 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6049 evas_object_smart_member_del(cw->dim.mask_obj);
6050 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6056 e_comp_object_dim_client_set(E_Client *ec)
6058 E_Comp_Config *conf = e_comp_config_get();
6060 if (!conf->dim_rect_enable) return ;
6061 if (dim_client == ec) return;
6063 Eina_Bool prev_dim = EINA_FALSE;
6064 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6066 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6067 prev_dim = EINA_TRUE;
6069 if (prev_dim && dim_client->visible && ec)
6071 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6072 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6076 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6077 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6083 e_comp_object_dim_client_get(void)
6085 E_Comp_Config *conf = e_comp_config_get();
6087 if (!conf->dim_rect_enable ) return NULL;
6093 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6096 char emit[32] = "\0";
6097 E_Comp_Config *conf = e_comp_config_get();
6100 if (!conf->dim_rect_enable) return;
6101 if (!cw->effect_obj) return;
6102 if (enable == cw->dim.enable) return;
6104 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6105 if (noeffect || !conf->dim_rect_effect)
6107 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6111 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6114 cw->dim.enable = enable;
6116 if (cw->dim.mask_set && !enable)
6118 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6119 edje_object_signal_emit(cw->effect_obj, emit, "e");
6121 else if (cw->dim.mask_set && enable)
6123 edje_object_signal_emit(cw->effect_obj, emit, "e");
6124 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6128 edje_object_signal_emit(cw->effect_obj, emit, "e");
6133 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6135 API_ENTRY EINA_FALSE;
6136 E_Comp_Config *conf = e_comp_config_get();
6138 if (!ec) return EINA_FALSE;
6139 if (!conf->dim_rect_enable) return EINA_FALSE;
6141 if (cw->dim.enable) return EINA_TRUE;
6147 _e_comp_object_dim_update(E_Comp_Object *cw)
6149 E_Comp_Config *conf = e_comp_config_get();
6152 if (!conf->dim_rect_enable) return;
6153 if (!cw->effect_obj) return;
6156 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6157 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6159 if (cw->dim.mask_set)
6161 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6167 e_comp_object_clear(Evas_Object *obj)
6171 _e_comp_object_clear(cw);
6175 e_comp_object_hwc_update_exists(Evas_Object *obj)
6177 API_ENTRY EINA_FALSE;
6178 return cw->hwc_need_update;
6183 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6186 cw->hwc_need_update = set;
6190 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6192 API_ENTRY EINA_FALSE;
6193 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6197 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6200 if (cw->indicator.obj != indicator)
6201 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6202 cw->indicator.obj = indicator;
6203 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6207 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6210 if (cw->indicator.obj != indicator) return;
6211 cw->indicator.obj = NULL;
6212 edje_object_part_unswallow(cw->shobj, indicator);
6216 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6219 Edje_Message_Int_Set *msg;
6221 if (!cw->indicator.obj) return;
6223 cw->indicator.w = w;
6224 cw->indicator.h = h;
6226 if (!cw->shobj) return;
6228 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6232 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6233 edje_object_message_signal_process(cw->shobj);
6236 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6238 e_comp_object_map_update(Evas_Object *obj)
6241 E_Client *ec = cw->ec;
6242 E_Comp_Wl_Client_Data *cdata;
6244 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6247 int l, remain = sizeof buffer;
6250 if (e_object_is_del(E_OBJECT(ec))) return;
6251 cdata = e_client_cdata_get(ec);
6254 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6255 * when new buffer is attached.
6257 if (!cdata->buffer_ref.buffer) return;
6259 if ((!cw->redirected) ||
6260 (e_client_video_hw_composition_check(ec)) ||
6261 (!e_comp_wl_output_buffer_transform_get(ec) &&
6262 cdata->scaler.buffer_viewport.buffer.scale == 1))
6264 if (evas_object_map_enable_get(cw->effect_obj))
6266 ELOGF("TRANSFORM", "map: disable", cw->ec);
6267 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6268 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6269 evas_object_resize(cw->effect_obj, tw, th);
6276 EINA_SAFETY_ON_NULL_RETURN(map);
6278 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6284 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6286 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6287 e_map_point_image_uv_set(map, 0, x, y);
6288 l = snprintf(p, remain, "%d,%d", x, y);
6289 p += l, remain -= l;
6291 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6292 e_map_point_image_uv_set(map, 1, x, y);
6293 l = snprintf(p, remain, " %d,%d", x, y);
6294 p += l, remain -= l;
6296 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6297 e_map_point_image_uv_set(map, 2, x, y);
6298 l = snprintf(p, remain, " %d,%d", x, y);
6299 p += l, remain -= l;
6301 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6302 e_map_point_image_uv_set(map, 3, x, y);
6303 l = snprintf(p, remain, " %d,%d", x, y);
6304 p += l, remain -= l;
6306 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6308 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6310 e_comp_object_map_set(cw->effect_obj, map);
6311 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6315 /* if there's screen rotation with comp mode, then ec->effect_obj and
6316 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6318 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6319 evas_object_resize(cw->effect_obj, tw, th);
6323 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6325 API_ENTRY EINA_FALSE;
6327 cw->render_trace = set;
6333 e_comp_object_native_usable_get(Evas_Object *obj)
6335 API_ENTRY EINA_FALSE;
6336 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6338 if (cw->ec->input_only) return EINA_FALSE;
6339 if (cw->external_content) return EINA_FALSE;
6340 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6342 /* just return true value, if it is normal case */
6343 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6346 Evas_Native_Surface *ns;
6347 ns = evas_object_image_native_surface_get(cw->obj);
6349 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6352 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6360 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6362 API_ENTRY EINA_FALSE;
6363 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6364 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6365 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6369 case E_COMP_IMAGE_FILTER_BLUR:
6370 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6372 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6373 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6375 case E_COMP_IMAGE_FILTER_INVERSE:
6376 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6378 case E_COMP_IMAGE_FILTER_NONE:
6380 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6384 cw->image_filter = filter;
6389 EINTERN E_Comp_Image_Filter
6390 e_comp_object_image_filter_get(Evas_Object *obj)
6392 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6393 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6394 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6395 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6397 return cw->image_filter;
6401 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6405 if (!_damage_trace) return;
6407 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6408 evas_object_del(obj);
6410 _damage_trace_post_objs = NULL;
6414 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6416 if (!_damage_trace) return;
6418 _damage_trace_post_objs = _damage_trace_objs;
6419 _damage_trace_objs = NULL;
6423 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6425 if (_damage_trace == onoff) return;
6429 evas_event_callback_add(e_comp->evas,
6430 EVAS_CALLBACK_RENDER_PRE,
6431 _e_comp_object_damage_trace_render_pre_cb,
6434 evas_event_callback_add(e_comp->evas,
6435 EVAS_CALLBACK_RENDER_POST,
6436 _e_comp_object_damage_trace_render_post_cb,
6443 EINA_LIST_FREE(_damage_trace_objs, obj)
6444 evas_object_del(obj);
6446 _damage_trace_objs = NULL;
6448 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6449 evas_object_del(obj);
6451 _damage_trace_post_objs = NULL;
6453 evas_event_callback_del(e_comp->evas,
6454 EVAS_CALLBACK_RENDER_PRE,
6455 _e_comp_object_damage_trace_render_pre_cb);
6457 evas_event_callback_del(e_comp->evas,
6458 EVAS_CALLBACK_RENDER_POST,
6459 _e_comp_object_damage_trace_render_post_cb);
6462 _damage_trace = onoff;
6466 e_comp_object_redirected_get(Evas_Object *obj)
6468 API_ENTRY EINA_FALSE;
6469 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6471 return cw->redirected;
6475 e_comp_object_color_visible_get(Evas_Object *obj)
6477 API_ENTRY EINA_FALSE;
6480 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6482 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6486 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6490 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6494 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6502 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6504 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6506 return e_map_set_to_comp_object(em, obj);
6510 e_comp_object_map_get(const Evas_Object *obj)
6512 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6514 return e_map_get_from_comp_object(obj);
6518 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6520 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6522 evas_object_map_enable_set(obj, enable);
6528 e_comp_object_render_update_lock(Evas_Object *obj)
6530 E_Comp_Wl_Buffer *buffer;
6531 struct wayland_tbm_client_queue *cqueue;
6533 API_ENTRY EINA_FALSE;
6535 if (cw->render_update_lock.lock == 0)
6537 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6539 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6540 if ((buffer) && (buffer->resource))
6542 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6544 wayland_tbm_server_client_queue_flush(cqueue);
6547 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6548 e_comp_object_render_update_del(obj);
6550 ELOGF("COMP", "Render update lock enabled", cw->ec);
6553 cw->render_update_lock.lock++;
6559 e_comp_object_render_update_unlock(Evas_Object *obj)
6563 if (cw->render_update_lock.lock == 0)
6566 cw->render_update_lock.lock--;
6568 if (cw->render_update_lock.lock == 0)
6571 if (cw->render_update_lock.pending_move_set)
6573 evas_object_move(obj,
6574 cw->render_update_lock.pending_move_x,
6575 cw->render_update_lock.pending_move_y);
6576 cw->render_update_lock.pending_move_x = 0;
6577 cw->render_update_lock.pending_move_y = 0;
6578 cw->render_update_lock.pending_move_set = EINA_FALSE;
6581 if (cw->render_update_lock.pending_resize_set)
6583 evas_object_resize(obj,
6584 cw->render_update_lock.pending_resize_w,
6585 cw->render_update_lock.pending_resize_h);
6586 cw->render_update_lock.pending_resize_w = 0;
6587 cw->render_update_lock.pending_resize_h = 0;
6588 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6591 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6593 if ((cw->ec->exp_iconify.buffer_flush) &&
6594 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6595 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6596 e_comp_object_clear(obj);
6598 e_comp_object_render_update_add(obj);
6600 ELOGF("COMP", "Render update lock disabled", cw->ec);
6605 e_comp_object_render_update_lock_get(Evas_Object *obj)
6607 API_ENTRY EINA_FALSE;
6609 if (cw->render_update_lock.lock > 0)
6616 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6620 if (cw->transparent.set)
6622 if (r) *r = cw->transparent.user_r;
6623 if (g) *g = cw->transparent.user_g;
6624 if (b) *b = cw->transparent.user_b;
6625 if (a) *a = cw->transparent.user_a;
6629 evas_object_color_get(obj, r, g, b, a);
6634 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6638 evas_object_render_op_set(cw->obj, op);
6641 EINTERN Evas_Render_Op
6642 e_comp_object_render_op_get(Evas_Object *obj)
6644 API_ENTRY EVAS_RENDER_BLEND;
6646 return evas_object_render_op_get(cw->obj);
6650 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6653 wl_signal_add(&cw->events.lower, listener);
6656 #ifdef REFACTOR_DESK_AREA
6658 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6661 wl_signal_add(&cw->events.lower_done, listener);
6665 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6668 wl_signal_add(&cw->events.raise, listener);
6673 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6676 wl_signal_add(&cw->events.show, listener);
6680 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6683 wl_signal_add(&cw->events.hide, listener);
6686 #ifdef REFACTOR_DESK_AREA
6688 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6691 wl_signal_add(&cw->events.set_layer, listener);
6695 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6698 wl_signal_add(&cw->events.stack_above, listener);
6702 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6705 wl_signal_add(&cw->events.stack_below, listener);