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"
16 #include "e_pixmap_intern.h"
17 #include "e_map_intern.h"
18 #include "e_hwc_windows_intern.h"
22 = keys that return objects =
23 - E_Client: the client associated with the object (E_Client*)
24 - comp_smart_obj: cw->smart_obj (Evas_Object*)
25 - comp_obj: cw (E_Comp_Object*)
27 = keys that are bool flags =
28 - client_restack: client needs a protocol-level restack
29 - comp_override: object is triggering a nocomp override to force compositing
30 - comp_ref: object has a ref from visibility animations
31 - comp_showing: object is currently running its show animation
32 - comp_hiding: object is currently running its hiding animation
33 - comp_object: object is a compositor-created object
34 - comp_object_skip: object has a name which prohibits theme shadows
35 - comp_object-to_del: list of objects which will be deleted when this object is deleted
36 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
37 - effect_running: object is animating by external module
40 #define UPDATE_MAX 512 // same as evas
41 #define FAILURE_MAX 2 // seems reasonable
42 #define SMART_NAME "e_comp_object"
43 #define INPUT_OBJ_SMART_NAME "input_object"
45 /* for non-util functions */
46 #define API_ENTRY E_Comp_Object *cw; \
47 cw = evas_object_smart_data_get(obj); \
48 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
50 /* for util functions (obj may or may not be E_Comp_Object */
51 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
54 CRI("YOU PASSED NULL! ARGH!"); \
57 cw = evas_object_smart_data_get(obj); \
58 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
60 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
62 /* enable for lots of client size info in console output */
64 # define e_util_size_debug_set(x, y)
67 /* enable along with display-specific damage INF calls to enable render tracing
71 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
73 #define RENDER_DEBUG(...)
76 #ifdef REFACTOR_DESK_AREA
78 typedef struct _E_Comp_Object
82 int x, y, w, h; // geometry
86 E_Comp_Object_Frame client_inset;
88 Eina_Stringshare *frame_theme;
89 Eina_Stringshare *frame_name;
90 Eina_Stringshare *visibility_effect; //effect when toggling visibility
92 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
94 Evas_Object *smart_obj; // smart object
95 Evas_Object *clip; // clipper over effect object
96 Evas_Object *input_obj; // input smart object
97 Evas_Object *obj; // composite object
98 Evas_Object *frame_object; // for client frames
99 Evas_Object *shobj; // shadow object
100 Evas_Object *effect_obj; // effects object
101 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
105 } transform_bg_color;
106 Evas_Object *transform_tranp_obj;// transform transp rect obj
107 Evas_Object *default_input_obj; // default input object
108 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
109 Eina_List *obj_mirror; // extra mirror objects
110 Eina_Tiler *updates; //render update regions
111 Eina_Tiler *pending_updates; //render update regions which are about to render
113 Evas_Native_Surface *ns; //for custom gl rendering
115 struct wl_listener buffer_destroy_listener;
117 unsigned int update_count; // how many updates have happened to this obj
119 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
121 unsigned int animating; // it's busy animating
122 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
123 unsigned int force_visible; //number of visible obj_mirror objects
124 Eina_Bool delete_pending : 1; // delete pending
125 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
126 Eina_Bool showing : 1; // object is currently in "show" animation
127 Eina_Bool hiding : 1; // object is currently in "hide" animation
128 Eina_Bool visible : 1; // is visible
130 Eina_Bool shaped : 1; // is shaped
131 Eina_Bool update : 1; // has updates to fetch
132 Eina_Bool redirected : 1; // has updates to fetch
133 Eina_Bool native : 1; // native
135 Eina_Bool nocomp : 1; // nocomp applied
136 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
137 Eina_Bool real_hid : 1; // last hide was a real window unmap
139 Eina_Bool effect_set : 1; //effect_obj has a valid group
140 Eina_Bool effect_running : 1; //effect_obj is playing an animation
141 Eina_Bool effect_clip : 1; //effect_obj is clipped
142 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
144 Eina_Bool updates_exist : 1;
145 Eina_Bool updates_full : 1; // entire object will be updated
147 Eina_Bool force_move : 1;
148 Eina_Bool frame_extends : 1; //frame may extend beyond object size
149 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
150 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
151 Eina_Bool user_alpha_set : 1;
152 Eina_Bool user_alpha : 1;
156 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
157 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
164 } indicator; //indicator object for internal client
168 Evas_Object *mask_obj;
171 int mask_x, mask_y, mask_w, mask_h;
174 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
176 tbm_surface_h tbm_surface;
177 E_Comp_Image_Filter image_filter;
178 Eina_Bool set_mouse_callbacks;
183 E_Comp_Wl_Buffer_Ref buffer_ref;
184 Eina_Bool pending_move_set;
185 int pending_move_x, pending_move_y;
186 Eina_Bool pending_resize_set;
187 int pending_resize_w, pending_resize_h;
188 } render_update_lock;
201 struct wl_signal lower;
202 //#ifdef REFACTOR_DESK_AREA
203 struct wl_signal raise;
205 struct wl_signal show;
206 struct wl_signal hide;
207 //#ifdef REFACTOR_DESK_AREA
208 struct wl_signal set_layer;
209 struct wl_signal stack_above;
210 struct wl_signal stack_below;
216 typedef struct _E_Input_Rect_Data
222 typedef struct _E_Input_Rect_Smart_Data
224 Eina_List *input_rect_data_list;
226 } E_Input_Rect_Smart_Data;
228 struct E_Comp_Object_Mover
231 E_Comp_Object_Mover_Cb func;
237 static Eina_Inlist *_e_comp_object_movers = NULL;
238 static Evas_Smart *_e_comp_smart = NULL;
239 static Evas_Smart *_e_comp_input_obj_smart = NULL;
241 static int _e_comp_object_hooks_delete = 0;
242 static int _e_comp_object_hooks_walking = 0;
244 static Eina_Inlist *_e_comp_object_hooks[] =
246 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
247 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
248 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
249 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
250 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
251 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
252 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
253 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
256 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
257 static int _e_comp_object_intercept_hooks_delete = 0;
258 static int _e_comp_object_intercept_hooks_walking = 0;
260 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
262 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
263 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
267 static Eina_Bool _damage_trace = EINA_FALSE;
268 static Eina_List *_damage_trace_objs = NULL;
269 static Eina_List *_damage_trace_post_objs = NULL;
271 /* sekrit functionzzz */
272 EINTERN void e_client_focused_set(E_Client *ec);
274 /* emitted every time a new noteworthy comp object is added */
275 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
277 /* ecore event define */
278 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
279 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
280 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
282 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
283 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
284 static void _e_comp_object_dim_update(E_Comp_Object *cw);
285 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
286 #ifdef REFACTOR_DESK_AREA
288 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
291 static E_Client *dim_client = NULL;
294 _e_comp_object_hooks_clean(void)
297 E_Comp_Object_Hook *ch;
300 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
301 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
303 if (!ch->delete_me) continue;
304 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
310 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
312 E_Comp_Object_Hook *ch;
313 Eina_Bool ret = EINA_TRUE;
315 if (e_object_is_del(E_OBJECT(ec)))
317 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
318 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
319 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
320 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
321 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
322 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
323 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
324 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
330 e_object_ref(E_OBJECT(ec));
331 _e_comp_object_hooks_walking++;
332 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
334 if (ch->delete_me) continue;
335 if (!(ch->func(ch->data, ec)))
341 _e_comp_object_hooks_walking--;
342 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
343 _e_comp_object_hooks_clean();
345 e_object_unref(E_OBJECT(ec));
350 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
352 _e_comp_object_intercept_hooks_clean(void)
355 E_Comp_Object_Intercept_Hook *ch;
358 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
359 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
361 if (!ch->delete_me) continue;
362 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
368 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
370 E_Comp_Object_Intercept_Hook *ch;
371 Eina_Bool ret = EINA_TRUE;
373 if (e_object_is_del(E_OBJECT(ec))) return ret;
374 e_object_ref(E_OBJECT(ec));
375 _e_comp_object_intercept_hooks_walking++;
376 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
378 if (ch->delete_me) continue;
379 if (!(ch->func(ch->data, ec)))
385 _e_comp_object_intercept_hooks_walking--;
386 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
387 _e_comp_object_intercept_hooks_clean();
389 e_object_unref(E_OBJECT(ec));
396 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
398 E_Event_Comp_Object *ev = event;
401 ec = evas_object_data_get(ev->comp_object, "E_Client");
405 e_object_unref(E_OBJECT(ec));
407 evas_object_unref(ev->comp_object);
412 _e_comp_object_event_add(Evas_Object *obj)
414 E_Event_Comp_Object *ev;
417 if (stopping) return;
418 ev = E_NEW(E_Event_Comp_Object, 1);
419 EINA_SAFETY_ON_NULL_RETURN(ev);
421 evas_object_ref(obj);
422 ev->comp_object = obj;
423 ec = evas_object_data_get(ev->comp_object, "E_Client");
427 e_object_ref(E_OBJECT(ec));
429 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
433 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
435 E_Event_Comp_Object *ev = event;
438 ec = evas_object_data_get(ev->comp_object, "E_Client");
442 e_object_unref(E_OBJECT(ec));
444 evas_object_unref(ev->comp_object);
449 _e_comp_object_event_simple(Evas_Object *obj, int type)
451 E_Event_Comp_Object *ev;
454 ev = E_NEW(E_Event_Comp_Object, 1);
457 evas_object_ref(obj);
458 ev->comp_object = obj;
459 ec = evas_object_data_get(ev->comp_object, "E_Client");
463 e_object_ref(E_OBJECT(ec));
465 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
467 /////////////////////////////////////
470 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
472 E_Comp_Object *cw = data;
474 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
478 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
480 E_Comp_Object *cw = data;
482 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
483 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
486 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
487 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
491 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
493 E_Comp_Object *cw = data;
496 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
497 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
500 /////////////////////////////////////
502 #ifdef REFACTOR_DESK_AREA
504 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
507 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
512 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
513 if (cw->ec->input_only) return;
515 layer = evas_object_layer_get(obj);
517 if (cw->transform_bg_obj)
519 if (layer != evas_object_layer_get(cw->transform_bg_obj))
521 evas_object_layer_set(cw->transform_bg_obj, layer);
524 evas_object_stack_below(cw->transform_bg_obj, obj);
527 if (cw->transform_tranp_obj)
529 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
531 evas_object_layer_set(cw->transform_tranp_obj, layer);
534 evas_object_stack_below(cw->transform_tranp_obj, obj);
539 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
546 if (!map) return NULL;
548 e_map_util_points_populate_from_object_full(map, obj, 0);
549 e_map_util_points_color_set(map, 255, 255, 255, 255);
551 for (i = 0 ; i < 4 ; ++i)
556 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
557 e_map_point_coord_set(map, i, x, y, 1.0);
564 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
570 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
573 e_comp_object_map_set(obj, map);
574 e_comp_object_map_enable_set(obj, EINA_TRUE);
581 evas_object_map_enable_set(obj, EINA_FALSE);
586 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
592 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
595 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
597 e_comp_object_map_set(obj, map);
598 e_comp_object_map_enable_set(obj, EINA_TRUE);
605 evas_object_map_enable_set(obj, EINA_FALSE);
608 /////////////////////////////////////
610 static inline Eina_Bool
611 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
613 if (num > 1) return EINA_TRUE;
614 if ((rects[0].x == 0) && (rects[0].y == 0) &&
615 ((int)rects[0].w == w) && ((int)rects[0].h == h))
620 /////////////////////////////////////
622 /* add a client to the layer-client list */
623 #ifdef REFACTOR_DESK_AREA
626 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
628 g_rec_mutex_lock(&e_comp->ec_list_mutex);
631 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));
633 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));
634 if ((!above) && (!below))
637 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
638 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
639 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
641 e_comp->layers[cw->layer].clients_count++;
643 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
647 _e_comp_object_layers_remove(E_Comp_Object *cw)
649 g_rec_mutex_lock(&e_comp->ec_list_mutex);
651 if (cw->ec && e_comp->layers[cw->layer].clients)
653 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
654 e_comp->layers[cw->layer].clients_count--;
657 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
661 /////////////////////////////////////
663 _e_comp_object_alpha_set(E_Comp_Object *cw)
665 Eina_Bool alpha = cw->ec->argb;
667 if ((cw->external_content) &&
668 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
673 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
674 if (cw->user_alpha_set) alpha = cw->user_alpha;
676 evas_object_image_alpha_set(cw->obj, alpha);
680 _e_comp_object_shadow(E_Comp_Object *cw)
682 if (e_client_util_shadow_state_get(cw->ec))
683 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
685 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
686 if (cw->frame_object)
687 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
688 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
691 /* convert from the surface coordinates to the buffer coordinates */
693 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
695 E_Comp_Wl_Buffer_Viewport *vp;
696 E_Comp_Wl_Client_Data *cdata;
700 cdata = e_client_cdata_get(ec);
702 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
709 vp = &cdata->scaler.buffer_viewport;
710 transform = e_comp_wl_output_buffer_transform_get(ec);
712 e_pixmap_size_get(ec->pixmap, &bw, &bh);
714 /* for subsurface, it should be swap 90 and 270 */
715 if (e_comp_wl_subsurface_check(ec))
718 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
719 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
727 case WL_OUTPUT_TRANSFORM_NORMAL:
728 default: tx = sx, ty = sy; break;
729 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
730 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
731 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
732 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
733 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
734 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
735 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
738 tx *= vp->buffer.scale;
739 ty *= vp->buffer.scale;
746 _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)
754 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
755 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
762 if (dw) *dw = MAX(x1, x2) - mx;
763 if (dh) *dh = MAX(y1, y2) - my;
767 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
768 int *dx, int *dy, int *dw, int *dh)
770 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
771 E_Util_Transform_Rect_Vertex sv, dv;
775 e_pixmap_size_get(ec->pixmap, &bw, &bh);
777 sv = e_util_transform_rect_to_vertices(&rect);
779 for (i = 0; i < 4; i++)
781 double x = 0.0, y = 0.0;
783 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
785 /* if evas decide coordinate is outside of map, it returns (0, 0)
786 in this case, full damage is added.
788 if ((i != 0) && (x == 0.0) && (y == 0.0))
791 dv.vertices[i].vertex[0] = x;
792 dv.vertices[i].vertex[1] = y;
793 dv.vertices[i].vertex[2] = 1.0;
794 dv.vertices[i].vertex[3] = 1.0;
797 rect = e_util_transform_vertices_to_rect(&dv);
799 if (dx) *dx = rect.x;
800 if (dy) *dy = rect.y;
801 if (dw) *dw = rect.w;
802 if (dh) *dh = rect.h;
816 _e_comp_object_map_damage_transform_get(E_Client *ec)
823 if (!e_client_transform_core_enable_get(ec))
826 m = e_client_map_get(ec);
830 e_pixmap_size_get(ec->pixmap, &bw, &bh);
831 if ((bw == 0) || (bh == 0))
844 e_map_point_coord_set(m2, 0, 0, 0, 0);
845 e_map_point_coord_set(m2, 1, bw, 0, 0);
846 e_map_point_coord_set(m2, 2, bw, bh, 0);
847 e_map_point_coord_set(m2, 3, 0, bh, 0);
849 for (i = 0; i < 4; i++)
853 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
854 e_map_point_image_uv_set(m2, i, map_x, map_y);
861 /////////////////////////////////////
863 /* handle evas mouse-in events on client object */
865 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
867 Evas_Event_Mouse_In *ev = event_info;
868 E_Comp_Object *cw = data;
870 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
873 /* handle evas mouse-out events on client object */
875 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
877 Evas_Event_Mouse_Out *ev = event_info;
878 E_Comp_Object *cw = data;
880 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
883 /* handle evas mouse wheel events on client object */
885 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
887 Evas_Event_Mouse_Wheel *ev = event_info;
888 E_Comp_Object *cw = data;
889 E_Binding_Event_Wheel ev2;
892 if (e_client_action_get()) return;
893 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
894 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
897 /* handle evas mouse down events on client object */
899 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
901 Evas_Event_Mouse_Down *ev = event_info;
902 E_Comp_Object *cw = data;
903 E_Binding_Event_Mouse_Button ev2;
906 if (e_client_action_get()) return;
907 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
908 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
911 /* handle evas mouse up events on client object */
913 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
915 Evas_Event_Mouse_Up *ev = event_info;
916 E_Comp_Object *cw = data;
917 E_Binding_Event_Mouse_Button ev2;
920 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
921 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
922 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
925 /* handle evas mouse movement events on client object */
927 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
929 Evas_Event_Mouse_Move *ev = event_info;
930 E_Comp_Object *cw = data;
933 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
934 e_client_mouse_move(cw->ec, &ev->cur.output);
936 /////////////////////////////////////
938 /* helper function for checking compositor themes based on user-defined matches */
940 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
942 if (((m->title) && (!ec->netwm.name)) ||
943 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
945 #if defined(__cplusplus) || defined(c_plusplus)
946 if (((m->clas) && (!ec->icccm.cpp_class)) ||
947 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
950 if (((m->clas) && (!ec->icccm.class)) ||
951 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
955 if (((m->role) && (!ec->icccm.window_role)) ||
956 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
962 if ((int)ec->netwm.type != m->primary_type)
965 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
968 if (m->borderless != 0)
972 if (e_client_util_borderless(ec))
974 if (!(((m->borderless == -1) && (!borderless)) ||
975 ((m->borderless == 1) && (borderless))))
982 if (((ec->icccm.transient_for != 0) ||
985 if (!(((m->dialog == -1) && (!dialog)) ||
986 ((m->dialog == 1) && (dialog))))
989 if (m->accepts_focus != 0)
991 int accepts_focus = 0;
993 if (ec->icccm.accepts_focus)
995 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
996 ((m->accepts_focus == 1) && (accepts_focus))))
1005 if (!(((m->vkbd == -1) && (!vkbd)) ||
1006 ((m->vkbd == 1) && (vkbd))))
1011 if (!(((m->argb == -1) && (!ec->argb)) ||
1012 ((m->argb == 1) && (ec->argb))))
1015 if (m->fullscreen != 0)
1017 int fullscreen = ec->fullscreen;
1019 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1020 ((m->fullscreen == 1) && (fullscreen))))
1025 if (!(m->modal == -1))
1031 /* function for setting up a client's compositor frame theme (cw->shobj) */
1033 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1037 Eina_List *list = NULL, *l;
1038 E_Input_Rect_Data *input_rect_data;
1039 E_Input_Rect_Smart_Data *input_rect_sd;
1041 Eina_Stringshare *reshadow_group = NULL;
1042 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1043 Eina_Stringshare *name, *title;
1044 E_Comp_Config *conf = e_comp_config_get();
1046 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1047 /* match correct client type */
1048 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1049 name = cw->ec->icccm.name;
1050 title = cw->ec->icccm.title;
1051 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1052 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1054 /* skipping here is mostly a hack for systray because I hate it */
1057 EINA_LIST_FOREACH(list, l, m)
1059 if (((m->name) && (!name)) ||
1060 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1062 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1065 no_shadow = m->no_shadow;
1066 if (m->shadow_style)
1068 /* fast effects are just themes with "/fast" appended and shorter effect times */
1071 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1072 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1074 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1076 /* default to non-fast style if fast not available */
1079 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1080 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1082 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1084 if (ok && m->visibility_effect)
1085 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1092 if (skip || (cw->ec->e.state.video))
1094 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1096 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1099 if (conf->shadow_style)
1103 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1104 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1106 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1110 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1111 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1113 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1120 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1122 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1126 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1128 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1133 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1138 if (cw->ec->override)
1140 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1141 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1143 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1144 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1150 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1151 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1154 _e_comp_object_shadow(cw);
1157 if (focus || cw->ec->focused || cw->ec->override)
1158 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1160 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1162 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1165 /* visibility must always be enabled for re_manage clients to prevent
1166 * pop-in animations every time the user sees a persistent client again;
1167 * applying visibility for iconic clients prevents the client from getting
1170 if (cw->visible || cw->ec->re_manage)
1171 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1173 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1175 /* breaks animation counter */
1176 if (cw->frame_object)
1178 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1179 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1181 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1187 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1191 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1194 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1196 if (input_rect_data->obj)
1198 pass_event_flag = EINA_TRUE;
1204 if (cw->indicator.obj)
1206 Evas_Object *indicator;
1207 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1208 if (indicator != cw->indicator.obj)
1210 edje_object_part_unswallow(cw->shobj, indicator);
1211 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1212 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1216 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1217 evas_object_pass_events_set(cw->obj, pass_event_flag);
1222 /////////////////////////////////////////////
1225 _e_comp_object_animating_begin(E_Comp_Object *cw)
1228 if (cw->animating == 1)
1230 e_comp->animating++;
1232 e_object_ref(E_OBJECT(cw->ec));
1237 _e_comp_object_animating_end(E_Comp_Object *cw)
1246 if (cw->ec->launching)
1248 if (!cw->ec->extra_animating)
1250 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1251 cw->ec->launching = EINA_FALSE;
1252 if (cw->ec->first_mapped)
1254 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1255 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1258 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1262 e_comp->animating--;
1263 cw->showing = cw->hiding = 0;
1265 if (e_comp->animating == 0)
1266 e_comp_visibility_calculation_set(EINA_TRUE);
1267 /* remove ref from animation start, account for possibility of deletion from unref */
1268 return !!e_object_unref(E_OBJECT(cw->ec));
1274 /* handle the end of a compositor animation */
1276 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1278 E_Comp_Object *cw = data;
1280 /* visible clients which have never been sized are a bug */
1281 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1282 CRI("ACK! ec:%p", cw->ec);
1283 if (!_e_comp_object_animating_end(cw)) return;
1284 if (cw->animating) return;
1285 /* hide only after animation finishes to guarantee a full run of the animation */
1286 if (!cw->defer_hide) return;
1287 if ((!strcmp(emission, "e,action,hide,done")) ||
1288 (!strcmp(emission, "e,action,done")) ||
1289 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1291 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1292 evas_object_hide(cw->smart_obj);
1296 /* run a visibility compositor effect if available, return false if object is dead */
1298 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1304 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1305 if (!cw->effect_running)
1306 _e_comp_object_animating_begin(cw);
1307 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1308 return _e_comp_object_animating_end(cw);
1309 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1310 return _e_comp_object_animating_end(cw);
1312 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1315 zone = e_comp_zone_find_by_ec(cw->ec);
1317 zw = zone->w, zh = zone->h;
1322 zone = e_comp_object_util_zone_get(cw->smart_obj);
1323 if (!zone) zone = e_zone_current_get();
1330 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1331 cw->w, cw->h, zw, zh, x, y}, 8);
1332 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1333 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1336 /////////////////////////////////////////////
1338 /* create necessary objects for clients that e manages */
1340 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1342 if (cw->set_mouse_callbacks) return;
1343 if (!cw->smart_obj) return;
1345 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1346 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1348 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1350 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1352 cw->set_mouse_callbacks = EINA_TRUE;
1356 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1358 if (!cw->set_mouse_callbacks) return;
1359 if (!cw->smart_obj) return;
1361 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1362 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1364 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1366 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1368 cw->set_mouse_callbacks = EINA_FALSE;
1372 _e_comp_object_setup(E_Comp_Object *cw)
1374 cw->clip = evas_object_rectangle_add(e_comp->evas);
1375 evas_object_move(cw->clip, -9999, -9999);
1376 evas_object_resize(cw->clip, 999999, 999999);
1377 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1378 cw->effect_obj = edje_object_add(e_comp->evas);
1379 evas_object_move(cw->effect_obj, cw->x, cw->y);
1380 evas_object_clip_set(cw->effect_obj, cw->clip);
1381 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1382 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1383 cw->shobj = edje_object_add(e_comp->evas);
1384 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1385 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1386 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1388 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1389 if (cw->ec->override)
1391 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1392 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1393 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1395 else if (!cw->ec->input_only)
1397 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1398 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1399 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1401 cw->real_hid = !cw->ec->input_only;
1402 if (!cw->ec->input_only)
1404 e_util_size_debug_set(cw->effect_obj, 1);
1405 _e_comp_object_mouse_event_callback_set(cw);
1408 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1409 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1410 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1411 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1412 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1413 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1415 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1418 /////////////////////////////////////////////
1420 /* for fast path evas rendering; only called during render */
1422 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1424 E_Comp_Object *cw = data;
1425 E_Client *ec = cw->ec;
1427 int bx, by, bxx, byy;
1429 if (e_object_is_del(E_OBJECT(ec))) return;
1430 if (cw->external_content) return;
1431 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1432 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1435 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1436 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1438 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1440 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1441 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1445 bx = by = bxx = byy = 0;
1446 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1449 Edje_Message_Int_Set *msg;
1450 Edje_Message_Int msg2;
1451 Eina_Bool id = (bx || by || bxx || byy);
1453 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1459 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1461 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1465 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1466 e_comp_client_post_update_add(cw->ec);
1468 else if (e_comp_object_render(ec->frame))
1470 /* apply shape mask if necessary */
1471 if ((!cw->native) && (ec->shaped))
1472 e_comp_object_shape_apply(ec->frame);
1474 /* shaped clients get precise mouse events to handle transparent pixels */
1475 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1477 /* queue another render if client is still dirty; cannot refresh here. */
1478 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1479 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1481 if (cw->render_trace)
1483 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1489 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1491 E_Comp_Object *cw = data;
1492 E_Client *ec = cw->ec;
1494 if (e_object_is_del(E_OBJECT(ec))) return;
1495 if (cw->external_content) return;
1496 if (!e_comp->hwc) return;
1498 e_comp_client_render_list_add(cw->ec);
1500 if (!ec->hwc_window) return;
1502 e_hwc_windows_rendered_window_add(ec->hwc_window);
1505 /////////////////////////////////////////////
1508 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1510 E_Comp_Object *cw = data;
1513 if (cw->render_update_lock.lock)
1515 cw->render_update_lock.pending_move_x = x;
1516 cw->render_update_lock.pending_move_y = y;
1517 cw->render_update_lock.pending_move_set = EINA_TRUE;
1521 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1522 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1523 (cw->external_content))
1525 /* delay to move until the external content is unset */
1526 cw->ec->changes.pos = 1;
1531 if (cw->ec->move_after_resize)
1533 if ((x != cw->ec->x) || (y != cw->ec->y))
1535 if (!cw->ec->is_cursor)
1536 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1537 e_client_pos_set(cw->ec, x, y);
1538 cw->ec->changes.pos = 1;
1544 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1545 (cw->ec->manage_resize.resize_obj))
1547 e_client_pos_set(cw->ec, x, y);
1548 cw->ec->client.x = x + cw->client_inset.l;
1549 cw->ec->client.y = y + cw->client_inset.t;
1550 e_policy_visibility_client_defer_move(cw->ec);
1554 /* if frame_object does not exist, client_inset indicates CSD.
1555 * this means that ec->client matches cw->x/y, the opposite
1558 fx = (!cw->frame_object) * cw->client_inset.l;
1559 fy = (!cw->frame_object) * cw->client_inset.t;
1560 if ((cw->x == x + fx) && (cw->y == y + fy))
1562 if ((cw->ec->x != x) || (cw->ec->y != y))
1564 /* handle case where client tries to move to position and back very quickly */
1565 e_client_pos_set(cw->ec, x, y);
1566 cw->ec->client.x = x + cw->client_inset.l;
1567 cw->ec->client.y = y + cw->client_inset.t;
1571 if (!cw->ec->maximize_override)
1573 /* prevent moving in some directions while directionally maximized */
1574 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1576 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1579 ix = x + cw->client_inset.l;
1580 iy = y + cw->client_inset.t;
1581 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1582 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1583 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1585 /* prevent moving at all if move isn't allowed in current maximize state */
1586 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1587 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1590 zone = e_comp_zone_find_by_ec(cw->ec);
1593 cw->ec->changes.need_unmaximize = 1;
1594 cw->ec->saved.x = ix - zone->x;
1595 cw->ec->saved.y = iy - zone->y;
1596 cw->ec->saved.w = cw->ec->client.w;
1597 cw->ec->saved.h = cw->ec->client.h;
1601 /* only update during resize if triggered by resize */
1602 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1603 /* delay to move while surface waits paired commit serial*/
1604 if (e_client_pending_geometry_has(cw->ec))
1606 /* do nothing while waiting paired commit serial*/
1610 e_client_pos_set(cw->ec, x, y);
1611 if (cw->ec->new_client)
1613 /* don't actually do anything until first client idler loop */
1614 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1615 cw->ec->changes.pos = 1;
1620 /* only update xy position of client to avoid invalid
1621 * first damage region if it is not a new_client. */
1622 cw->ec->client.x = ix;
1623 cw->ec->client.y = iy;
1626 if (!cw->frame_object)
1628 evas_object_move(obj, x, y);
1633 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1635 E_Comp_Object *cw = data;
1636 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1639 if (cw->render_update_lock.lock)
1641 cw->render_update_lock.pending_resize_w = w;
1642 cw->render_update_lock.pending_resize_h = h;
1643 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1647 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1649 e_client_size_set(cw->ec, w, h);
1650 evas_object_resize(obj, w, h);
1654 /* if frame_object does not exist, client_inset indicates CSD.
1655 * this means that ec->client matches cw->w/h, the opposite
1658 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1659 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1660 if ((cw->w == w + fw) && (cw->h == h + fh))
1662 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1663 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1664 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1666 /* handle case where client tries to resize itself and back very quickly */
1667 e_client_size_set(cw->ec, w, h);
1668 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1669 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1670 evas_object_smart_callback_call(obj, "client_resize", NULL);
1674 /* guarantee that fullscreen is fullscreen */
1675 zone = e_comp_zone_find_by_ec(cw->ec);
1677 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1679 if (!e_client_transform_core_enable_get(cw->ec))
1682 /* calculate client size */
1683 iw = w - cw->client_inset.l - cw->client_inset.r;
1684 ih = h - cw->client_inset.t - cw->client_inset.b;
1685 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1687 /* prevent resizing while maximized depending on direction and config */
1688 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1690 Eina_Bool reject = EINA_FALSE;
1691 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1693 if (cw->ec->client.h != ih)
1695 cw->ec->saved.h = ih;
1696 cw->ec->saved.y = cw->ec->client.y - zone->y;
1697 reject = cw->ec->changes.need_unmaximize = 1;
1700 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1702 if (cw->ec->client.w != iw)
1704 cw->ec->saved.w = iw;
1705 cw->ec->saved.x = cw->ec->client.x - zone->x;
1706 reject = cw->ec->changes.need_unmaximize = 1;
1715 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1717 /* do nothing until client idler loops */
1718 if ((cw->ec->w != w) || (cw->ec->h != h))
1720 e_client_size_set(cw->ec, w, h);
1721 cw->ec->changes.size = 1;
1726 if (e_client_pending_geometry_has(cw->ec))
1728 /* do nothing while waiting paired commit serial*/
1732 e_client_size_set(cw->ec, w, h);
1734 cw->ec->client.w = iw;
1735 cw->ec->client.h = ih;
1736 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1738 /* The size of non-compositing window can be changed, so there is a
1739 * need to check that cw is H/W composited if cw is not redirected.
1740 * And of course we have to change size of evas object of H/W composited cw,
1741 * otherwise cw can't receive input events even if it is shown on the screen.
1743 Eina_Bool redirected = cw->redirected;
1745 redirected = e_comp_is_on_overlay(cw->ec);
1747 if ((!cw->ec->input_only) && (redirected) &&
1748 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1749 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1750 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1751 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1754 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1755 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1757 prev_w = cw->w, prev_h = cw->h;
1758 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1759 /* check shading and clamp to pixmap size for regular clients */
1760 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1761 (((w - fw != pw) || (h - fh != ph))))
1763 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1764 evas_object_smart_callback_call(obj, "client_resize", NULL);
1766 if (cw->frame_object || cw->ec->input_only)
1767 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1770 if ((cw->w == w) && (cw->h == h))
1772 /* going to be a noop resize which won't trigger smart resize */
1773 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1774 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1776 evas_object_resize(obj, w, h);
1780 evas_object_smart_callback_call(obj, "client_resize", NULL);
1783 if ((!cw->frame_object) && (!cw->ec->input_only))
1785 /* "just do it" for overrides */
1786 evas_object_resize(obj, w, h);
1788 if (!cw->ec->override)
1790 /* shape probably changed for non-overrides */
1795 /* this fixes positioning jiggles when using a resize mode
1796 * which also changes the client's position
1799 if (cw->frame_object)
1800 x = cw->x, y = cw->y;
1802 x = cw->ec->x, y = cw->ec->y;
1803 switch (cw->ec->resize_mode)
1805 case E_POINTER_RESIZE_BL:
1806 case E_POINTER_RESIZE_L:
1807 evas_object_move(obj, x + prev_w - cw->w, y);
1809 case E_POINTER_RESIZE_TL:
1810 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1812 case E_POINTER_RESIZE_T:
1813 case E_POINTER_RESIZE_TR:
1814 evas_object_move(obj, x, y + prev_h - cw->h);
1823 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1825 #ifdef REFACTOR_DESK_AREA
1826 E_Comp_Object *cw = data;
1827 E_Comp_Object_Data_Set_Layer layer_set_data;
1829 layer_set_data.cw = cw;
1830 layer_set_data.layer = layer;
1832 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1836 e_comp_render_queue();
1837 _e_comp_object_transform_obj_stack_update(obj);
1841 E_Comp_Object *cw = data;
1842 E_Comp_Wl_Client_Data *child_cdata;
1843 unsigned int l = e_comp_canvas_layer_map(layer);
1846 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1848 /* doing a compositor effect, follow directions */
1849 _e_comp_object_layer_set(obj, layer);
1850 if (layer == cw->ec->layer) //trying to put layer back
1854 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1855 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1856 if (cw->layer != l) goto layer_set;
1860 e_comp_render_queue();
1862 ec = e_client_above_get(cw->ec);
1863 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1864 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1865 ec = e_client_above_get(ec);
1866 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1868 ec = e_client_below_get(cw->ec);
1869 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1870 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1871 ec = e_client_below_get(ec);
1872 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1874 evas_object_stack_above(obj, ec->frame);
1879 if (ec && (cw->ec->parent == ec))
1881 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1882 evas_object_stack_above(obj, ec->frame);
1884 evas_object_stack_below(obj, ec->frame);
1887 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1893 if (cw->layer == l) return;
1894 if (e_comp_canvas_client_layer_map(layer) == 9999)
1895 return; //invalid layer for clients not doing comp effects
1896 if (cw->ec->fullscreen)
1898 cw->ec->saved.layer = layer;
1901 oldraise = e_config->transient.raise;
1903 /* clamp to valid client layer */
1904 layer = e_comp_canvas_client_layer_map_nearest(layer);
1905 cw->ec->layer = layer;
1906 if (e_config->transient.layer)
1909 Eina_List *list = eina_list_clone(cw->ec->transients);
1911 /* We need to set raise to one, else the child wont
1912 * follow to the new layer. It should be like this,
1913 * even if the user usually doesn't want to raise
1916 e_config->transient.raise = 1;
1917 EINA_LIST_FREE(list, child)
1919 child_cdata = e_client_cdata_get(child);
1920 if (child_cdata && !child_cdata->mapped)
1922 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1925 e_client_layer_set(child, layer);
1929 e_config->transient.raise = oldraise;
1931 _e_comp_object_layers_remove(cw);
1932 cw->layer = e_comp_canvas_layer_map(layer);
1933 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1934 //if (cw->ec->new_client)
1935 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1936 _e_comp_object_layer_set(obj, layer);
1937 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1938 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1939 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1941 /* can't stack a client above its own layer marker */
1942 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1944 if (!cw->visible) return;
1945 e_comp_render_queue();
1946 _e_comp_object_transform_obj_stack_update(obj);
1950 #ifdef REFACTOR_DESK_AREA
1952 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1955 #ifdef REFACTOR_DESK_AREA
1957 _e_comp_object_raise(Evas_Object *obj)
1960 _e_comp_object_raise(Evas_Object *obj)
1963 evas_object_raise(obj);
1965 if (evas_object_smart_smart_get(obj))
1967 E_Client *ec = e_comp_object_client_get(obj);
1969 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1973 #ifdef REFACTOR_DESK_AREA
1975 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1978 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1981 evas_object_lower(obj);
1983 if (evas_object_smart_smart_get(obj))
1985 E_Client *ec = e_comp_object_client_get(obj);
1988 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1989 #ifdef REFACTOR_DESK_AREA
1990 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1992 wl_signal_emit_mutable(&cw->events.lower, NULL);
1998 #ifdef REFACTOR_DESK_AREA
2000 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2003 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2006 evas_object_stack_above(obj, target);
2008 if (evas_object_smart_smart_get(obj))
2010 E_Client *ec = e_comp_object_client_get(obj);
2012 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2016 #ifdef REFACTOR_DESK_AREA
2018 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2021 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2024 evas_object_stack_below(obj, target);
2026 if (evas_object_smart_smart_get(obj))
2028 E_Client *ec = e_comp_object_client_get(obj);
2030 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2034 #ifdef REFACTOR_DESK_AREA
2036 e_comp_object_layer_set(Evas_Object *obj, short layer)
2039 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2042 evas_object_layer_set(obj, layer);
2044 if (evas_object_smart_smart_get(obj))
2046 E_Client *ec = e_comp_object_client_get(obj);
2048 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2052 #ifdef REFACTOR_DESK_AREA
2055 _e_comp_object_is_pending(E_Client *ec)
2059 if (!ec) return EINA_FALSE;
2061 topmost = e_comp_wl_topmost_parent_get(ec);
2063 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2067 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2069 E_Comp_Object *cw2 = NULL;
2072 Evas_Object *o = stack;
2073 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2075 /* We should consider topmost's layer_pending for subsurface */
2076 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2078 if (_e_comp_object_is_pending(cw->ec))
2079 e_comp_object_layer_update(cw->smart_obj,
2080 raising? stack : NULL,
2081 raising? NULL : stack);
2083 /* obey compositor effects! */
2084 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2085 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2086 stack_cb(cw->smart_obj, stack);
2087 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2088 evas_object_data_del(cw->smart_obj, "client_restack");
2092 cw2 = evas_object_data_get(o, "comp_obj");
2094 /* assume someone knew what they were doing during client init */
2095 if (cw->ec->new_client)
2096 layer = cw->ec->layer;
2097 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2098 layer = cw2->ec->layer;
2100 layer = evas_object_layer_get(stack);
2101 ecstack = e_client_below_get(cw->ec);
2102 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2104 evas_object_layer_set(cw->smart_obj, layer);
2105 /* we got our layer wrangled, return now! */
2106 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2109 /* check if we're stacking below another client */
2112 /* check for non-client layer object */
2113 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2115 /* find an existing client to use for layering
2116 * by walking up the object stack
2118 * this is guaranteed to be pretty quick since we'll either:
2119 * - run out of client layers
2120 * - find a stacking client
2122 o = evas_object_above_get(o);
2123 if ((!o) || (o == cw->smart_obj)) break;
2124 if (evas_object_layer_get(o) != layer)
2126 /* reached the top client layer somehow
2127 * use top client object
2129 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2132 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2133 * return here since the top client layer window
2138 ec = e_client_top_get();
2143 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2146 if (cw2 && cw->layer != cw2->layer)
2149 /* remove existing layers */
2150 _e_comp_object_layers_remove(cw);
2153 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2154 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2155 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2156 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2157 else //if no stacking objects found, either raise or lower
2158 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2161 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2163 /* find new object for stacking if cw2 is on state of layer_pending */
2164 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2166 E_Client *new_stack = NULL, *current_ec = NULL;
2167 current_ec = cw2->ec;
2170 while ((new_stack = e_client_below_get(current_ec)))
2172 current_ec = new_stack;
2173 if (new_stack == cw->ec) continue;
2174 if (new_stack->layer != cw2->ec->layer) break;
2175 if (!_e_comp_object_is_pending(new_stack)) break;
2177 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2178 stack = new_stack->frame;
2181 /* stack it above layer object */
2183 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2184 stack = e_comp->layers[below_layer].obj;
2189 while ((new_stack = e_client_above_get(current_ec)))
2191 current_ec = new_stack;
2192 if (new_stack == cw->ec) continue;
2193 if (new_stack->layer != cw2->ec->layer) break;
2194 if (!_e_comp_object_is_pending(new_stack)) break;
2196 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2197 stack = new_stack->frame;
2199 stack = e_comp->layers[cw2->layer].obj;
2203 /* set restack if stacking has changed */
2204 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2205 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2206 stack_cb(cw->smart_obj, stack);
2207 if (e_comp->layers[cw->layer].obj)
2208 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2210 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2212 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2213 evas_object_data_del(cw->smart_obj, "client_restack");
2214 if (!cw->visible) return;
2215 e_comp_render_queue();
2220 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2222 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2224 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2226 #ifdef REFACTOR_DESK_AREA
2227 E_Comp_Object *cw = data;
2228 E_Comp_Object_Data_Stack_Above stack_above_data;
2230 stack_above_data.cw = cw;
2231 stack_above_data.above_obj = above;
2233 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2235 if (evas_object_below_get(obj) == above)
2237 e_comp_object_layer_update(obj, above, NULL);
2241 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2243 _e_comp_object_transform_obj_stack_update(obj);
2244 _e_comp_object_transform_obj_stack_update(above);
2251 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2253 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2255 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2257 #ifdef REFACTOR_DESK_AREA
2258 E_Comp_Object *cw = data;
2259 E_Comp_Object_Data_Stack_Below stack_below_data;
2261 stack_below_data.cw = cw;
2262 stack_below_data.below_obj = below;
2264 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2267 e_comp_render_queue();
2269 if (evas_object_above_get(obj) == below)
2271 e_comp_object_layer_update(obj, NULL, below);
2275 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2277 if (evas_object_smart_smart_get(obj))
2278 _e_comp_object_transform_obj_stack_update(obj);
2279 if (evas_object_smart_smart_get(below))
2280 _e_comp_object_transform_obj_stack_update(below);
2287 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2289 E_Comp_Object *cw = data;
2291 #ifdef REFACTOR_DESK_AREA
2296 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2298 #ifdef REFACTOR_DESK_AREA
2299 wl_signal_emit_mutable(&cw->events.lower, cw);
2301 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2303 if (cw->ec->layer_pending)
2304 e_comp_object_layer_update(obj, NULL, obj);
2306 _e_comp_object_lower(cw, obj);
2309 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2310 o = evas_object_below_get(obj);
2311 _e_comp_object_layers_remove(cw);
2312 /* prepend to client list since this client should be the first item now */
2313 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2314 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2315 evas_object_data_set(obj, "client_restack", (void*)1);
2316 _e_comp_object_lower(cw, obj);
2317 evas_object_data_del(obj, "client_restack");
2318 if (!cw->visible) goto end;
2319 e_comp_render_queue();
2320 _e_comp_object_transform_obj_stack_update(obj);
2328 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2330 E_Comp_Object *cw = data;
2331 #ifdef REFACTOR_DESK_AREA
2337 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2339 #ifdef REFACTOR_DESK_AREA
2340 wl_signal_emit_mutable(&cw->events.raise, cw);
2342 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2344 if (cw->ec->layer_pending)
2346 int obj_layer = evas_object_layer_get(obj);
2347 if (cw->ec->layer != obj_layer)
2348 e_comp_object_layer_update(obj, NULL, NULL);
2351 _e_comp_object_raise(obj);
2354 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2355 o = evas_object_above_get(obj);
2356 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2358 /* still stack below override below the layer marker */
2359 for (op = o = e_comp->layers[cw->layer].obj;
2360 o && o != e_comp->layers[cw->layer - 1].obj;
2361 op = o, o = evas_object_below_get(o))
2363 if (evas_object_smart_smart_get(o))
2367 ec = e_comp_object_client_get(o);
2368 if (ec && (!ec->override)) break;
2371 _e_comp_object_stack_below(obj, op);
2372 e_client_focus_defer_set(cw->ec);
2374 if (!cw->visible) goto end;
2375 e_comp_render_queue();
2376 _e_comp_object_transform_obj_stack_update(obj);
2384 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2386 E_Comp_Object *cw = data;
2388 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2389 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2391 ELOGF("COMP", "Hide. intercepted", cw->ec);
2396 if (cw->ec->launching == EINA_TRUE)
2398 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2399 cw->ec->launching = EINA_FALSE;
2404 /* hidden flag = just do it */
2405 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2406 evas_object_hide(obj);
2408 wl_signal_emit_mutable(&cw->events.hide, NULL);
2413 if (cw->ec->input_only)
2415 /* input_only = who cares */
2416 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2417 evas_object_hide(obj);
2419 wl_signal_emit_mutable(&cw->events.hide, NULL);
2423 /* already hidden or currently animating */
2424 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2426 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2430 /* don't try hiding during shutdown */
2431 cw->defer_hide |= stopping;
2432 if (!cw->defer_hide)
2434 if ((!cw->ec->iconic) && (!cw->ec->override))
2435 /* unset delete requested so the client doesn't break */
2436 cw->ec->delete_requested = 0;
2437 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2439 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2440 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2443 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2446 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2448 _e_comp_object_animating_begin(cw);
2449 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2451 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2452 cw->defer_hide = !!cw->animating;
2454 e_comp_object_effect_set(obj, NULL);
2457 if (cw->animating) return;
2458 /* if we have no animations running, go ahead and hide */
2460 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2461 evas_object_hide(obj);
2463 wl_signal_emit_mutable(&cw->events.hide, NULL);
2467 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2469 E_Client *ec = cw->ec;
2472 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2474 if (ec->show_pending.count > 0)
2476 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2477 ec->show_pending.running = EINA_TRUE;
2481 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2482 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2484 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2489 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,
2490 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2491 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2494 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2497 if (ec->iconic && cw->animating)
2499 /* triggered during iconify animation */
2500 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2503 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2506 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2507 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2509 evas_object_move(cw->smart_obj, ec->x, ec->y);
2510 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2511 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2513 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2514 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2517 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2518 evas_object_show(cw->smart_obj);
2521 e_client_focus_defer_set(ec);
2525 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2529 pw = ec->client.w, ph = ec->client.h;
2531 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2533 ec->changes.visible = !ec->hidden;
2536 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2540 cw->updates = eina_tiler_new(pw, ph);
2543 ec->changes.visible = !ec->hidden;
2546 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2551 eina_tiler_tile_size_set(cw->updates, 1, 1);
2554 /* ignore until client idler first run */
2555 ec->changes.visible = !ec->hidden;
2558 ELOGF("COMP", "show_helper. return. new_client", ec);
2565 evas_object_move(cw->smart_obj, ec->x, ec->y);
2566 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2567 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2568 evas_object_show(cw->smart_obj);
2571 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2573 /* start_drag not received */
2574 ec->changes.visible = 1;
2577 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2580 /* re-set geometry */
2581 evas_object_move(cw->smart_obj, ec->x, ec->y);
2582 /* force resize in case it hasn't happened yet, or just to update size */
2583 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2584 if ((cw->w < 1) || (cw->h < 1))
2586 /* if resize didn't go through, try again */
2587 ec->visible = ec->changes.visible = 1;
2589 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2592 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2593 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2594 e_pixmap_clear(ec->pixmap);
2596 if (cw->real_hid && w && h)
2599 /* force comp theming in case it didn't happen already */
2600 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2601 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2602 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2605 /* only do the show if show is allowed */
2608 if (ec->internal) //internal clients render when they feel like it
2609 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2611 if (!e_client_is_iconified_by_client(ec)||
2612 e_policy_visibility_client_is_uniconic(ec))
2614 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2615 evas_object_show(cw->smart_obj);
2617 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2618 it is rendered in idle callback without native surface and
2619 compositor shows an empty frame if other objects aren't shown
2620 because job callback of e_comp called at the next loop.
2621 it causes a visual defect when windows are switched.
2625 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2626 e_comp_object_dirty(cw->smart_obj);
2627 e_comp_object_render(cw->smart_obj);
2632 wl_signal_emit_mutable(&cw->events.show, NULL);
2636 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2638 E_Comp_Object *cw = data;
2639 E_Client *ec = cw->ec;
2641 E_Input_Rect_Data *input_rect_data;
2642 E_Input_Rect_Smart_Data *input_rect_sd;
2645 if (ec->ignored) return;
2649 //INF("SHOW2 %p", ec);
2650 _e_comp_intercept_show_helper(cw);
2653 //INF("SHOW %p", ec);
2656 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2657 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2658 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2659 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2663 if ((!cw->obj) && (cw->external_content))
2665 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2669 _e_comp_object_setup(cw);
2672 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2673 cw->obj = evas_object_image_filled_add(e_comp->evas);
2674 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2675 e_util_size_debug_set(cw->obj, 1);
2676 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2677 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2678 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2679 evas_object_name_set(cw->obj, "cw->obj");
2680 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2682 _e_comp_object_alpha_set(cw);
2685 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2688 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2689 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2692 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2695 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2697 if (input_rect_data->obj)
2699 evas_object_geometry_set(input_rect_data->obj,
2700 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2701 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2702 input_rect_data->rect.w, input_rect_data->rect.h);
2709 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2711 _e_comp_intercept_show_helper(cw);
2715 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2717 E_Comp_Object *cw = data;
2721 /* note: this is here as it seems there are enough apps that do not even
2722 * expect us to emulate a look of focus but not actually set x input
2723 * focus as we do - so simply abort any focus set on such windows */
2724 /* be strict about accepting focus hint */
2725 /* be strict about accepting focus hint */
2726 if ((!ec->icccm.accepts_focus) &&
2727 (!ec->icccm.take_focus))
2731 if (e_client_focused_get() == ec)
2732 e_client_focused_set(NULL);
2734 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2735 evas_object_focus_set(obj, focus);
2739 if (focus && ec->lock_focus_out) return;
2740 if (e_object_is_del(E_OBJECT(ec)) && focus)
2741 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2743 /* filter focus setting based on current state */
2748 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2749 evas_object_focus_set(obj, focus);
2752 if ((ec->iconic) && (!ec->deskshow))
2754 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2756 /* don't focus an iconified window. that's silly! */
2757 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2758 e_client_uniconify(ec);
2759 e_client_focus_latest_set(ec);
2773 /* not yet visible, wait till the next time... */
2774 ec->want_focus = !ec->hidden;
2779 e_client_focused_set(ec);
2783 if (e_client_focused_get() == ec)
2784 e_client_focused_set(NULL);
2788 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2790 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2792 evas_object_focus_set(obj, focus);
2796 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2798 E_Comp_Object *cw = data;
2800 if (cw->transparent.set)
2802 cw->transparent.user_r = r;
2803 cw->transparent.user_g = g;
2804 cw->transparent.user_b = b;
2805 cw->transparent.user_a = a;
2807 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2809 cw->transparent.user_r,
2810 cw->transparent.user_g,
2811 cw->transparent.user_b,
2812 cw->transparent.user_a);
2816 evas_object_color_set(obj, r, g, b, a);
2819 ////////////////////////////////////////////////////
2822 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2824 int w, h, ox, oy, ow, oh;
2826 Eina_Bool pass_event_flag = EINA_FALSE;
2827 E_Input_Rect_Data *input_rect_data;
2828 E_Input_Rect_Smart_Data *input_rect_sd;
2830 if (cw->frame_object)
2832 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2833 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2834 /* set a fixed size, force edje calc, check size difference */
2835 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2836 edje_object_message_signal_process(cw->frame_object);
2837 edje_object_calc_force(cw->frame_object);
2838 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2839 cw->client_inset.l = ox;
2840 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2841 cw->client_inset.t = oy;
2842 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2843 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2844 evas_object_resize(cw->frame_object, w, h);
2848 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2851 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2853 if (input_rect_data->obj)
2855 pass_event_flag = EINA_TRUE;
2861 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2862 evas_object_pass_events_set(cw->obj, pass_event_flag);
2866 cw->client_inset.l = 0;
2867 cw->client_inset.r = 0;
2868 cw->client_inset.t = 0;
2869 cw->client_inset.b = 0;
2871 cw->client_inset.calc = !!cw->frame_object;
2875 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2877 E_Comp_Object *cw = data;
2881 /* - get current size
2883 * - readjust for new frame size
2886 w = cw->ec->w, h = cw->ec->h;
2887 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2889 _e_comp_object_frame_recalc(cw);
2891 if (!cw->ec->fullscreen)
2892 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2894 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2895 if (cw->ec->fullscreen)
2897 zone = e_comp_zone_find_by_ec(cw->ec);
2899 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2901 else if (cw->ec->new_client)
2903 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2904 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2905 evas_object_resize(cw->ec->frame, w, h);
2907 else if ((w != cw->ec->w) || (h != cw->ec->h))
2908 evas_object_resize(cw->ec->frame, w, h);
2912 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2914 E_Comp_Object *cw = data;
2916 _e_comp_object_shadow_setup(cw);
2917 if (cw->frame_object)
2919 _e_comp_object_shadow(cw);
2920 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2921 _e_comp_object_frame_recalc(cw);
2922 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2927 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2929 E_Comp_Object *cw = data;
2931 if (_e_comp_object_shadow_setup(cw))
2932 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2933 if (cw->frame_object)
2935 _e_comp_object_shadow(cw);
2936 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2937 _e_comp_object_frame_recalc(cw);
2938 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2943 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2945 E_Comp_Object *cw = data;
2947 if (cw->frame_object)
2949 _e_comp_object_shadow(cw);
2950 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2951 _e_comp_object_frame_recalc(cw);
2952 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2957 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2959 E_Comp_Object *cw = data;
2961 if (_e_comp_object_shadow_setup(cw))
2964 cw->ec->changes.size = 1;
2966 if (cw->frame_object)
2968 _e_comp_object_shadow(cw);
2969 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2970 _e_comp_object_frame_recalc(cw);
2971 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2976 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2978 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2982 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2984 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2988 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2990 E_Comp_Object *cw = data;
2992 if (!cw->ec) return; //NYI
2993 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2997 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2999 E_Comp_Object *cw = data;
3001 if (!cw->ec) return; //NYI
3002 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3006 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3008 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3012 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3014 E_Comp_Object *cw = data;
3016 if (!e_object_is_del(E_OBJECT(cw->ec)))
3017 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3021 _e_comp_input_obj_smart_add(Evas_Object *obj)
3023 E_Input_Rect_Smart_Data *input_rect_sd;
3024 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3026 if (!input_rect_sd) return;
3027 evas_object_smart_data_set(obj, input_rect_sd);
3031 _e_comp_input_obj_smart_del(Evas_Object *obj)
3033 E_Input_Rect_Smart_Data *input_rect_sd;
3034 E_Input_Rect_Data *input_rect_data;
3036 input_rect_sd = evas_object_smart_data_get(obj);
3037 if (!input_rect_sd) return;
3039 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3041 if (input_rect_data->obj)
3043 evas_object_smart_member_del(input_rect_data->obj);
3044 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3046 E_FREE(input_rect_data);
3048 E_FREE(input_rect_sd);
3052 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3054 E_Input_Rect_Smart_Data *input_rect_sd;
3055 E_Input_Rect_Data *input_rect_data;
3059 input_rect_sd = evas_object_smart_data_get(obj);
3060 if (!input_rect_sd) return;
3062 cw = input_rect_sd->cw;
3063 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3065 if (input_rect_data->obj)
3067 evas_object_geometry_set(input_rect_data->obj,
3068 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3069 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3070 input_rect_data->rect.w, input_rect_data->rect.h);
3076 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3078 E_Input_Rect_Smart_Data *input_rect_sd;
3079 E_Input_Rect_Data *input_rect_data;
3083 input_rect_sd = evas_object_smart_data_get(obj);
3084 if (!input_rect_sd) return;
3086 cw = input_rect_sd->cw;
3087 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3089 if (input_rect_data->obj)
3091 evas_object_geometry_set(input_rect_data->obj,
3092 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3093 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3094 input_rect_data->rect.w, input_rect_data->rect.h);
3100 _e_comp_input_obj_smart_show(Evas_Object *obj)
3102 E_Input_Rect_Smart_Data *input_rect_sd;
3103 E_Input_Rect_Data *input_rect_data;
3106 input_rect_sd = evas_object_smart_data_get(obj);
3107 if (!input_rect_sd) return;
3109 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3111 if (input_rect_data->obj)
3113 evas_object_show(input_rect_data->obj);
3119 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3121 E_Input_Rect_Smart_Data *input_rect_sd;
3122 E_Input_Rect_Data *input_rect_data;
3125 input_rect_sd = evas_object_smart_data_get(obj);
3126 if (!input_rect_sd) return;
3128 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3130 if (input_rect_data->obj)
3132 evas_object_hide(input_rect_data->obj);
3138 _e_comp_input_obj_smart_init(void)
3140 if (_e_comp_input_obj_smart) return;
3142 static const Evas_Smart_Class sc =
3144 INPUT_OBJ_SMART_NAME,
3145 EVAS_SMART_CLASS_VERSION,
3146 _e_comp_input_obj_smart_add,
3147 _e_comp_input_obj_smart_del,
3148 _e_comp_input_obj_smart_move,
3149 _e_comp_input_obj_smart_resize,
3150 _e_comp_input_obj_smart_show,
3151 _e_comp_input_obj_smart_hide,
3164 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3170 _e_comp_smart_add(Evas_Object *obj)
3174 cw = E_NEW(E_Comp_Object, 1);
3175 EINA_SAFETY_ON_NULL_RETURN(cw);
3177 wl_signal_init(&cw->events.lower);
3178 #ifdef REFACTOR_DESK_AREA
3179 wl_signal_init(&cw->events.lower_done);
3180 wl_signal_init(&cw->events.raise);
3182 wl_signal_init(&cw->events.show);
3183 wl_signal_init(&cw->events.hide);
3184 #ifdef REFACTOR_DESK_AREA
3185 wl_signal_init(&cw->events.set_layer);
3186 wl_signal_init(&cw->events.stack_above);
3187 wl_signal_init(&cw->events.stack_below);
3190 cw->smart_obj = obj;
3191 cw->x = cw->y = cw->w = cw->h = -1;
3192 evas_object_smart_data_set(obj, cw);
3193 cw->opacity = 255.0;
3194 cw->external_content = 0;
3195 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3196 cw->transform_bg_color.r = 0;
3197 cw->transform_bg_color.g = 0;
3198 cw->transform_bg_color.b = 0;
3199 cw->transform_bg_color.a = 255;
3200 evas_object_data_set(obj, "comp_obj", cw);
3201 evas_object_move(obj, -1, -1);
3202 /* intercept ALL the callbacks! */
3203 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3204 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3205 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3206 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3207 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3208 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3209 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3210 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3211 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3212 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3213 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3215 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3216 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3217 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3218 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3220 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3221 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3223 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3224 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3226 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3228 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3229 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3233 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3236 evas_object_color_set(cw->clip, r, g, b, a);
3237 evas_object_smart_callback_call(obj, "color_set", NULL);
3242 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3245 evas_object_clip_set(cw->clip, clip);
3249 _e_comp_smart_clip_unset(Evas_Object *obj)
3252 evas_object_clip_unset(cw->clip);
3256 _e_comp_smart_hide(Evas_Object *obj)
3258 TRACE_DS_BEGIN(COMP:SMART HIDE);
3263 evas_object_hide(cw->clip);
3264 if (cw->input_obj) evas_object_hide(cw->input_obj);
3265 evas_object_hide(cw->effect_obj);
3266 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3267 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3268 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3275 /* unset native surface if current displaying buffer was destroied */
3276 if (!cw->buffer_destroy_listener.notify)
3278 Evas_Native_Surface *ns;
3279 ns = evas_object_image_native_surface_get(cw->obj);
3280 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3281 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3284 if (!cw->ec->input_only)
3286 edje_object_freeze(cw->effect_obj);
3287 edje_object_freeze(cw->shobj);
3288 edje_object_play_set(cw->shobj, 0);
3289 if (cw->frame_object)
3290 edje_object_play_set(cw->frame_object, 0);
3293 e_comp_render_queue(); //force nocomp recheck
3299 _e_comp_smart_show(Evas_Object *obj)
3307 if ((cw->w < 0) || (cw->h < 0))
3308 CRI("ACK! ec:%p", cw->ec);
3310 TRACE_DS_BEGIN(COMP:SMART SHOW);
3312 e_comp_object_map_update(obj);
3314 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3315 evas_object_show(tmp->frame);
3317 evas_object_show(cw->clip);
3318 if (cw->input_obj) evas_object_show(cw->input_obj);
3319 if (!cw->ec->input_only)
3321 edje_object_thaw(cw->effect_obj);
3322 edje_object_thaw(cw->shobj);
3323 edje_object_play_set(cw->shobj, 1);
3324 if (cw->frame_object)
3325 edje_object_play_set(cw->frame_object, 1);
3327 evas_object_show(cw->effect_obj);
3328 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3329 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3330 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3331 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3332 e_comp_render_queue();
3333 if (cw->ec->input_only)
3338 if (cw->ec->iconic && (!cw->ec->new_client))
3340 if (e_client_is_iconified_by_client(cw->ec))
3342 ELOGF("COMP", "Set launching flag..", cw->ec);
3343 cw->ec->launching = EINA_TRUE;
3346 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3348 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3351 ELOGF("COMP", "Set launching flag..", cw->ec);
3352 cw->ec->launching = EINA_TRUE;
3354 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3355 _e_comp_object_animating_begin(cw);
3356 if (!_e_comp_object_effect_visibility_start(cw, 1))
3362 /* ensure some random effect doesn't lock the client offscreen */
3366 e_comp_object_effect_set(obj, NULL);
3369 _e_comp_object_dim_update(cw);
3375 _e_comp_smart_del(Evas_Object *obj)
3381 if (cw->buffer_destroy_listener.notify)
3383 wl_list_remove(&cw->buffer_destroy_listener.link);
3384 cw->buffer_destroy_listener.notify = NULL;
3387 if (cw->tbm_surface)
3389 tbm_surface_internal_unref(cw->tbm_surface);
3390 cw->tbm_surface = NULL;
3393 if (cw->render_update_lock.buffer_ref.buffer)
3395 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3396 cw->ec, cw->render_update_lock.lock);
3397 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3400 e_comp_object_render_update_del(cw->smart_obj);
3401 E_FREE_FUNC(cw->updates, eina_tiler_free);
3402 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3409 EINA_LIST_FREE(cw->obj_mirror, o)
3411 evas_object_image_data_set(o, NULL);
3412 evas_object_freeze_events_set(o, 1);
3413 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3417 #ifdef REFACTOR_DESK_AREA
3419 _e_comp_object_layers_remove(cw);
3421 l = evas_object_data_get(obj, "comp_object-to_del");
3422 E_FREE_LIST(l, evas_object_del);
3423 _e_comp_object_mouse_event_callback_unset(cw);
3424 evas_object_del(cw->clip);
3425 evas_object_del(cw->obj);
3426 evas_object_del(cw->shobj);
3427 evas_object_del(cw->effect_obj);
3428 evas_object_del(cw->frame_object);
3429 evas_object_del(cw->input_obj);
3430 evas_object_del(cw->mask.obj);
3431 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3432 evas_object_del(cw->transform_bg_obj);
3433 evas_object_del(cw->transform_tranp_obj);
3434 evas_object_del(cw->default_input_obj);
3435 eina_stringshare_del(cw->frame_theme);
3436 eina_stringshare_del(cw->frame_name);
3440 e_comp->animating--;
3442 e_object_unref(E_OBJECT(cw->ec));
3444 cw->ec->frame = NULL;
3449 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3453 cw->x = x, cw->y = y;
3454 evas_object_move(cw->effect_obj, x, y);
3455 evas_object_move(cw->default_input_obj, x, y);
3456 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3458 e_comp_object_map_update(obj);
3462 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3464 Eina_Bool first = EINA_FALSE;
3469 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3471 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3473 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3475 if (cw->w != w || cw->h != h)
3476 e_comp_object_map_update(obj);
3478 first = ((cw->w < 1) || (cw->h < 1));
3479 cw->w = w, cw->h = h;
3483 if (cw->frame_object)
3484 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3487 /* verify pixmap:object size */
3488 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3490 if ((ww != pw) || (hh != ph))
3491 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3493 evas_object_resize(cw->effect_obj, tw, th);
3494 evas_object_resize(cw->default_input_obj, w, h);
3496 evas_object_resize(cw->input_obj, w, h);
3498 evas_object_resize(cw->mask.obj, w, h);
3499 /* resize render update tiler */
3502 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3503 cw->updates_full = 0;
3504 if (cw->updates) eina_tiler_clear(cw->updates);
3508 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3509 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3517 e_comp_render_queue();
3523 _e_comp_smart_init(void)
3525 if (_e_comp_smart) return;
3527 static const Evas_Smart_Class sc =
3530 EVAS_SMART_CLASS_VERSION,
3534 _e_comp_smart_resize,
3537 _e_comp_smart_color_set,
3538 _e_comp_smart_clip_set,
3539 _e_comp_smart_clip_unset,
3549 _e_comp_smart = evas_smart_class_new(&sc);
3554 e_comp_object_init(void)
3556 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3557 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3558 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3559 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3563 e_comp_object_shutdown(void)
3569 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3571 API_ENTRY EINA_FALSE;
3572 return !!cw->force_visible;
3574 /////////////////////////////////////////////////////////
3577 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3580 Eina_Bool comp_object;
3582 comp_object = !!evas_object_data_get(obj, "comp_object");
3587 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3589 e_comp_render_queue();
3591 l = evas_object_data_get(obj, "comp_object-to_del");
3592 E_FREE_LIST(l, evas_object_del);
3596 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3598 if (e_comp_util_object_is_above_nocomp(obj) &&
3599 (!evas_object_data_get(obj, "comp_override")))
3601 evas_object_data_set(obj, "comp_override", (void*)1);
3602 e_comp_override_add();
3607 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3609 Eina_Bool ref = EINA_TRUE;
3610 if (evas_object_visible_get(obj))
3614 d = evas_object_data_del(obj, "comp_hiding");
3616 /* currently trying to hide */
3619 /* already visible */
3623 evas_object_show(obj);
3626 evas_object_ref(obj);
3627 evas_object_data_set(obj, "comp_ref", (void*)1);
3629 edje_object_signal_emit(obj, "e,state,visible", "e");
3630 evas_object_data_set(obj, "comp_showing", (void*)1);
3631 if (e_comp_util_object_is_above_nocomp(obj))
3633 evas_object_data_set(obj, "comp_override", (void*)1);
3634 e_comp_override_add();
3639 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3641 if (!evas_object_visible_get(obj)) return;
3642 /* already hiding */
3643 if (evas_object_data_get(obj, "comp_hiding")) return;
3644 if (!evas_object_data_del(obj, "comp_showing"))
3646 evas_object_ref(obj);
3647 evas_object_data_set(obj, "comp_ref", (void*)1);
3649 edje_object_signal_emit(obj, "e,state,hidden", "e");
3650 evas_object_data_set(obj, "comp_hiding", (void*)1);
3652 if (evas_object_data_del(obj, "comp_override"))
3653 e_comp_override_timed_pop();
3657 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3659 if (!e_util_strcmp(emission, "e,action,hide,done"))
3661 if (!evas_object_data_del(obj, "comp_hiding")) return;
3662 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3663 evas_object_hide(obj);
3664 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3667 evas_object_data_del(obj, "comp_showing");
3668 if (evas_object_data_del(obj, "comp_ref"))
3669 evas_object_unref(obj);
3673 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3679 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3683 E_API E_Comp_Object_Hook *
3684 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3686 E_Comp_Object_Hook *ch;
3688 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3689 ch = E_NEW(E_Comp_Object_Hook, 1);
3690 if (!ch) return NULL;
3691 ch->hookpoint = hookpoint;
3693 ch->data = (void*)data;
3694 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3699 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3702 if (_e_comp_object_hooks_walking == 0)
3704 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3708 _e_comp_object_hooks_delete++;
3711 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3712 E_API E_Comp_Object_Intercept_Hook *
3713 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3715 E_Comp_Object_Intercept_Hook *ch;
3717 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3718 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3719 if (!ch) return NULL;
3720 ch->hookpoint = hookpoint;
3722 ch->data = (void*)data;
3723 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3728 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3731 if (_e_comp_object_intercept_hooks_walking == 0)
3733 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3737 _e_comp_object_intercept_hooks_delete++;
3742 e_comp_object_util_add(Evas_Object *obj)
3746 E_Comp_Config *conf = e_comp_config_get();
3747 Eina_Bool skip = EINA_FALSE;
3753 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3755 name = evas_object_name_get(obj);
3756 vis = evas_object_visible_get(obj);
3757 o = edje_object_add(e_comp->evas);
3758 evas_object_data_set(o, "comp_object", (void*)1);
3760 skip = (!strncmp(name, "noshadow", 8));
3762 evas_object_data_set(o, "comp_object_skip", (void*)1);
3764 if (conf->shadow_style)
3766 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3767 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3770 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3771 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3772 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3774 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3776 evas_object_geometry_get(obj, &x, &y, &w, &h);
3777 evas_object_geometry_set(o, x, y, w, h);
3778 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3780 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3782 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3783 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3784 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3787 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3789 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3791 edje_object_part_swallow(o, "e.swallow.content", obj);
3793 _e_comp_object_event_add(o);
3796 evas_object_show(o);
3801 /* utility functions for deleting objects when their "owner" is deleted */
3803 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3808 EINA_SAFETY_ON_NULL_RETURN(to_del);
3809 l = evas_object_data_get(obj, "comp_object-to_del");
3810 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3811 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3812 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3816 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3821 EINA_SAFETY_ON_NULL_RETURN(to_del);
3822 l = evas_object_data_get(obj, "comp_object-to_del");
3824 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3827 /////////////////////////////////////////////////////////
3829 EINTERN Evas_Object *
3830 e_comp_object_client_add(E_Client *ec)
3835 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3836 if (ec->frame) return NULL;
3837 _e_comp_smart_init();
3838 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3839 cw = evas_object_smart_data_get(o);
3840 if (!cw) return NULL;
3841 evas_object_data_set(o, "E_Client", ec);
3844 evas_object_data_set(o, "comp_object", (void*)1);
3846 _e_comp_object_event_add(o);
3851 /* utility functions for getting client inset */
3853 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3856 if (!cw->client_inset.calc)
3862 if (ax) *ax = x - cw->client_inset.l;
3863 if (ay) *ay = y - cw->client_inset.t;
3867 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3870 if (!cw->client_inset.calc)
3876 if (ax) *ax = x + cw->client_inset.l;
3877 if (ay) *ay = y + cw->client_inset.t;
3881 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3884 if (!cw->client_inset.calc)
3890 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3891 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3895 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3898 if (!cw->client_inset.calc)
3904 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3905 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3909 e_comp_object_client_get(Evas_Object *obj)
3914 /* FIXME: remove this when eo is used */
3915 o = evas_object_data_get(obj, "comp_smart_obj");
3917 return e_comp_object_client_get(o);
3918 return cw ? cw->ec : NULL;
3922 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3925 if (cw->frame_extends)
3926 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3931 if (w) *w = cw->ec->w;
3932 if (h) *h = cw->ec->h;
3937 e_comp_object_util_zone_get(Evas_Object *obj)
3939 E_Zone *zone = NULL;
3943 zone = e_comp_zone_find_by_ec(cw->ec);
3948 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3949 zone = e_comp_zone_xy_get(x, y);
3955 e_comp_object_util_center(Evas_Object *obj)
3957 int x, y, w, h, ow, oh;
3962 zone = e_comp_object_util_zone_get(obj);
3963 EINA_SAFETY_ON_NULL_RETURN(zone);
3964 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3965 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3966 ow = cw->ec->w, oh = cw->ec->h;
3968 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3969 x = x + (w - ow) / 2;
3970 y = y + (h - oh) / 2;
3971 evas_object_move(obj, x, y);
3975 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3977 int x, y, w, h, ow, oh;
3980 EINA_SAFETY_ON_NULL_RETURN(on);
3981 evas_object_geometry_get(on, &x, &y, &w, &h);
3982 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3983 ow = cw->ec->w, oh = cw->ec->h;
3985 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3986 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3990 e_comp_object_util_fullscreen(Evas_Object *obj)
3995 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3998 evas_object_move(obj, 0, 0);
3999 evas_object_resize(obj, e_comp->w, e_comp->h);
4004 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4012 ow = cw->w, oh = cw->h;
4014 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4015 zone = e_comp_object_util_zone_get(obj);
4016 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4017 if (x) *x = zx + (zw - ow) / 2;
4018 if (y) *y = zy + (zh - oh) / 2;
4022 e_comp_object_input_objs_del(Evas_Object *obj)
4025 E_Input_Rect_Data *input_rect_data;
4026 E_Input_Rect_Smart_Data *input_rect_sd;
4031 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4032 if (!input_rect_sd) return;
4034 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4036 if (input_rect_data->obj)
4038 evas_object_smart_member_del(input_rect_data->obj);
4039 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4041 E_FREE(input_rect_data);
4046 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4049 E_Input_Rect_Data *input_rect_data = NULL;
4050 E_Input_Rect_Smart_Data *input_rect_sd;
4051 int client_w, client_h;
4053 if (cw->ec->client.w)
4054 client_w = cw->ec->client.w;
4056 client_w = cw->ec->w;
4058 if (cw->ec->client.h)
4059 client_h = cw->ec->client.h;
4061 client_h = cw->ec->h;
4063 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4067 _e_comp_input_obj_smart_init();
4068 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4069 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4070 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4073 input_rect_sd->cw = cw;
4076 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4079 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4080 if (input_rect_data)
4082 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4083 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4087 if ((input_rect_data) &&
4088 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4090 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4091 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4092 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4093 evas_object_clip_set(input_rect_data->obj, cw->clip);
4094 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4095 evas_object_geometry_set(input_rect_data->obj,
4096 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4097 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4098 evas_object_pass_events_set(cw->default_input_obj, 1);
4099 evas_object_pass_events_set(cw->obj, 1);
4102 evas_object_show(input_rect_data->obj);
4103 evas_object_show(cw->input_obj);
4108 evas_object_smart_member_del(cw->input_obj);
4109 E_FREE_FUNC(cw->input_obj, evas_object_del);
4110 evas_object_pass_events_set(cw->default_input_obj, 0);
4111 evas_object_pass_events_set(cw->obj, 0);
4116 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4119 E_Input_Rect_Smart_Data *input_rect_sd;
4120 E_Input_Rect_Data *input_rect_data;
4123 if (!cw->input_obj) return;
4125 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4128 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4130 *list = eina_list_append(*list, &input_rect_data->rect);
4136 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4139 if (l) *l = cw->client_inset.l;
4140 if (r) *r = cw->client_inset.r;
4141 if (t) *t = cw->client_inset.t;
4142 if (b) *b = cw->client_inset.b;
4145 /* set geometry for CSD */
4147 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4153 if (cw->frame_object)
4154 CRI("ACK! ec:%p", cw->ec);
4155 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4156 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4157 calc = cw->client_inset.calc;
4158 cw->client_inset.calc = l || r || t || b;
4159 eina_stringshare_replace(&cw->frame_theme, "borderless");
4160 if (cw->client_inset.calc)
4162 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4163 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4164 e_client_size_set(cw->ec, tw, th);
4166 else if (cw->ec->maximized || cw->ec->fullscreen)
4168 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4169 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4171 if (!cw->ec->new_client)
4173 if (calc && cw->client_inset.calc)
4175 tx = cw->ec->x - (l - cw->client_inset.l);
4176 ty = cw->ec->y - (t - cw->client_inset.t);
4177 e_client_pos_set(cw->ec, tx, ty);
4179 cw->ec->changes.pos = cw->ec->changes.size = 1;
4182 cw->client_inset.l = l;
4183 cw->client_inset.r = r;
4184 cw->client_inset.t = t;
4185 cw->client_inset.b = b;
4189 e_comp_object_frame_allowed(Evas_Object *obj)
4191 API_ENTRY EINA_FALSE;
4192 return (cw->frame_object || (!cw->client_inset.calc));
4196 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4198 API_ENTRY EINA_FALSE;
4199 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4200 eina_stringshare_replace(&cw->frame_name, name);
4201 if (cw->frame_object)
4202 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4207 e_comp_object_frame_exists(Evas_Object *obj)
4209 API_ENTRY EINA_FALSE;
4210 return !!cw->frame_object;
4214 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4216 Evas_Object *o, *pbg;
4219 Eina_Stringshare *theme;
4221 API_ENTRY EINA_FALSE;
4223 if (!e_util_strcmp(cw->frame_theme, name))
4224 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4225 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4226 return _e_comp_object_shadow_setup(cw);
4227 pbg = cw->frame_object;
4228 theme = eina_stringshare_add(name);
4230 if (cw->frame_object)
4234 w = cw->ec->w, h = cw->ec->h;
4235 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4236 if ((cw->ec->w != w) || (cw->ec->h != h))
4238 cw->ec->changes.size = 1;
4241 E_FREE_FUNC(cw->frame_object, evas_object_del);
4242 if (!name) goto reshadow;
4244 o = edje_object_add(e_comp->evas);
4245 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4246 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4247 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4249 cw->frame_object = NULL;
4251 eina_stringshare_del(cw->frame_theme);
4252 cw->frame_theme = theme;
4257 if (theme != e_config->theme_default_border_style)
4259 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4260 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4264 ok = e_theme_edje_object_set(o, "base/theme/border",
4265 "e/widgets/border/default/border");
4266 if (ok && (theme == e_config->theme_default_border_style))
4268 /* Reset default border style to default */
4269 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4270 e_config_save_queue();
4277 cw->frame_object = o;
4278 eina_stringshare_del(cw->frame_theme);
4279 cw->frame_theme = theme;
4280 evas_object_name_set(o, "cw->frame_object");
4283 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4287 cw->ec->changes.icon = 1;
4293 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4298 _e_comp_object_shadow_setup(cw);
4301 int old_x, old_y, new_x = 0, new_y = 0;
4303 old_x = cw->x, old_y = cw->y;
4305 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4307 new_x = cw->ec->x, new_y = cw->ec->y;
4308 else if (cw->ec->placed || (!cw->ec->new_client))
4310 /* if no previous frame:
4311 * - reapply client_inset
4316 if (cw->ec->changes.size)
4324 zone = e_comp_zone_find_by_ec(cw->ec);
4327 x = cw->ec->client.x, y = cw->ec->client.y;
4328 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4329 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4331 new_x = x, new_y = y;
4334 if (old_x != new_x || old_y != new_y)
4336 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4337 cw->y = cw->x = -99999;
4338 evas_object_move(obj, new_x, new_y);
4342 if (cw->ec->maximized)
4344 cw->ec->changes.need_maximize = 1;
4347 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4348 if (cw->frame_object)
4350 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4353 cw->frame_extends = 0;
4354 evas_object_del(pbg);
4359 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4361 E_Comp_Object_Mover *prov;
4364 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4365 edje_object_signal_emit(cw->shobj, sig, src);
4366 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4367 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4368 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4370 /* start with highest priority callback first */
4371 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4373 if (!e_util_glob_match(sig, prov->sig)) continue;
4374 if (prov->func(prov->data, obj, sig)) break;
4379 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4381 /* FIXME: at some point I guess this should use eo to inherit
4382 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4383 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4386 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4390 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4393 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4397 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4400 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4404 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4407 Eina_Rectangle rect;
4410 if (cw->ec->input_only || (!cw->updates)) return;
4411 if (cw->nocomp) return;
4412 rect.x = x, rect.y = y;
4413 rect.w = w, rect.h = h;
4414 evas_object_smart_callback_call(obj, "damage", &rect);
4416 if (e_comp_is_on_overlay(cw->ec))
4418 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4419 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4420 * E module attempts to block screen update due to the particular policy.
4422 if (e_pixmap_resource_get(cw->ec->pixmap))
4423 cw->hwc_need_update = EINA_TRUE;
4426 /* ignore overdraw */
4427 if (cw->updates_full)
4429 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4430 e_comp_object_render_update_add(obj);
4432 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4433 evas_object_show(cw->smart_obj);
4437 /* clip rect to client surface */
4438 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4439 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4440 /* if rect is the total size of the client after clip, clear the updates
4441 * since this is guaranteed to be the whole region anyway
4443 eina_tiler_area_size_get(cw->updates, &tw, &th);
4444 if ((w > tw) || (h > th))
4446 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4447 eina_tiler_clear(cw->updates);
4448 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4450 tw = cw->ec->client.w, th = cw->ec->client.h;
4452 if ((!x) && (!y) && (w == tw) && (h == th))
4454 eina_tiler_clear(cw->updates);
4455 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4456 cw->updates_full = 1;
4457 cw->update_count = 0;
4460 if (cw->update_count > UPDATE_MAX)
4462 /* this is going to get really dumb, so just update the whole thing */
4463 eina_tiler_clear(cw->updates);
4464 cw->update_count = cw->updates_full = 1;
4465 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4466 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4470 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4471 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4473 cw->updates_exist = 1;
4474 e_comp_object_render_update_add(obj);
4476 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4477 evas_object_show(cw->smart_obj);
4481 e_comp_object_damage_exists(Evas_Object *obj)
4483 API_ENTRY EINA_FALSE;
4484 return cw->updates_exist;
4488 e_comp_object_render_update_add(Evas_Object *obj)
4492 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4493 if (cw->render_update_lock.lock) return;
4494 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4498 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4500 e_comp_render_queue();
4504 e_comp_object_render_update_del(Evas_Object *obj)
4508 if (cw->ec->input_only || (!cw->updates)) return;
4509 if (!cw->update) return;
4511 /* this gets called during comp animating to clear the update flag */
4512 if (e_comp->grabbed) return;
4513 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4514 if (!e_comp->updates)
4516 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4517 if (e_comp->render_animator)
4518 ecore_animator_freeze(e_comp->render_animator);
4523 e_comp_object_shape_apply(Evas_Object *obj)
4527 unsigned int i, *pix, *p;
4531 if (!cw->ec) return; //NYI
4532 if (cw->external_content) return;
4535 if ((cw->ec->shape_rects_num >= 1) &&
4536 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4541 ERR("BUGGER: shape with native surface? cw=%p", cw);
4544 evas_object_image_size_get(cw->obj, &w, &h);
4545 if ((w < 1) || (h < 1)) return;
4548 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4549 _e_comp_object_alpha_set(cw);
4550 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4551 evas_object_image_alpha_set(o, 1);
4553 p = pix = evas_object_image_data_get(cw->obj, 1);
4556 evas_object_image_data_set(cw->obj, pix);
4561 unsigned char *spix, *sp;
4563 spix = calloc(w * h, sizeof(unsigned char));
4565 for (i = 0; i < cw->ec->shape_rects_num; i++)
4569 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4570 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4571 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4572 sp = spix + (w * ry) + rx;
4573 for (py = 0; py < rh; py++)
4575 for (px = 0; px < rw; px++)
4583 for (py = 0; py < h; py++)
4585 for (px = 0; px < w; px++)
4587 unsigned int mask, imask;
4589 mask = ((unsigned int)(*sp)) << 24;
4591 imask |= imask >> 8;
4592 imask |= imask >> 8;
4593 *p = mask | (*p & imask);
4594 //if (*sp) *p = 0xff000000 | *p;
4595 //else *p = 0x00000000;
4604 for (py = 0; py < h; py++)
4606 for (px = 0; px < w; px++)
4610 evas_object_image_data_set(cw->obj, pix);
4611 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4612 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4614 evas_object_image_data_set(o, pix);
4615 evas_object_image_data_update_add(o, 0, 0, w, h);
4617 // don't need to fix alpha chanel as blending
4618 // should be totally off here regardless of
4619 // alpha channel content
4623 _e_comp_object_clear(E_Comp_Object *cw)
4628 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4630 if (cw->render_update_lock.lock) return;
4633 e_pixmap_clear(cw->ec->pixmap);
4635 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4636 evas_object_image_size_set(cw->obj, 1, 1);
4637 evas_object_image_data_set(cw->obj, NULL);
4638 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4640 evas_object_image_size_set(o, 1, 1);
4641 evas_object_image_data_set(o, NULL);
4644 e_comp_object_render_update_del(cw->smart_obj);
4648 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4652 API_ENTRY EINA_FALSE;
4654 if (cw->transparent.set == set)
4659 evas_object_color_get(obj, &r, &g, &b, &a);
4660 evas_object_color_set(obj, 0, 0, 0, 0);
4662 cw->transparent.user_r = r;
4663 cw->transparent.user_g = g;
4664 cw->transparent.user_b = b;
4665 cw->transparent.user_a = a;
4667 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4669 cw->transparent.user_r,
4670 cw->transparent.user_g,
4671 cw->transparent.user_b,
4672 cw->transparent.user_a);
4674 cw->transparent.set = EINA_TRUE;
4678 cw->transparent.set = EINA_FALSE;
4680 evas_object_color_set(obj,
4681 cw->transparent.user_r,
4682 cw->transparent.user_g,
4683 cw->transparent.user_b,
4684 cw->transparent.user_a);
4686 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4688 cw->transparent.user_r,
4689 cw->transparent.user_g,
4690 cw->transparent.user_b,
4691 cw->transparent.user_a);
4697 /* helper function to simplify toggling of redirection for display servers which support it */
4699 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4704 if (cw->redirected == set) return;
4705 cw->redirected = set;
4706 if (cw->external_content) return;
4708 e_comp_object_map_update(obj);
4712 if (cw->updates_exist)
4713 e_comp_object_render_update_add(obj);
4715 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4717 _e_comp_object_transparent_set(obj, EINA_FALSE);
4718 evas_object_smart_callback_call(obj, "redirected", NULL);
4722 _e_comp_object_clear(cw);
4723 _e_comp_object_transparent_set(obj, EINA_TRUE);
4724 evas_object_smart_callback_call(obj, "unredirected", NULL);
4729 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4732 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4734 if (cw->buffer_destroy_listener.notify)
4736 cw->buffer_destroy_listener.notify = NULL;
4737 wl_list_remove(&cw->buffer_destroy_listener.link);
4740 if (e_object_is_del(E_OBJECT(cw->ec)))
4742 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4747 /* if it's current displaying buffer, do not remove its content */
4748 if (!evas_object_visible_get(cw->ec->frame))
4749 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4754 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4759 if (cw->buffer_destroy_listener.notify)
4761 wl_list_remove(&cw->buffer_destroy_listener.link);
4762 cw->buffer_destroy_listener.notify = NULL;
4765 if (cw->tbm_surface)
4767 tbm_surface_internal_unref(cw->tbm_surface);
4768 cw->tbm_surface = NULL;
4773 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4775 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4776 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4778 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4780 tbm_surface_internal_ref(ns->data.tbm.buffer);
4781 cw->tbm_surface = ns->data.tbm.buffer;
4785 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4786 evas_object_image_native_surface_set(cw->obj, ns);
4790 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4792 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4793 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4794 evas_object_image_native_surface_set(o, ns);
4801 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4803 Evas_Native_Surface ns;
4806 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4807 if (cw->ec->input_only) return;
4808 if (cw->external_content) return;
4809 if (cw->render_update_lock.lock) return;
4812 memset(&ns, 0, sizeof(Evas_Native_Surface));
4816 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4817 set = (!cw->ec->shaped);
4819 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4823 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4827 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4830 if (cw->ec->input_only) return;
4833 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4834 _e_comp_object_alpha_set(cw);
4836 e_comp_object_native_surface_set(obj, cw->native);
4837 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4841 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4847 if (cw->blanked == set) return;
4849 _e_comp_object_alpha_set(cw);
4852 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4853 evas_object_image_data_set(cw->obj, NULL);
4857 e_comp_object_native_surface_set(obj, 1);
4858 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4862 _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)
4867 if (!_damage_trace) return;
4871 if (!evas_object_visible_get(cw->obj)) return;
4873 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4875 o = evas_object_rectangle_add(e_comp->evas);
4876 evas_object_layer_set(o, E_LAYER_MAX);
4877 evas_object_name_set(o, "damage_trace");
4878 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4879 evas_object_resize(o, dmg_w, dmg_h);
4880 evas_object_color_set(o, 0, 128, 0, 128);
4881 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4882 evas_object_pass_events_set(o, EINA_TRUE);
4883 evas_object_show(o);
4885 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4887 dmg_w, dmg_h, dmg_x, dmg_y,
4888 origin->w, origin->h, origin->x, origin->y);
4890 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4893 /* mark an object as dirty and setup damages */
4895 e_comp_object_dirty(Evas_Object *obj)
4898 Eina_Rectangle *rect;
4902 Eina_Bool dirty, visible;
4906 if (cw->external_content) return;
4907 if (!cw->redirected) return;
4908 if (cw->render_update_lock.lock)
4910 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4913 /* only actually dirty if pixmap is available */
4914 if (!e_pixmap_resource_get(cw->ec->pixmap))
4916 // e_pixmap_size_get returns last attached buffer size
4917 // eventhough it is destroyed
4918 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4921 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4922 visible = cw->visible;
4923 if (!dirty) w = h = 1;
4924 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4926 evas_object_image_data_set(cw->obj, NULL);
4927 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4928 evas_object_image_size_set(cw->obj, tw, th);
4929 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4930 if (cw->pending_updates)
4931 eina_tiler_area_size_set(cw->pending_updates, w, h);
4932 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4934 evas_object_image_pixels_dirty_set(o, dirty);
4936 evas_object_image_data_set(o, NULL);
4937 evas_object_image_size_set(o, tw, th);
4938 visible |= evas_object_visible_get(o);
4942 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4946 e_comp_object_native_surface_set(obj, 1);
4948 m = _e_comp_object_map_damage_transform_get(cw->ec);
4949 it = eina_tiler_iterator_new(cw->updates);
4950 EINA_ITERATOR_FOREACH(it, rect)
4952 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4953 * of evas engine and doesn't convert damage according to evas_map.
4954 * so damage of evas_object_image use surface coordinate.
4958 int damage_x, damage_y, damage_w, damage_h;
4960 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4961 &damage_x, &damage_y, &damage_w, &damage_h);
4962 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4963 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4967 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4968 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4971 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4972 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4973 if (cw->pending_updates)
4974 eina_tiler_rect_add(cw->pending_updates, rect);
4976 eina_iterator_free(it);
4977 if (m) e_map_free(m);
4978 if (cw->pending_updates)
4979 eina_tiler_clear(cw->updates);
4982 cw->pending_updates = cw->updates;
4983 cw->updates = eina_tiler_new(w, h);
4984 eina_tiler_tile_size_set(cw->updates, 1, 1);
4986 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4987 evas_object_smart_callback_call(obj, "dirty", NULL);
4988 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4989 /* force render if main object is hidden but mirrors are visible */
4990 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4991 e_comp_object_render(obj);
4995 e_comp_object_render(Evas_Object *obj)
5002 API_ENTRY EINA_FALSE;
5004 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5005 if (cw->ec->input_only) return EINA_TRUE;
5006 if (cw->external_content) return EINA_TRUE;
5007 if (cw->native) return EINA_FALSE;
5008 /* if comp object is not redirected state, comp object should not be set by newly committed data
5009 because image size of comp object is 1x1 and it should not be shown on canvas */
5010 if (!cw->redirected) return EINA_TRUE;
5011 if (cw->render_update_lock.lock)
5013 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5016 e_comp_object_render_update_del(obj);
5017 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5019 if (!cw->pending_updates)
5021 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5022 evas_object_image_data_set(cw->obj, NULL);
5023 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5024 evas_object_image_data_set(o, NULL);
5028 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5030 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5032 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5035 e_pixmap_image_refresh(cw->ec->pixmap);
5036 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5039 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5040 e_pixmap_image_data_ref(cw->ec->pixmap);
5042 /* set pixel data */
5043 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5044 _e_comp_object_alpha_set(cw);
5045 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5047 evas_object_image_data_set(o, pix);
5048 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5049 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5052 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5054 e_comp_client_post_update_add(cw->ec);
5059 /* create a duplicate of an evas object */
5061 e_comp_object_util_mirror_add(Evas_Object *obj)
5065 unsigned int *pix = NULL;
5066 Eina_Bool argb = EINA_FALSE;
5071 cw = evas_object_data_get(obj, "comp_mirror");
5074 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5075 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5076 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5077 evas_object_image_alpha_set(o, 1);
5078 evas_object_image_source_set(o, obj);
5081 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5082 if (cw->external_content)
5084 ERR("%p of client %p is external content.", obj, cw->ec);
5087 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5088 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5089 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5090 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5091 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5092 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5093 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5094 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5095 evas_object_data_set(o, "comp_mirror", cw);
5097 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5098 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5100 evas_object_image_size_set(o, tw, th);
5103 pix = evas_object_image_data_get(cw->obj, 0);
5109 evas_object_image_native_surface_set(o, cw->ns);
5112 Evas_Native_Surface ns;
5113 memset(&ns, 0, sizeof(Evas_Native_Surface));
5114 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5115 evas_object_image_native_surface_set(o, &ns);
5120 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5121 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5123 (e_pixmap_image_exists(cw->ec->pixmap)))
5124 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5126 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5133 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5134 evas_object_image_pixels_dirty_set(o, dirty);
5135 evas_object_image_data_set(o, pix);
5136 evas_object_image_data_set(cw->obj, pix);
5138 evas_object_image_data_update_add(o, 0, 0, tw, th);
5143 //////////////////////////////////////////////////////
5146 e_comp_object_effect_allowed_get(Evas_Object *obj)
5148 API_ENTRY EINA_FALSE;
5150 if (!cw->shobj) return EINA_FALSE;
5151 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5152 return !e_comp_config_get()->match.disable_borders;
5155 /* setup an api effect for a client */
5157 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5160 Eina_Stringshare *grp;
5161 E_Comp_Config *config;
5162 Eina_Bool loaded = EINA_FALSE;
5164 API_ENTRY EINA_FALSE;
5165 if (!cw->shobj) return EINA_FALSE; //input window
5167 if (!effect) effect = "none";
5168 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5170 config = e_comp_config_get();
5171 if ((config) && (config->effect_file))
5173 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5175 cw->effect_set = EINA_TRUE;
5182 edje_object_file_get(cw->effect_obj, NULL, &grp);
5183 cw->effect_set = !eina_streq(effect, "none");
5184 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5185 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5187 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5188 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5189 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5191 if (cw->effect_running)
5193 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5196 cw->effect_set = EINA_FALSE;
5197 return cw->effect_set;
5201 if (cw->effect_running)
5203 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5206 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5207 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5208 if (cw->effect_clip)
5210 evas_object_clip_unset(cw->clip);
5211 cw->effect_clip = 0;
5213 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5215 _e_comp_object_dim_update(cw);
5217 return cw->effect_set;
5220 /* set params for embryo scripts in effect */
5222 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5224 Edje_Message_Int_Set *msg;
5228 EINA_SAFETY_ON_NULL_RETURN(params);
5229 EINA_SAFETY_ON_FALSE_RETURN(count);
5230 if (!cw->effect_set) return;
5232 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5233 msg->count = (int)count;
5234 for (x = 0; x < count; x++)
5235 msg->val[x] = params[x];
5236 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5237 edje_object_message_signal_process(cw->effect_obj);
5241 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5243 Edje_Signal_Cb end_cb;
5245 E_Comp_Object *cw = data;
5247 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5248 cw->effect_running = 0;
5249 if (!_e_comp_object_animating_end(cw)) return;
5251 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5253 evas_object_data_del(cw->smart_obj, "effect_running");
5254 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5255 e_comp_visibility_calculation_set(EINA_TRUE);
5258 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5259 if (!end_cb) return;
5260 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5261 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5262 end_cb(end_data, cw->smart_obj, emission, source);
5265 /* clip effect to client's zone */
5267 e_comp_object_effect_clip(Evas_Object *obj)
5271 zone = e_comp_zone_find_by_ec(cw->ec);
5273 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5274 if (!cw->effect_clip_able) return;
5275 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5276 cw->effect_clip = 1;
5279 /* unclip effect from client's zone */
5281 e_comp_object_effect_unclip(Evas_Object *obj)
5284 if (!cw->effect_clip) return;
5285 evas_object_clip_unset(cw->smart_obj);
5286 cw->effect_clip = 0;
5289 /* start effect, running end_cb after */
5291 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5293 API_ENTRY EINA_FALSE;
5294 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5295 if (!cw->effect_set) return EINA_FALSE;
5297 if (cw->effect_running)
5299 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5302 e_comp_object_effect_clip(obj);
5303 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5305 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5306 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5307 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5308 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5310 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5311 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5313 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5314 _e_comp_object_animating_begin(cw);
5315 cw->effect_running = 1;
5319 /* stop a currently-running effect immediately */
5321 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5324 Edje_Signal_Cb end_cb_before = NULL;
5325 void *end_data_before = NULL;
5326 API_ENTRY EINA_FALSE;
5328 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5329 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5331 if (end_cb_before != end_cb) return EINA_TRUE;
5332 e_comp_object_effect_unclip(obj);
5333 if (cw->effect_clip)
5335 evas_object_clip_unset(cw->effect_obj);
5336 cw->effect_clip = 0;
5338 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5339 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5341 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5343 evas_object_data_del(cw->smart_obj, "effect_running");
5344 e_comp_visibility_calculation_set(EINA_TRUE);
5347 cw->effect_running = 0;
5348 ret = _e_comp_object_animating_end(cw);
5350 if ((ret) && (end_cb_before))
5352 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5353 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5360 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5362 return a->pri - b->pri;
5365 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5366 E_API E_Comp_Object_Mover *
5367 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5369 E_Comp_Object_Mover *prov;
5371 prov = E_NEW(E_Comp_Object_Mover, 1);
5372 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5373 prov->func = provider;
5374 prov->data = (void*)data;
5377 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5378 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5383 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5385 EINA_SAFETY_ON_NULL_RETURN(prov);
5386 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5391 e_comp_object_effect_object_get(Evas_Object *obj)
5395 return cw->effect_obj;
5399 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5401 API_ENTRY EINA_FALSE;
5402 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5403 if (!cw->effect_set) return EINA_FALSE;
5410 ////////////////////////////////////
5413 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5415 if (e_comp->autoclose.obj)
5417 e_comp_ungrab_input(0, 1);
5418 if (e_comp->autoclose.del_cb)
5419 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5420 else if (!already_del)
5422 evas_object_hide(e_comp->autoclose.obj);
5423 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5425 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5427 e_comp->autoclose.obj = NULL;
5428 e_comp->autoclose.data = NULL;
5429 e_comp->autoclose.del_cb = NULL;
5430 e_comp->autoclose.key_cb = NULL;
5431 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5435 _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)
5437 _e_comp_object_autoclose_cleanup(0);
5441 _e_comp_object_autoclose_setup(Evas_Object *obj)
5443 if (!e_comp->autoclose.rect)
5445 /* create rect just below autoclose object to catch mouse events */
5446 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5447 evas_object_move(e_comp->autoclose.rect, 0, 0);
5448 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5449 evas_object_show(e_comp->autoclose.rect);
5450 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5451 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5452 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5453 e_comp_grab_input(0, 1);
5455 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5456 evas_object_focus_set(obj, 1);
5460 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5462 _e_comp_object_autoclose_setup(obj);
5463 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5467 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5469 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5470 _e_comp_object_autoclose_cleanup(1);
5471 if (e_client_focused_get()) return;
5473 E_Zone *zone = e_zone_current_get();
5476 e_zone_focus_reset(zone);
5480 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5484 if (e_comp->autoclose.obj)
5486 if (e_comp->autoclose.obj == obj) return;
5487 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5488 e_comp->autoclose.obj = obj;
5489 e_comp->autoclose.del_cb = del_cb;
5490 e_comp->autoclose.key_cb = cb;
5491 e_comp->autoclose.data = (void*)data;
5492 if (evas_object_visible_get(obj))
5493 _e_comp_object_autoclose_setup(obj);
5495 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5496 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5499 e_comp->autoclose.obj = obj;
5500 e_comp->autoclose.del_cb = del_cb;
5501 e_comp->autoclose.key_cb = cb;
5502 e_comp->autoclose.data = (void*)data;
5503 if (evas_object_visible_get(obj))
5504 _e_comp_object_autoclose_setup(obj);
5506 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5507 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5511 e_comp_object_is_animating(Evas_Object *obj)
5515 return cw->animating;
5519 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5523 if ((cw->external_content) &&
5524 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5526 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5527 "But current external content is %d object for %p.",
5528 cw->content_type, cw->ec);
5532 cw->user_alpha_set = EINA_TRUE;
5533 cw->user_alpha = alpha;
5535 if (!cw->obj) return;
5537 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5539 evas_object_image_alpha_set(cw->obj, alpha);
5541 if ((!cw->native) && (!cw->external_content))
5542 evas_object_image_data_set(cw->obj, NULL);
5546 e_comp_object_alpha_get(Evas_Object *obj)
5548 API_ENTRY EINA_FALSE;
5550 return evas_object_image_alpha_get(cw->obj);
5554 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5556 Eina_Bool mask_set = EINA_FALSE;
5560 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5561 if (cw->ec->input_only) return;
5568 o = evas_object_rectangle_add(e_comp->evas);
5569 evas_object_color_set(o, 0, 0, 0, 0);
5570 evas_object_clip_set(o, cw->clip);
5571 evas_object_smart_member_add(o, obj);
5572 evas_object_move(o, 0, 0);
5573 evas_object_resize(o, cw->w, cw->h);
5574 /* save render op value to restore when clear a mask.
5576 * NOTE: DO NOT change the render op on ec->frame while mask object
5577 * is set. it will overwrite the changed op value. */
5578 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5579 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5580 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5581 if (cw->visible) evas_object_show(o);
5584 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5585 ELOGF("COMP", " |mask_obj", cw->ec);
5586 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5593 evas_object_smart_member_del(cw->mask.obj);
5594 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5596 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5597 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5603 e_comp_object_mask_has(Evas_Object *obj)
5605 API_ENTRY EINA_FALSE;
5607 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5611 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5616 if ((cw->external_content) &&
5617 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5619 WRN("Can set up size to ONLY evas \"image\" object. "
5620 "But current external content is %d object for %p.",
5621 cw->content_type, cw->ec);
5625 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5627 evas_object_image_size_set(cw->obj, tw, th);
5631 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5633 Eina_Bool transform_set = EINA_FALSE;
5635 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5636 if (cw->ec->input_only) return;
5638 transform_set = !!set;
5642 if (!cw->transform_bg_obj)
5644 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5645 evas_object_move(o, 0, 0);
5646 evas_object_resize(o, 1, 1);
5647 if (cw->transform_bg_color.a >= 255)
5648 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5650 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5651 evas_object_color_set(o,
5652 cw->transform_bg_color.r,
5653 cw->transform_bg_color.g,
5654 cw->transform_bg_color.b,
5655 cw->transform_bg_color.a);
5656 if (cw->visible) evas_object_show(o);
5658 cw->transform_bg_obj = o;
5659 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5661 _e_comp_object_transform_obj_stack_update(obj);
5665 if (cw->transform_bg_obj)
5667 evas_object_smart_member_del(cw->transform_bg_obj);
5668 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5674 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5678 cw->transform_bg_color.r = r;
5679 cw->transform_bg_color.g = g;
5680 cw->transform_bg_color.b = b;
5681 cw->transform_bg_color.a = a;
5683 if (cw->transform_bg_obj)
5685 evas_object_color_set(cw->transform_bg_obj,
5686 cw->transform_bg_color.r,
5687 cw->transform_bg_color.g,
5688 cw->transform_bg_color.b,
5689 cw->transform_bg_color.a);
5694 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5697 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5698 if (cw->ec->input_only) return;
5699 if (!cw->transform_bg_obj) return;
5701 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5705 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5708 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5709 if (cw->ec->input_only) return;
5710 if (!cw->transform_bg_obj) return;
5712 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5716 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5718 Eina_Bool transform_set = EINA_FALSE;
5720 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5721 if (cw->ec->input_only) return;
5723 transform_set = !!set;
5727 if (!cw->transform_tranp_obj)
5729 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5730 evas_object_move(o, 0, 0);
5731 evas_object_resize(o, 1, 1);
5732 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5733 evas_object_color_set(o, 0, 0, 0, 0);
5734 if (cw->visible) evas_object_show(o);
5736 cw->transform_tranp_obj = o;
5737 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5738 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5739 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5741 _e_comp_object_transform_obj_stack_update(obj);
5745 if (cw->transform_tranp_obj)
5747 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5748 evas_object_smart_member_del(cw->transform_tranp_obj);
5749 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5755 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5758 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5759 if (cw->ec->input_only) return;
5760 if (!cw->transform_tranp_obj) return;
5762 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5766 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5769 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5770 if (cw->ec->input_only) return;
5771 if (!cw->transform_tranp_obj) return;
5773 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5776 #ifdef REFACTOR_DESK_AREA
5779 e_comp_object_layer_update(Evas_Object *obj,
5780 Evas_Object *above, Evas_Object *below)
5782 E_Comp_Object *cw2 = NULL;
5783 Evas_Object *o = NULL;
5788 if (cw->ec->layer_block) return;
5789 if ((above) && (below))
5791 ERR("Invalid layer update request! cw=%p", cw);
5799 layer = evas_object_layer_get(o);
5800 cw2 = evas_object_data_get(o, "comp_obj");
5803 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5805 o = evas_object_above_get(o);
5806 if ((!o) || (o == cw->smart_obj)) break;
5807 if (evas_object_layer_get(o) != layer)
5809 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5814 ec = e_client_top_get();
5815 if (ec) o = ec->frame;
5818 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5822 _e_comp_object_layers_remove(cw);
5825 if (cw2->layer > cw->layer)
5826 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5827 else if (cw2->layer == cw->layer)
5830 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5832 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5834 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5837 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5840 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5845 e_comp_object_layer_get(Evas_Object *obj)
5852 e_comp_object_content_set(Evas_Object *obj,
5853 Evas_Object *content,
5854 E_Comp_Object_Content_Type type)
5856 API_ENTRY EINA_FALSE;
5858 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5859 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5860 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5864 ERR("Can't set e.swallow.content to requested content. "
5865 "Previous comp object should not be changed at all.");
5869 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5871 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5872 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5874 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5875 type, content, cw->ec, cw->ec->pixmap);
5879 cw->external_content = EINA_TRUE;
5882 cw->content_type = type;
5883 e_util_size_debug_set(cw->obj, 1);
5884 evas_object_name_set(cw->obj, "cw->obj");
5885 _e_comp_object_alpha_set(cw);
5888 _e_comp_object_shadow_setup(cw);
5894 e_comp_object_content_unset(Evas_Object *obj)
5896 API_ENTRY EINA_FALSE;
5898 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5899 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5901 if (!cw->obj && !cw->ec->visible)
5903 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5907 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5909 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5915 if (cw->frame_object)
5916 edje_object_part_unswallow(cw->frame_object, cw->obj);
5918 edje_object_part_unswallow(cw->shobj, cw->obj);
5920 evas_object_del(cw->obj);
5921 evas_object_hide(cw->obj);
5925 cw->external_content = EINA_FALSE;
5926 if (cw->ec->is_cursor)
5929 DBG("%p is cursor surface..", cw->ec);
5930 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5932 evas_object_resize(cw->ec->frame, pw, ph);
5933 evas_object_hide(cw->ec->frame);
5938 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5939 cw->obj = evas_object_image_filled_add(e_comp->evas);
5940 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5941 e_util_size_debug_set(cw->obj, 1);
5942 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5943 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5944 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5945 evas_object_name_set(cw->obj, "cw->obj");
5946 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5947 _e_comp_object_alpha_set(cw);
5950 _e_comp_object_shadow_setup(cw);
5955 _e_comp_intercept_show_helper(cw);
5959 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5960 e_comp_object_dirty(cw->smart_obj);
5961 e_comp_object_render(cw->smart_obj);
5962 e_comp_object_render_update_add(obj);
5967 EINTERN Evas_Object *
5968 e_comp_object_content_get(Evas_Object *obj)
5972 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5974 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5976 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5983 E_API E_Comp_Object_Content_Type
5984 e_comp_object_content_type_get(Evas_Object *obj)
5986 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5988 return cw->content_type;
5992 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5995 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5996 E_Comp_Config *conf = e_comp_config_get();
5997 if (cw->ec->input_only) return;
5998 if (!conf->dim_rect_enable) return;
6000 cw->dim.mask_set = mask_set;
6006 if (!cw->dim.enable) return;
6007 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6011 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6013 Eina_Bool mask_set = EINA_FALSE;
6017 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6018 E_Comp_Config *conf = e_comp_config_get();
6019 if (cw->ec->input_only) return;
6020 if (!conf->dim_rect_enable) return;
6026 if (cw->dim.mask_obj)
6028 evas_object_smart_member_del(cw->dim.mask_obj);
6029 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6032 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);
6033 o = evas_object_rectangle_add(e_comp->evas);
6034 evas_object_color_set(o, 0, 0, 0, 0);
6035 evas_object_smart_member_add(o, obj);
6036 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6037 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6039 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6040 if (cw->visible) evas_object_show(o);
6042 cw->dim.mask_obj = o;
6043 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6045 evas_object_layer_set(cw->dim.mask_obj, 9998);
6049 if (cw->dim.mask_obj)
6051 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6052 evas_object_smart_member_del(cw->dim.mask_obj);
6053 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6059 e_comp_object_dim_client_set(E_Client *ec)
6061 E_Comp_Config *conf = e_comp_config_get();
6063 if (!conf->dim_rect_enable) return ;
6064 if (dim_client == ec) return;
6066 Eina_Bool prev_dim = EINA_FALSE;
6067 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6069 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6070 prev_dim = EINA_TRUE;
6072 if (prev_dim && dim_client->visible && ec)
6074 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6075 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6079 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6080 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6086 e_comp_object_dim_client_get(void)
6088 E_Comp_Config *conf = e_comp_config_get();
6090 if (!conf->dim_rect_enable ) return NULL;
6096 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6099 char emit[32] = "\0";
6100 E_Comp_Config *conf = e_comp_config_get();
6103 if (!conf->dim_rect_enable) return;
6104 if (!cw->effect_obj) return;
6105 if (enable == cw->dim.enable) return;
6107 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6108 if (noeffect || !conf->dim_rect_effect)
6110 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6114 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6117 cw->dim.enable = enable;
6119 if (cw->dim.mask_set && !enable)
6121 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6122 edje_object_signal_emit(cw->effect_obj, emit, "e");
6124 else if (cw->dim.mask_set && enable)
6126 edje_object_signal_emit(cw->effect_obj, emit, "e");
6127 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6131 edje_object_signal_emit(cw->effect_obj, emit, "e");
6136 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6138 API_ENTRY EINA_FALSE;
6139 E_Comp_Config *conf = e_comp_config_get();
6141 if (!ec) return EINA_FALSE;
6142 if (!conf->dim_rect_enable) return EINA_FALSE;
6144 if (cw->dim.enable) return EINA_TRUE;
6150 _e_comp_object_dim_update(E_Comp_Object *cw)
6152 E_Comp_Config *conf = e_comp_config_get();
6155 if (!conf->dim_rect_enable) return;
6156 if (!cw->effect_obj) return;
6159 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6160 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6162 if (cw->dim.mask_set)
6164 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6170 e_comp_object_clear(Evas_Object *obj)
6174 _e_comp_object_clear(cw);
6178 e_comp_object_hwc_update_exists(Evas_Object *obj)
6180 API_ENTRY EINA_FALSE;
6181 return cw->hwc_need_update;
6186 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6189 cw->hwc_need_update = set;
6193 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6195 API_ENTRY EINA_FALSE;
6196 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6200 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6203 if (cw->indicator.obj != indicator)
6204 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6205 cw->indicator.obj = indicator;
6206 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6210 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6213 if (cw->indicator.obj != indicator) return;
6214 cw->indicator.obj = NULL;
6215 edje_object_part_unswallow(cw->shobj, indicator);
6219 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6222 Edje_Message_Int_Set *msg;
6224 if (!cw->indicator.obj) return;
6226 cw->indicator.w = w;
6227 cw->indicator.h = h;
6229 if (!cw->shobj) return;
6231 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6235 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6236 edje_object_message_signal_process(cw->shobj);
6239 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6241 e_comp_object_map_update(Evas_Object *obj)
6244 E_Client *ec = cw->ec;
6245 E_Comp_Wl_Client_Data *cdata;
6247 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6250 int l, remain = sizeof buffer;
6253 if (e_object_is_del(E_OBJECT(ec))) return;
6254 cdata = e_client_cdata_get(ec);
6257 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6258 * when new buffer is attached.
6260 if (!cdata->buffer_ref.buffer) return;
6262 if ((!cw->redirected) ||
6263 (e_client_video_hw_composition_check(ec)) ||
6264 (!e_comp_wl_output_buffer_transform_get(ec) &&
6265 cdata->scaler.buffer_viewport.buffer.scale == 1))
6267 if (evas_object_map_enable_get(cw->effect_obj))
6269 ELOGF("TRANSFORM", "map: disable", cw->ec);
6270 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6271 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6272 evas_object_resize(cw->effect_obj, tw, th);
6279 EINA_SAFETY_ON_NULL_RETURN(map);
6281 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6287 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6289 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6290 e_map_point_image_uv_set(map, 0, x, y);
6291 l = snprintf(p, remain, "%d,%d", x, y);
6292 p += l, remain -= l;
6294 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6295 e_map_point_image_uv_set(map, 1, x, y);
6296 l = snprintf(p, remain, " %d,%d", x, y);
6297 p += l, remain -= l;
6299 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6300 e_map_point_image_uv_set(map, 2, x, y);
6301 l = snprintf(p, remain, " %d,%d", x, y);
6302 p += l, remain -= l;
6304 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6305 e_map_point_image_uv_set(map, 3, x, y);
6306 l = snprintf(p, remain, " %d,%d", x, y);
6307 p += l, remain -= l;
6309 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6311 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6313 e_comp_object_map_set(cw->effect_obj, map);
6314 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6318 /* if there's screen rotation with comp mode, then ec->effect_obj and
6319 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6321 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6322 evas_object_resize(cw->effect_obj, tw, th);
6326 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6328 API_ENTRY EINA_FALSE;
6330 cw->render_trace = set;
6336 e_comp_object_native_usable_get(Evas_Object *obj)
6338 API_ENTRY EINA_FALSE;
6339 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6341 if (cw->ec->input_only) return EINA_FALSE;
6342 if (cw->external_content) return EINA_FALSE;
6343 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6345 /* just return true value, if it is normal case */
6346 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6349 Evas_Native_Surface *ns;
6350 ns = evas_object_image_native_surface_get(cw->obj);
6352 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6355 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6363 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6365 API_ENTRY EINA_FALSE;
6366 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6367 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6368 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6372 case E_COMP_IMAGE_FILTER_BLUR:
6373 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6375 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6376 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6378 case E_COMP_IMAGE_FILTER_INVERSE:
6379 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6381 case E_COMP_IMAGE_FILTER_NONE:
6383 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6387 cw->image_filter = filter;
6392 EINTERN E_Comp_Image_Filter
6393 e_comp_object_image_filter_get(Evas_Object *obj)
6395 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6396 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6397 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6398 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6400 return cw->image_filter;
6404 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6408 if (!_damage_trace) return;
6410 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6411 evas_object_del(obj);
6413 _damage_trace_post_objs = NULL;
6417 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6419 if (!_damage_trace) return;
6421 _damage_trace_post_objs = _damage_trace_objs;
6422 _damage_trace_objs = NULL;
6426 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6428 if (_damage_trace == onoff) return;
6432 evas_event_callback_add(e_comp->evas,
6433 EVAS_CALLBACK_RENDER_PRE,
6434 _e_comp_object_damage_trace_render_pre_cb,
6437 evas_event_callback_add(e_comp->evas,
6438 EVAS_CALLBACK_RENDER_POST,
6439 _e_comp_object_damage_trace_render_post_cb,
6446 EINA_LIST_FREE(_damage_trace_objs, obj)
6447 evas_object_del(obj);
6449 _damage_trace_objs = NULL;
6451 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6452 evas_object_del(obj);
6454 _damage_trace_post_objs = NULL;
6456 evas_event_callback_del(e_comp->evas,
6457 EVAS_CALLBACK_RENDER_PRE,
6458 _e_comp_object_damage_trace_render_pre_cb);
6460 evas_event_callback_del(e_comp->evas,
6461 EVAS_CALLBACK_RENDER_POST,
6462 _e_comp_object_damage_trace_render_post_cb);
6465 _damage_trace = onoff;
6469 e_comp_object_redirected_get(Evas_Object *obj)
6471 API_ENTRY EINA_FALSE;
6472 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6474 return cw->redirected;
6478 e_comp_object_color_visible_get(Evas_Object *obj)
6480 API_ENTRY EINA_FALSE;
6483 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6485 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6489 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6493 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6497 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6505 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6507 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6509 return e_map_set_to_comp_object(em, obj);
6513 e_comp_object_map_get(const Evas_Object *obj)
6515 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6517 return e_map_get_from_comp_object(obj);
6521 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6523 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6525 evas_object_map_enable_set(obj, enable);
6531 e_comp_object_render_update_lock(Evas_Object *obj)
6533 E_Comp_Wl_Buffer *buffer;
6534 struct wayland_tbm_client_queue *cqueue;
6536 API_ENTRY EINA_FALSE;
6538 if (cw->render_update_lock.lock == 0)
6540 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6542 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6543 if ((buffer) && (buffer->resource))
6545 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6547 wayland_tbm_server_client_queue_flush(cqueue);
6550 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6551 e_comp_object_render_update_del(obj);
6553 ELOGF("COMP", "Render update lock enabled", cw->ec);
6556 cw->render_update_lock.lock++;
6562 e_comp_object_render_update_unlock(Evas_Object *obj)
6566 if (cw->render_update_lock.lock == 0)
6569 cw->render_update_lock.lock--;
6571 if (cw->render_update_lock.lock == 0)
6574 if (cw->render_update_lock.pending_move_set)
6576 evas_object_move(obj,
6577 cw->render_update_lock.pending_move_x,
6578 cw->render_update_lock.pending_move_y);
6579 cw->render_update_lock.pending_move_x = 0;
6580 cw->render_update_lock.pending_move_y = 0;
6581 cw->render_update_lock.pending_move_set = EINA_FALSE;
6584 if (cw->render_update_lock.pending_resize_set)
6586 evas_object_resize(obj,
6587 cw->render_update_lock.pending_resize_w,
6588 cw->render_update_lock.pending_resize_h);
6589 cw->render_update_lock.pending_resize_w = 0;
6590 cw->render_update_lock.pending_resize_h = 0;
6591 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6594 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6596 if ((cw->ec->exp_iconify.buffer_flush) &&
6597 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6598 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6599 e_comp_object_clear(obj);
6601 e_comp_object_render_update_add(obj);
6603 ELOGF("COMP", "Render update lock disabled", cw->ec);
6608 e_comp_object_render_update_lock_get(Evas_Object *obj)
6610 API_ENTRY EINA_FALSE;
6612 if (cw->render_update_lock.lock > 0)
6619 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6623 if (cw->transparent.set)
6625 if (r) *r = cw->transparent.user_r;
6626 if (g) *g = cw->transparent.user_g;
6627 if (b) *b = cw->transparent.user_b;
6628 if (a) *a = cw->transparent.user_a;
6632 evas_object_color_get(obj, r, g, b, a);
6637 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6641 evas_object_render_op_set(cw->obj, op);
6644 EINTERN Evas_Render_Op
6645 e_comp_object_render_op_get(Evas_Object *obj)
6647 API_ENTRY EVAS_RENDER_BLEND;
6649 return evas_object_render_op_get(cw->obj);
6653 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6656 wl_signal_add(&cw->events.lower, listener);
6659 #ifdef REFACTOR_DESK_AREA
6661 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6664 wl_signal_add(&cw->events.lower_done, listener);
6668 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6671 wl_signal_add(&cw->events.raise, listener);
6676 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6679 wl_signal_add(&cw->events.show, listener);
6683 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6686 wl_signal_add(&cw->events.hide, listener);
6689 #ifdef REFACTOR_DESK_AREA
6691 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6694 wl_signal_add(&cw->events.set_layer, listener);
6698 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6701 wl_signal_add(&cw->events.stack_above, listener);
6705 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6708 wl_signal_add(&cw->events.stack_below, listener);