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_window_intern.h"
19 #include "e_hwc_windows_intern.h"
20 #include "e_policy_visibility_intern.h"
21 #include "e_client_video_intern.h"
22 #include "e_client_intern.h"
26 = keys that return objects =
27 - E_Client: the client associated with the object (E_Client*)
28 - comp_smart_obj: cw->smart_obj (Evas_Object*)
29 - comp_obj: cw (E_Comp_Object*)
31 = keys that are bool flags =
32 - client_restack: client needs a protocol-level restack
33 - comp_override: object is triggering a nocomp override to force compositing
34 - comp_ref: object has a ref from visibility animations
35 - comp_showing: object is currently running its show animation
36 - comp_hiding: object is currently running its hiding animation
37 - comp_object: object is a compositor-created object
38 - comp_object_skip: object has a name which prohibits theme shadows
39 - comp_object-to_del: list of objects which will be deleted when this object is deleted
40 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
41 - effect_running: object is animating by external module
44 #define UPDATE_MAX 512 // same as evas
45 #define FAILURE_MAX 2 // seems reasonable
46 #define SMART_NAME "e_comp_object"
47 #define INPUT_OBJ_SMART_NAME "input_object"
49 /* for non-util functions */
50 #define API_ENTRY E_Comp_Object *cw; \
51 cw = evas_object_smart_data_get(obj); \
52 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
54 /* for util functions (obj may or may not be E_Comp_Object */
55 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
58 CRI("YOU PASSED NULL! ARGH!"); \
61 cw = evas_object_smart_data_get(obj); \
62 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
64 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
66 /* enable for lots of client size info in console output */
68 # define e_util_size_debug_set(x, y)
71 /* enable along with display-specific damage INF calls to enable render tracing
75 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
77 #define RENDER_DEBUG(...)
80 #ifdef REFACTOR_DESK_AREA
82 typedef struct _E_Comp_Object
86 int x, y, w, h; // geometry
90 E_Comp_Object_Frame client_inset;
92 Eina_Stringshare *frame_theme;
93 Eina_Stringshare *frame_name;
94 Eina_Stringshare *visibility_effect; //effect when toggling visibility
96 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
98 Evas_Object *smart_obj; // smart object
99 Evas_Object *clip; // clipper over effect object
100 Evas_Object *input_obj; // input smart object
101 Evas_Object *obj; // composite object
102 Evas_Object *frame_object; // for client frames
103 Evas_Object *shobj; // shadow object
104 Evas_Object *effect_obj; // effects object
105 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
109 } transform_bg_color;
110 Evas_Object *transform_tranp_obj;// transform transp rect obj
111 Evas_Object *default_input_obj; // default input object
112 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
113 Eina_List *obj_mirror; // extra mirror objects
114 Eina_Tiler *updates; //render update regions
115 Eina_Tiler *pending_updates; //render update regions which are about to render
117 Evas_Native_Surface *ns; //for custom gl rendering
119 struct wl_listener buffer_destroy_listener;
121 unsigned int update_count; // how many updates have happened to this obj
123 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
125 unsigned int animating; // it's busy animating
126 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
127 unsigned int force_visible; //number of visible obj_mirror objects
128 Eina_Bool delete_pending : 1; // delete pending
129 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
130 Eina_Bool showing : 1; // object is currently in "show" animation
131 Eina_Bool hiding : 1; // object is currently in "hide" animation
132 Eina_Bool visible : 1; // is visible
134 Eina_Bool shaped : 1; // is shaped
135 Eina_Bool update : 1; // has updates to fetch
136 Eina_Bool redirected : 1; // has updates to fetch
137 Eina_Bool native : 1; // native
139 Eina_Bool nocomp : 1; // nocomp applied
140 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
141 Eina_Bool real_hid : 1; // last hide was a real window unmap
143 Eina_Bool effect_set : 1; //effect_obj has a valid group
144 Eina_Bool effect_running : 1; //effect_obj is playing an animation
145 Eina_Bool effect_clip : 1; //effect_obj is clipped
146 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
148 Eina_Bool updates_exist : 1;
149 Eina_Bool updates_full : 1; // entire object will be updated
151 Eina_Bool force_move : 1;
152 Eina_Bool frame_extends : 1; //frame may extend beyond object size
153 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
154 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
155 Eina_Bool user_alpha_set : 1;
156 Eina_Bool user_alpha : 1;
160 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
161 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
168 } indicator; //indicator object for internal client
172 Evas_Object *mask_obj;
175 int mask_x, mask_y, mask_w, mask_h;
178 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
180 tbm_surface_h tbm_surface;
181 E_Comp_Image_Filter image_filter;
182 Eina_Bool set_mouse_callbacks;
187 E_Comp_Wl_Buffer_Ref buffer_ref;
188 Eina_Bool pending_move_set;
189 int pending_move_x, pending_move_y;
190 Eina_Bool pending_resize_set;
191 int pending_resize_w, pending_resize_h;
192 } render_update_lock;
205 struct wl_signal lower;
206 //#ifdef REFACTOR_DESK_AREA
207 struct wl_signal raise;
209 struct wl_signal show;
210 struct wl_signal hide;
211 //#ifdef REFACTOR_DESK_AREA
212 struct wl_signal set_layer;
213 struct wl_signal stack_above;
214 struct wl_signal stack_below;
220 typedef struct _E_Input_Rect_Data
226 typedef struct _E_Input_Rect_Smart_Data
228 Eina_List *input_rect_data_list;
230 } E_Input_Rect_Smart_Data;
232 struct E_Comp_Object_Mover
235 E_Comp_Object_Mover_Cb func;
241 static Eina_Inlist *_e_comp_object_movers = NULL;
242 static Evas_Smart *_e_comp_smart = NULL;
243 static Evas_Smart *_e_comp_input_obj_smart = NULL;
245 static int _e_comp_object_hooks_delete = 0;
246 static int _e_comp_object_hooks_walking = 0;
248 static Eina_Inlist *_e_comp_object_hooks[] =
250 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
251 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
252 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
253 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
254 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
255 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
256 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
257 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
260 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
261 static int _e_comp_object_intercept_hooks_delete = 0;
262 static int _e_comp_object_intercept_hooks_walking = 0;
264 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
266 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
267 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
271 static Eina_Bool _damage_trace = EINA_FALSE;
272 static Eina_List *_damage_trace_objs = NULL;
273 static Eina_List *_damage_trace_post_objs = NULL;
275 /* sekrit functionzzz */
276 EINTERN void e_client_focused_set(E_Client *ec);
278 /* emitted every time a new noteworthy comp object is added */
279 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
281 /* ecore event define */
282 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
283 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
284 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
286 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
287 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
288 static void _e_comp_object_dim_update(E_Comp_Object *cw);
289 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
290 #ifdef REFACTOR_DESK_AREA
292 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
295 static E_Client *dim_client = NULL;
298 _e_comp_object_hooks_clean(void)
301 E_Comp_Object_Hook *ch;
304 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
305 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
307 if (!ch->delete_me) continue;
308 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
314 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
316 E_Comp_Object_Hook *ch;
317 Eina_Bool ret = EINA_TRUE;
319 if (e_object_is_del(E_OBJECT(ec)))
321 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
322 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
323 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
324 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
325 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
326 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
327 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
328 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
334 e_object_ref(E_OBJECT(ec));
335 _e_comp_object_hooks_walking++;
336 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
338 if (ch->delete_me) continue;
339 if (!(ch->func(ch->data, ec)))
345 _e_comp_object_hooks_walking--;
346 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
347 _e_comp_object_hooks_clean();
349 e_object_unref(E_OBJECT(ec));
354 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
356 _e_comp_object_intercept_hooks_clean(void)
359 E_Comp_Object_Intercept_Hook *ch;
362 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
363 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
365 if (!ch->delete_me) continue;
366 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
372 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
374 E_Comp_Object_Intercept_Hook *ch;
375 Eina_Bool ret = EINA_TRUE;
377 if (e_object_is_del(E_OBJECT(ec))) return ret;
378 e_object_ref(E_OBJECT(ec));
379 _e_comp_object_intercept_hooks_walking++;
380 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
382 if (ch->delete_me) continue;
383 if (!(ch->func(ch->data, ec)))
389 _e_comp_object_intercept_hooks_walking--;
390 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
391 _e_comp_object_intercept_hooks_clean();
393 e_object_unref(E_OBJECT(ec));
400 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
402 E_Event_Comp_Object *ev = event;
405 ec = evas_object_data_get(ev->comp_object, "E_Client");
409 e_object_unref(E_OBJECT(ec));
411 evas_object_unref(ev->comp_object);
416 _e_comp_object_event_add(Evas_Object *obj)
418 E_Event_Comp_Object *ev;
421 if (stopping) return;
422 ev = E_NEW(E_Event_Comp_Object, 1);
423 EINA_SAFETY_ON_NULL_RETURN(ev);
425 evas_object_ref(obj);
426 ev->comp_object = obj;
427 ec = evas_object_data_get(ev->comp_object, "E_Client");
431 e_object_ref(E_OBJECT(ec));
433 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
437 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
439 E_Event_Comp_Object *ev = event;
442 ec = evas_object_data_get(ev->comp_object, "E_Client");
446 e_object_unref(E_OBJECT(ec));
448 evas_object_unref(ev->comp_object);
453 _e_comp_object_event_simple(Evas_Object *obj, int type)
455 E_Event_Comp_Object *ev;
458 ev = E_NEW(E_Event_Comp_Object, 1);
461 evas_object_ref(obj);
462 ev->comp_object = obj;
463 ec = evas_object_data_get(ev->comp_object, "E_Client");
467 e_object_ref(E_OBJECT(ec));
469 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
471 /////////////////////////////////////
474 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
476 E_Comp_Object *cw = data;
478 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
482 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
484 E_Comp_Object *cw = data;
486 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
487 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
490 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
491 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
495 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
497 E_Comp_Object *cw = data;
500 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
501 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
504 /////////////////////////////////////
506 #ifdef REFACTOR_DESK_AREA
508 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
511 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
516 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
517 if (cw->ec->input_only) return;
519 layer = evas_object_layer_get(obj);
521 if (cw->transform_bg_obj)
523 if (layer != evas_object_layer_get(cw->transform_bg_obj))
525 evas_object_layer_set(cw->transform_bg_obj, layer);
528 evas_object_stack_below(cw->transform_bg_obj, obj);
531 if (cw->transform_tranp_obj)
533 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
535 evas_object_layer_set(cw->transform_tranp_obj, layer);
538 evas_object_stack_below(cw->transform_tranp_obj, obj);
543 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
550 if (!map) return NULL;
552 e_map_util_points_populate_from_object_full(map, obj, 0);
553 e_map_util_points_color_set(map, 255, 255, 255, 255);
555 for (i = 0 ; i < 4 ; ++i)
560 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
561 e_map_point_coord_set(map, i, x, y, 1.0);
568 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
574 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
577 e_comp_object_map_set(obj, map);
578 e_comp_object_map_enable_set(obj, EINA_TRUE);
585 evas_object_map_enable_set(obj, EINA_FALSE);
590 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
596 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
599 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
601 e_comp_object_map_set(obj, map);
602 e_comp_object_map_enable_set(obj, EINA_TRUE);
609 evas_object_map_enable_set(obj, EINA_FALSE);
612 /////////////////////////////////////
614 static inline Eina_Bool
615 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
617 if (num > 1) return EINA_TRUE;
618 if ((rects[0].x == 0) && (rects[0].y == 0) &&
619 ((int)rects[0].w == w) && ((int)rects[0].h == h))
624 /////////////////////////////////////
626 /* add a client to the layer-client list */
627 #ifdef REFACTOR_DESK_AREA
630 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
632 g_rec_mutex_lock(&e_comp->ec_list_mutex);
635 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));
637 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));
638 if ((!above) && (!below))
641 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
642 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
643 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
645 e_comp->layers[cw->layer].clients_count++;
647 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
651 _e_comp_object_layers_remove(E_Comp_Object *cw)
653 g_rec_mutex_lock(&e_comp->ec_list_mutex);
655 if (cw->ec && e_comp->layers[cw->layer].clients)
657 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
658 e_comp->layers[cw->layer].clients_count--;
661 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
665 /////////////////////////////////////
667 _e_comp_object_alpha_set(E_Comp_Object *cw)
669 Eina_Bool alpha = cw->ec->argb;
671 if ((cw->external_content) &&
672 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
677 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
678 if (cw->user_alpha_set) alpha = cw->user_alpha;
680 evas_object_image_alpha_set(cw->obj, alpha);
684 _e_comp_object_shadow(E_Comp_Object *cw)
686 if (e_client_util_shadow_state_get(cw->ec))
687 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
689 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
690 if (cw->frame_object)
691 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
692 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
695 /* convert from the surface coordinates to the buffer coordinates */
697 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
699 E_Comp_Wl_Buffer_Viewport *vp;
700 E_Comp_Wl_Client_Data *cdata;
704 cdata = e_client_cdata_get(ec);
706 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
713 vp = &cdata->scaler.buffer_viewport;
714 transform = e_comp_wl_output_buffer_transform_get(ec);
716 e_pixmap_size_get(ec->pixmap, &bw, &bh);
718 /* for subsurface, it should be swap 90 and 270 */
719 if (e_comp_wl_subsurface_check(ec))
722 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
723 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
724 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
725 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
731 case WL_OUTPUT_TRANSFORM_NORMAL:
732 default: tx = sx, ty = sy; break;
733 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
734 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
735 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
736 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
737 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
738 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
739 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
742 tx *= vp->buffer.scale;
743 ty *= vp->buffer.scale;
750 _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)
758 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
759 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
766 if (dw) *dw = MAX(x1, x2) - mx;
767 if (dh) *dh = MAX(y1, y2) - my;
771 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
772 int *dx, int *dy, int *dw, int *dh)
774 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
775 E_Util_Transform_Rect_Vertex sv, dv;
779 e_pixmap_size_get(ec->pixmap, &bw, &bh);
781 sv = e_util_transform_rect_to_vertices(&rect);
783 for (i = 0; i < 4; i++)
785 double x = 0.0, y = 0.0;
787 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
789 /* if evas decide coordinate is outside of map, it returns (0, 0)
790 in this case, full damage is added.
792 if ((i != 0) && (x == 0.0) && (y == 0.0))
795 dv.vertices[i].vertex[0] = x;
796 dv.vertices[i].vertex[1] = y;
797 dv.vertices[i].vertex[2] = 1.0;
798 dv.vertices[i].vertex[3] = 1.0;
801 rect = e_util_transform_vertices_to_rect(&dv);
803 if (dx) *dx = rect.x;
804 if (dy) *dy = rect.y;
805 if (dw) *dw = rect.w;
806 if (dh) *dh = rect.h;
820 _e_comp_object_map_damage_transform_get(E_Client *ec)
827 if (!e_client_transform_core_enable_get(ec))
830 m = e_client_map_get(ec);
834 e_pixmap_size_get(ec->pixmap, &bw, &bh);
835 if ((bw == 0) || (bh == 0))
848 e_map_point_coord_set(m2, 0, 0, 0, 0);
849 e_map_point_coord_set(m2, 1, bw, 0, 0);
850 e_map_point_coord_set(m2, 2, bw, bh, 0);
851 e_map_point_coord_set(m2, 3, 0, bh, 0);
853 for (i = 0; i < 4; i++)
857 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
858 e_map_point_image_uv_set(m2, i, map_x, map_y);
865 /////////////////////////////////////
867 /* handle evas mouse-in events on client object */
869 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
871 Evas_Event_Mouse_In *ev = event_info;
872 E_Comp_Object *cw = data;
874 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
877 /* handle evas mouse-out events on client object */
879 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
881 Evas_Event_Mouse_Out *ev = event_info;
882 E_Comp_Object *cw = data;
884 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
887 /* handle evas mouse wheel events on client object */
889 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
891 Evas_Event_Mouse_Wheel *ev = event_info;
892 E_Comp_Object *cw = data;
893 E_Binding_Event_Wheel ev2;
896 if (e_client_action_get()) return;
897 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
898 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
901 /* handle evas mouse down events on client object */
903 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
905 Evas_Event_Mouse_Down *ev = event_info;
906 E_Comp_Object *cw = data;
907 E_Binding_Event_Mouse_Button ev2;
910 if (e_client_action_get()) return;
911 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
912 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
915 /* handle evas mouse up events on client object */
917 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
919 Evas_Event_Mouse_Up *ev = event_info;
920 E_Comp_Object *cw = data;
921 E_Binding_Event_Mouse_Button ev2;
924 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
925 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
926 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
929 /* handle evas mouse movement events on client object */
931 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
933 Evas_Event_Mouse_Move *ev = event_info;
934 E_Comp_Object *cw = data;
937 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
938 e_client_mouse_move(cw->ec, &ev->cur.output);
940 /////////////////////////////////////
942 /* helper function for checking compositor themes based on user-defined matches */
944 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
946 if (((m->title) && (!ec->netwm.name)) ||
947 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
949 #if defined(__cplusplus) || defined(c_plusplus)
950 if (((m->clas) && (!ec->icccm.cpp_class)) ||
951 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
954 if (((m->clas) && (!ec->icccm.class)) ||
955 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
959 if (((m->role) && (!ec->icccm.window_role)) ||
960 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
966 if ((int)ec->netwm.type != m->primary_type)
969 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
972 if (m->borderless != 0)
976 if (e_client_util_borderless(ec))
978 if (!(((m->borderless == -1) && (!borderless)) ||
979 ((m->borderless == 1) && (borderless))))
986 if (((ec->icccm.transient_for != 0) ||
989 if (!(((m->dialog == -1) && (!dialog)) ||
990 ((m->dialog == 1) && (dialog))))
993 if (m->accepts_focus != 0)
995 int accepts_focus = 0;
997 if (ec->icccm.accepts_focus)
999 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
1000 ((m->accepts_focus == 1) && (accepts_focus))))
1009 if (!(((m->vkbd == -1) && (!vkbd)) ||
1010 ((m->vkbd == 1) && (vkbd))))
1015 if (!(((m->argb == -1) && (!ec->argb)) ||
1016 ((m->argb == 1) && (ec->argb))))
1019 if (m->fullscreen != 0)
1021 int fullscreen = ec->fullscreen;
1023 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1024 ((m->fullscreen == 1) && (fullscreen))))
1029 if (!(m->modal == -1))
1035 /* function for setting up a client's compositor frame theme (cw->shobj) */
1037 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1041 Eina_List *list = NULL, *l;
1042 E_Input_Rect_Data *input_rect_data;
1043 E_Input_Rect_Smart_Data *input_rect_sd;
1045 Eina_Stringshare *reshadow_group = NULL;
1046 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1047 Eina_Stringshare *name, *title;
1048 E_Comp_Config *conf = e_comp_config_get();
1050 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1051 /* match correct client type */
1052 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1053 name = cw->ec->icccm.name;
1054 title = cw->ec->icccm.title;
1055 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1056 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1058 /* skipping here is mostly a hack for systray because I hate it */
1061 EINA_LIST_FOREACH(list, l, m)
1063 if (((m->name) && (!name)) ||
1064 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1066 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1069 no_shadow = m->no_shadow;
1070 if (m->shadow_style)
1072 /* fast effects are just themes with "/fast" appended and shorter effect times */
1075 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1076 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1078 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1080 /* default to non-fast style if fast not available */
1083 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1084 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1086 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1088 if (ok && m->visibility_effect)
1089 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1096 if (skip || (cw->ec->e.state.video))
1098 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1103 if (conf->shadow_style)
1107 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1108 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1110 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1114 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1115 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1117 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1124 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1126 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1130 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1132 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1137 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1142 if (cw->ec->override)
1144 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1145 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1147 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1148 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1154 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1155 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1158 _e_comp_object_shadow(cw);
1161 if (focus || cw->ec->focused || cw->ec->override)
1162 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1168 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1169 /* visibility must always be enabled for re_manage clients to prevent
1170 * pop-in animations every time the user sees a persistent client again;
1171 * applying visibility for iconic clients prevents the client from getting
1174 if (cw->visible || cw->ec->re_manage)
1175 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1177 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1179 /* breaks animation counter */
1180 if (cw->frame_object)
1182 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1183 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1184 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1185 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1191 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1195 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1198 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1200 if (input_rect_data->obj)
1202 pass_event_flag = EINA_TRUE;
1208 if (cw->indicator.obj)
1210 Evas_Object *indicator;
1211 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1212 if (indicator != cw->indicator.obj)
1214 edje_object_part_unswallow(cw->shobj, indicator);
1215 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1216 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1220 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1221 evas_object_pass_events_set(cw->obj, pass_event_flag);
1226 /////////////////////////////////////////////
1229 _e_comp_object_animating_begin(E_Comp_Object *cw)
1232 if (cw->animating == 1)
1234 e_comp->animating++;
1236 e_object_ref(E_OBJECT(cw->ec));
1241 _e_comp_object_animating_end(E_Comp_Object *cw)
1250 if (cw->ec->launching)
1252 if (!cw->ec->extra_animating)
1254 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1255 cw->ec->launching = EINA_FALSE;
1256 if (cw->ec->first_mapped)
1258 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1259 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1262 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1266 e_comp->animating--;
1267 cw->showing = cw->hiding = 0;
1269 if (e_comp->animating == 0)
1270 e_comp_visibility_calculation_set(EINA_TRUE);
1271 /* remove ref from animation start, account for possibility of deletion from unref */
1272 return !!e_object_unref(E_OBJECT(cw->ec));
1278 /* handle the end of a compositor animation */
1280 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1282 E_Comp_Object *cw = data;
1284 /* visible clients which have never been sized are a bug */
1285 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1286 CRI("ACK! ec:%p", cw->ec);
1287 if (!_e_comp_object_animating_end(cw)) return;
1288 if (cw->animating) return;
1289 /* hide only after animation finishes to guarantee a full run of the animation */
1290 if (!cw->defer_hide) return;
1291 if ((!strcmp(emission, "e,action,hide,done")) ||
1292 (!strcmp(emission, "e,action,done")) ||
1293 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1295 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1296 evas_object_hide(cw->smart_obj);
1300 /* run a visibility compositor effect if available, return false if object is dead */
1302 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1308 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1309 if (!cw->effect_running)
1310 _e_comp_object_animating_begin(cw);
1311 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1312 return _e_comp_object_animating_end(cw);
1313 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1314 return _e_comp_object_animating_end(cw);
1316 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1319 zone = e_comp_zone_find_by_ec(cw->ec);
1321 zw = zone->w, zh = zone->h;
1326 zone = e_comp_object_util_zone_get(cw->smart_obj);
1327 if (!zone) zone = e_zone_current_get();
1334 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1335 cw->w, cw->h, zw, zh, x, y}, 8);
1336 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1337 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1340 /////////////////////////////////////////////
1342 /* create necessary objects for clients that e manages */
1344 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1346 if (cw->set_mouse_callbacks) return;
1347 if (!cw->smart_obj) return;
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1350 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1351 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1352 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1353 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1354 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1356 cw->set_mouse_callbacks = EINA_TRUE;
1360 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1362 if (!cw->set_mouse_callbacks) return;
1363 if (!cw->smart_obj) return;
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1366 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1367 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1368 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1369 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1370 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1372 cw->set_mouse_callbacks = EINA_FALSE;
1376 _e_comp_object_setup(E_Comp_Object *cw)
1378 cw->clip = evas_object_rectangle_add(e_comp->evas);
1379 evas_object_move(cw->clip, -9999, -9999);
1380 evas_object_resize(cw->clip, 999999, 999999);
1381 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1382 cw->effect_obj = edje_object_add(e_comp->evas);
1383 evas_object_move(cw->effect_obj, cw->x, cw->y);
1384 evas_object_clip_set(cw->effect_obj, cw->clip);
1385 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1386 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1387 cw->shobj = edje_object_add(e_comp->evas);
1388 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1389 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1390 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1392 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1393 if (cw->ec->override)
1395 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1396 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1397 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1399 else if (!cw->ec->input_only)
1401 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1402 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1403 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1405 cw->real_hid = !cw->ec->input_only;
1406 if (!cw->ec->input_only)
1408 e_util_size_debug_set(cw->effect_obj, 1);
1409 _e_comp_object_mouse_event_callback_set(cw);
1412 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1413 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1414 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1415 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1416 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1417 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1419 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1422 /////////////////////////////////////////////
1424 /* for fast path evas rendering; only called during render */
1426 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1428 E_Comp_Object *cw = data;
1429 E_Client *ec = cw->ec;
1431 int bx, by, bxx, byy;
1433 if (e_object_is_del(E_OBJECT(ec))) return;
1434 if (cw->external_content) return;
1435 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1436 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1439 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1440 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1442 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1444 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1445 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1449 bx = by = bxx = byy = 0;
1450 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1453 Edje_Message_Int_Set *msg;
1454 Edje_Message_Int msg2;
1455 Eina_Bool id = (bx || by || bxx || byy);
1457 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1463 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1465 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1469 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1470 e_comp_client_post_update_add(cw->ec);
1472 else if (e_comp_object_render(ec->frame))
1474 /* apply shape mask if necessary */
1475 if ((!cw->native) && (ec->shaped))
1476 e_comp_object_shape_apply(ec->frame);
1478 /* shaped clients get precise mouse events to handle transparent pixels */
1479 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1481 /* queue another render if client is still dirty; cannot refresh here. */
1482 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1483 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1485 if (cw->render_trace)
1487 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1493 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1495 E_Comp_Object *cw = data;
1496 E_Client *ec = cw->ec;
1498 if (e_object_is_del(E_OBJECT(ec))) return;
1499 if (cw->external_content) return;
1500 if (!e_comp->hwc) return;
1502 e_comp_client_render_list_add(cw->ec);
1504 if (!ec->hwc_window) return;
1506 e_hwc_windows_rendered_window_add(ec->hwc_window);
1509 /////////////////////////////////////////////
1512 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1514 E_Comp_Object *cw = data;
1517 if (cw->render_update_lock.lock)
1519 cw->render_update_lock.pending_move_x = x;
1520 cw->render_update_lock.pending_move_y = y;
1521 cw->render_update_lock.pending_move_set = EINA_TRUE;
1525 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1526 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1527 (cw->external_content))
1529 /* delay to move until the external content is unset */
1530 cw->ec->changes.pos = 1;
1535 if (cw->ec->move_after_resize)
1537 if ((x != cw->ec->x) || (y != cw->ec->y))
1539 if (!cw->ec->is_cursor)
1540 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1541 e_client_pos_set(cw->ec, x, y);
1542 cw->ec->changes.pos = 1;
1548 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1549 (cw->ec->manage_resize.resize_obj))
1551 e_client_pos_set(cw->ec, x, y);
1552 cw->ec->client.x = x + cw->client_inset.l;
1553 cw->ec->client.y = y + cw->client_inset.t;
1554 e_policy_visibility_client_defer_move(cw->ec);
1558 /* if frame_object does not exist, client_inset indicates CSD.
1559 * this means that ec->client matches cw->x/y, the opposite
1562 fx = (!cw->frame_object) * cw->client_inset.l;
1563 fy = (!cw->frame_object) * cw->client_inset.t;
1564 if ((cw->x == x + fx) && (cw->y == y + fy))
1566 if ((cw->ec->x != x) || (cw->ec->y != y))
1568 /* handle case where client tries to move to position and back very quickly */
1569 e_client_pos_set(cw->ec, x, y);
1570 cw->ec->client.x = x + cw->client_inset.l;
1571 cw->ec->client.y = y + cw->client_inset.t;
1575 if (!cw->ec->maximize_override)
1577 /* prevent moving in some directions while directionally maximized */
1578 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1580 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1583 ix = x + cw->client_inset.l;
1584 iy = y + cw->client_inset.t;
1585 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1586 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1587 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1589 /* prevent moving at all if move isn't allowed in current maximize state */
1590 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1591 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1594 zone = e_comp_zone_find_by_ec(cw->ec);
1597 cw->ec->changes.need_unmaximize = 1;
1598 cw->ec->saved.x = ix - zone->x;
1599 cw->ec->saved.y = iy - zone->y;
1600 cw->ec->saved.w = cw->ec->client.w;
1601 cw->ec->saved.h = cw->ec->client.h;
1605 /* only update during resize if triggered by resize */
1606 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1607 /* delay to move while surface waits paired commit serial*/
1608 if (e_client_pending_geometry_has(cw->ec))
1610 /* do nothing while waiting paired commit serial*/
1614 e_client_pos_set(cw->ec, x, y);
1615 if (cw->ec->new_client)
1617 /* don't actually do anything until first client idler loop */
1618 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1619 cw->ec->changes.pos = 1;
1624 /* only update xy position of client to avoid invalid
1625 * first damage region if it is not a new_client. */
1626 cw->ec->client.x = ix;
1627 cw->ec->client.y = iy;
1630 if (!cw->frame_object)
1632 evas_object_move(obj, x, y);
1637 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1639 E_Comp_Object *cw = data;
1640 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1643 if (cw->render_update_lock.lock)
1645 cw->render_update_lock.pending_resize_w = w;
1646 cw->render_update_lock.pending_resize_h = h;
1647 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1651 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1653 e_client_size_set(cw->ec, w, h);
1654 evas_object_resize(obj, w, h);
1658 /* if frame_object does not exist, client_inset indicates CSD.
1659 * this means that ec->client matches cw->w/h, the opposite
1662 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1663 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1664 if ((cw->w == w + fw) && (cw->h == h + fh))
1666 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1667 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1668 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1670 /* handle case where client tries to resize itself and back very quickly */
1671 e_client_size_set(cw->ec, w, h);
1672 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1673 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1674 evas_object_smart_callback_call(obj, "client_resize", NULL);
1678 /* guarantee that fullscreen is fullscreen */
1679 zone = e_comp_zone_find_by_ec(cw->ec);
1681 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1683 if (!e_client_transform_core_enable_get(cw->ec))
1686 /* calculate client size */
1687 iw = w - cw->client_inset.l - cw->client_inset.r;
1688 ih = h - cw->client_inset.t - cw->client_inset.b;
1689 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1691 /* prevent resizing while maximized depending on direction and config */
1692 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1694 Eina_Bool reject = EINA_FALSE;
1695 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1697 if (cw->ec->client.h != ih)
1699 cw->ec->saved.h = ih;
1700 cw->ec->saved.y = cw->ec->client.y - zone->y;
1701 reject = cw->ec->changes.need_unmaximize = 1;
1704 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1706 if (cw->ec->client.w != iw)
1708 cw->ec->saved.w = iw;
1709 cw->ec->saved.x = cw->ec->client.x - zone->x;
1710 reject = cw->ec->changes.need_unmaximize = 1;
1719 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1721 /* do nothing until client idler loops */
1722 if ((cw->ec->w != w) || (cw->ec->h != h))
1724 e_client_size_set(cw->ec, w, h);
1725 cw->ec->changes.size = 1;
1730 if (e_client_pending_geometry_has(cw->ec))
1732 /* do nothing while waiting paired commit serial*/
1736 e_client_size_set(cw->ec, w, h);
1738 cw->ec->client.w = iw;
1739 cw->ec->client.h = ih;
1740 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1742 /* The size of non-compositing window can be changed, so there is a
1743 * need to check that cw is H/W composited if cw is not redirected.
1744 * And of course we have to change size of evas object of H/W composited cw,
1745 * otherwise cw can't receive input events even if it is shown on the screen.
1747 Eina_Bool redirected = cw->redirected;
1749 redirected = e_comp_is_on_overlay(cw->ec);
1751 if ((!cw->ec->input_only) && (redirected) &&
1752 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1753 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1754 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1755 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1758 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1759 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1761 prev_w = cw->w, prev_h = cw->h;
1762 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1763 /* check shading and clamp to pixmap size for regular clients */
1764 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1765 (((w - fw != pw) || (h - fh != ph))))
1767 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1768 evas_object_smart_callback_call(obj, "client_resize", NULL);
1770 if (cw->frame_object || cw->ec->input_only)
1771 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1774 if ((cw->w == w) && (cw->h == h))
1776 /* going to be a noop resize which won't trigger smart resize */
1777 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1778 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1780 evas_object_resize(obj, w, h);
1784 evas_object_smart_callback_call(obj, "client_resize", NULL);
1787 if ((!cw->frame_object) && (!cw->ec->input_only))
1789 /* "just do it" for overrides */
1790 evas_object_resize(obj, w, h);
1792 if (!cw->ec->override)
1794 /* shape probably changed for non-overrides */
1799 /* this fixes positioning jiggles when using a resize mode
1800 * which also changes the client's position
1803 if (cw->frame_object)
1804 x = cw->x, y = cw->y;
1806 x = cw->ec->x, y = cw->ec->y;
1807 switch (cw->ec->resize_mode)
1809 case E_POINTER_RESIZE_BL:
1810 case E_POINTER_RESIZE_L:
1811 evas_object_move(obj, x + prev_w - cw->w, y);
1813 case E_POINTER_RESIZE_TL:
1814 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1816 case E_POINTER_RESIZE_T:
1817 case E_POINTER_RESIZE_TR:
1818 evas_object_move(obj, x, y + prev_h - cw->h);
1827 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1829 #ifdef REFACTOR_DESK_AREA
1830 E_Comp_Object *cw = data;
1831 E_Comp_Object_Data_Set_Layer layer_set_data;
1833 layer_set_data.cw = cw;
1834 layer_set_data.layer = layer;
1836 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1840 e_comp_render_queue();
1841 _e_comp_object_transform_obj_stack_update(obj);
1845 E_Comp_Object *cw = data;
1846 E_Comp_Wl_Client_Data *child_cdata;
1847 unsigned int l = e_comp_canvas_layer_map(layer);
1850 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1852 /* doing a compositor effect, follow directions */
1853 _e_comp_object_layer_set(obj, layer);
1854 if (layer == cw->ec->layer) //trying to put layer back
1858 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1859 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1860 if (cw->layer != l) goto layer_set;
1864 e_comp_render_queue();
1866 ec = e_client_above_get(cw->ec);
1867 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1868 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1869 ec = e_client_above_get(ec);
1870 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1872 ec = e_client_below_get(cw->ec);
1873 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1874 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1875 ec = e_client_below_get(ec);
1876 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1878 evas_object_stack_above(obj, ec->frame);
1883 if (ec && (cw->ec->parent == ec))
1885 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1886 evas_object_stack_above(obj, ec->frame);
1888 evas_object_stack_below(obj, ec->frame);
1891 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1897 if (cw->layer == l) return;
1898 if (e_comp_canvas_client_layer_map(layer) == 9999)
1899 return; //invalid layer for clients not doing comp effects
1900 if (cw->ec->fullscreen)
1902 cw->ec->saved.layer = layer;
1905 oldraise = e_config->transient.raise;
1907 /* clamp to valid client layer */
1908 layer = e_comp_canvas_client_layer_map_nearest(layer);
1909 cw->ec->layer = layer;
1910 if (e_config->transient.layer)
1913 Eina_List *list = eina_list_clone(cw->ec->transients);
1915 /* We need to set raise to one, else the child wont
1916 * follow to the new layer. It should be like this,
1917 * even if the user usually doesn't want to raise
1920 e_config->transient.raise = 1;
1921 EINA_LIST_FREE(list, child)
1923 child_cdata = e_client_cdata_get(child);
1924 if (child_cdata && !child_cdata->mapped)
1926 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1929 e_client_layer_set(child, layer);
1933 e_config->transient.raise = oldraise;
1935 _e_comp_object_layers_remove(cw);
1936 cw->layer = e_comp_canvas_layer_map(layer);
1937 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1938 //if (cw->ec->new_client)
1939 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1940 _e_comp_object_layer_set(obj, layer);
1941 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1942 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1943 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1945 /* can't stack a client above its own layer marker */
1946 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1948 if (!cw->visible) return;
1949 e_comp_render_queue();
1950 _e_comp_object_transform_obj_stack_update(obj);
1954 #ifdef REFACTOR_DESK_AREA
1956 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1959 #ifdef REFACTOR_DESK_AREA
1961 _e_comp_object_raise(Evas_Object *obj)
1964 _e_comp_object_raise(Evas_Object *obj)
1967 evas_object_raise(obj);
1969 if (evas_object_smart_smart_get(obj))
1971 E_Client *ec = e_comp_object_client_get(obj);
1973 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1977 #ifdef REFACTOR_DESK_AREA
1979 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1982 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1985 evas_object_lower(obj);
1987 if (evas_object_smart_smart_get(obj))
1989 E_Client *ec = e_comp_object_client_get(obj);
1992 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1993 #ifdef REFACTOR_DESK_AREA
1994 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1996 wl_signal_emit_mutable(&cw->events.lower, NULL);
2002 #ifdef REFACTOR_DESK_AREA
2004 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2007 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2010 evas_object_stack_above(obj, target);
2012 if (evas_object_smart_smart_get(obj))
2014 E_Client *ec = e_comp_object_client_get(obj);
2016 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2020 #ifdef REFACTOR_DESK_AREA
2022 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2025 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2028 evas_object_stack_below(obj, target);
2030 if (evas_object_smart_smart_get(obj))
2032 E_Client *ec = e_comp_object_client_get(obj);
2034 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2038 #ifdef REFACTOR_DESK_AREA
2040 e_comp_object_layer_set(Evas_Object *obj, short layer)
2043 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2046 evas_object_layer_set(obj, layer);
2048 if (evas_object_smart_smart_get(obj))
2050 E_Client *ec = e_comp_object_client_get(obj);
2052 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2056 #ifdef REFACTOR_DESK_AREA
2059 _e_comp_object_is_pending(E_Client *ec)
2063 if (!ec) return EINA_FALSE;
2065 topmost = e_comp_wl_topmost_parent_get(ec);
2067 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2071 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2073 E_Comp_Object *cw2 = NULL;
2076 Evas_Object *o = stack;
2077 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2079 /* We should consider topmost's layer_pending for subsurface */
2080 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2082 if (_e_comp_object_is_pending(cw->ec))
2083 e_comp_object_layer_update(cw->smart_obj,
2084 raising? stack : NULL,
2085 raising? NULL : stack);
2087 /* obey compositor effects! */
2088 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2089 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2090 stack_cb(cw->smart_obj, stack);
2091 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2092 evas_object_data_del(cw->smart_obj, "client_restack");
2096 cw2 = evas_object_data_get(o, "comp_obj");
2098 /* assume someone knew what they were doing during client init */
2099 if (cw->ec->new_client)
2100 layer = cw->ec->layer;
2101 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2102 layer = cw2->ec->layer;
2104 layer = evas_object_layer_get(stack);
2105 ecstack = e_client_below_get(cw->ec);
2106 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2108 evas_object_layer_set(cw->smart_obj, layer);
2109 /* we got our layer wrangled, return now! */
2110 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2113 /* check if we're stacking below another client */
2116 /* check for non-client layer object */
2117 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2119 /* find an existing client to use for layering
2120 * by walking up the object stack
2122 * this is guaranteed to be pretty quick since we'll either:
2123 * - run out of client layers
2124 * - find a stacking client
2126 o = evas_object_above_get(o);
2127 if ((!o) || (o == cw->smart_obj)) break;
2128 if (evas_object_layer_get(o) != layer)
2130 /* reached the top client layer somehow
2131 * use top client object
2133 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2136 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2137 * return here since the top client layer window
2142 ec = e_client_top_get();
2147 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2150 if (cw2 && cw->layer != cw2->layer)
2153 /* remove existing layers */
2154 _e_comp_object_layers_remove(cw);
2157 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2158 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2159 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2160 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2161 else //if no stacking objects found, either raise or lower
2162 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2165 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2167 /* find new object for stacking if cw2 is on state of layer_pending */
2168 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2170 E_Client *new_stack = NULL, *current_ec = NULL;
2171 current_ec = cw2->ec;
2174 while ((new_stack = e_client_below_get(current_ec)))
2176 current_ec = new_stack;
2177 if (new_stack == cw->ec) continue;
2178 if (new_stack->layer != cw2->ec->layer) break;
2179 if (!_e_comp_object_is_pending(new_stack)) break;
2181 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2182 stack = new_stack->frame;
2185 /* stack it above layer object */
2187 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2188 stack = e_comp->layers[below_layer].obj;
2193 while ((new_stack = e_client_above_get(current_ec)))
2195 current_ec = new_stack;
2196 if (new_stack == cw->ec) continue;
2197 if (new_stack->layer != cw2->ec->layer) break;
2198 if (!_e_comp_object_is_pending(new_stack)) break;
2200 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2201 stack = new_stack->frame;
2203 stack = e_comp->layers[cw2->layer].obj;
2207 /* set restack if stacking has changed */
2208 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2209 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2210 stack_cb(cw->smart_obj, stack);
2211 if (e_comp->layers[cw->layer].obj)
2212 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2214 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2216 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2217 evas_object_data_del(cw->smart_obj, "client_restack");
2218 if (!cw->visible) return;
2219 e_comp_render_queue();
2224 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2226 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2228 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2230 #ifdef REFACTOR_DESK_AREA
2231 E_Comp_Object *cw = data;
2232 E_Comp_Object_Data_Stack_Above stack_above_data;
2234 stack_above_data.cw = cw;
2235 stack_above_data.above_obj = above;
2237 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2239 if (evas_object_below_get(obj) == above)
2241 e_comp_object_layer_update(obj, above, NULL);
2245 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2247 _e_comp_object_transform_obj_stack_update(obj);
2248 _e_comp_object_transform_obj_stack_update(above);
2255 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2257 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2259 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2261 #ifdef REFACTOR_DESK_AREA
2262 E_Comp_Object *cw = data;
2263 E_Comp_Object_Data_Stack_Below stack_below_data;
2265 stack_below_data.cw = cw;
2266 stack_below_data.below_obj = below;
2268 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2271 e_comp_render_queue();
2273 if (evas_object_above_get(obj) == below)
2275 e_comp_object_layer_update(obj, NULL, below);
2279 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2281 if (evas_object_smart_smart_get(obj))
2282 _e_comp_object_transform_obj_stack_update(obj);
2283 if (evas_object_smart_smart_get(below))
2284 _e_comp_object_transform_obj_stack_update(below);
2291 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2293 E_Comp_Object *cw = data;
2295 #ifdef REFACTOR_DESK_AREA
2300 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2302 #ifdef REFACTOR_DESK_AREA
2303 wl_signal_emit_mutable(&cw->events.lower, cw);
2305 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2307 if (cw->ec->layer_pending)
2308 e_comp_object_layer_update(obj, NULL, obj);
2310 _e_comp_object_lower(cw, obj);
2313 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2314 o = evas_object_below_get(obj);
2315 _e_comp_object_layers_remove(cw);
2316 /* prepend to client list since this client should be the first item now */
2317 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2318 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2319 evas_object_data_set(obj, "client_restack", (void*)1);
2320 _e_comp_object_lower(cw, obj);
2321 evas_object_data_del(obj, "client_restack");
2322 if (!cw->visible) goto end;
2323 e_comp_render_queue();
2324 _e_comp_object_transform_obj_stack_update(obj);
2332 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2334 E_Comp_Object *cw = data;
2335 #ifdef REFACTOR_DESK_AREA
2341 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2343 #ifdef REFACTOR_DESK_AREA
2344 wl_signal_emit_mutable(&cw->events.raise, cw);
2346 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2348 if (cw->ec->layer_pending)
2350 int obj_layer = evas_object_layer_get(obj);
2351 if (cw->ec->layer != obj_layer)
2352 e_comp_object_layer_update(obj, NULL, NULL);
2355 _e_comp_object_raise(obj);
2358 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2359 o = evas_object_above_get(obj);
2360 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2362 /* still stack below override below the layer marker */
2363 for (op = o = e_comp->layers[cw->layer].obj;
2364 o && o != e_comp->layers[cw->layer - 1].obj;
2365 op = o, o = evas_object_below_get(o))
2367 if (evas_object_smart_smart_get(o))
2371 ec = e_comp_object_client_get(o);
2372 if (ec && (!ec->override)) break;
2375 _e_comp_object_stack_below(obj, op);
2376 e_client_focus_defer_set(cw->ec);
2378 if (!cw->visible) goto end;
2379 e_comp_render_queue();
2380 _e_comp_object_transform_obj_stack_update(obj);
2388 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2390 E_Comp_Object *cw = data;
2392 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2393 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2395 ELOGF("COMP", "Hide. intercepted", cw->ec);
2400 if (cw->ec->launching == EINA_TRUE)
2402 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2403 cw->ec->launching = EINA_FALSE;
2408 /* hidden flag = just do it */
2409 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2410 evas_object_hide(obj);
2412 wl_signal_emit_mutable(&cw->events.hide, NULL);
2417 if (cw->ec->input_only)
2419 /* input_only = who cares */
2420 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2421 evas_object_hide(obj);
2423 wl_signal_emit_mutable(&cw->events.hide, NULL);
2427 /* already hidden or currently animating */
2428 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2430 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2434 /* don't try hiding during shutdown */
2435 cw->defer_hide |= stopping;
2436 if (!cw->defer_hide)
2438 if ((!cw->ec->iconic) && (!cw->ec->override))
2439 /* unset delete requested so the client doesn't break */
2440 cw->ec->delete_requested = 0;
2441 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2443 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2444 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2447 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2450 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2452 _e_comp_object_animating_begin(cw);
2453 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2455 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2456 cw->defer_hide = !!cw->animating;
2458 e_comp_object_effect_set(obj, NULL);
2461 if (cw->animating) return;
2462 /* if we have no animations running, go ahead and hide */
2464 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2465 evas_object_hide(obj);
2467 wl_signal_emit_mutable(&cw->events.hide, NULL);
2471 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2473 E_Client *ec = cw->ec;
2476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2478 if (ec->show_pending.count > 0)
2480 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2481 ec->show_pending.running = EINA_TRUE;
2485 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2486 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2488 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2493 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,
2494 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2495 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2498 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2501 if (ec->iconic && cw->animating)
2503 /* triggered during iconify animation */
2504 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2507 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2510 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2511 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2513 evas_object_move(cw->smart_obj, ec->x, ec->y);
2514 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2515 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2517 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2518 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2521 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2522 evas_object_show(cw->smart_obj);
2525 e_client_focus_defer_set(ec);
2529 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2533 pw = ec->client.w, ph = ec->client.h;
2535 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2537 ec->changes.visible = !ec->hidden;
2540 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2544 cw->updates = eina_tiler_new(pw, ph);
2547 ec->changes.visible = !ec->hidden;
2550 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2555 eina_tiler_tile_size_set(cw->updates, 1, 1);
2558 /* ignore until client idler first run */
2559 ec->changes.visible = !ec->hidden;
2562 ELOGF("COMP", "show_helper. return. new_client", ec);
2569 evas_object_move(cw->smart_obj, ec->x, ec->y);
2570 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2571 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2572 evas_object_show(cw->smart_obj);
2575 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2577 /* start_drag not received */
2578 ec->changes.visible = 1;
2581 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2584 /* re-set geometry */
2585 evas_object_move(cw->smart_obj, ec->x, ec->y);
2586 /* force resize in case it hasn't happened yet, or just to update size */
2587 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2588 if ((cw->w < 1) || (cw->h < 1))
2590 /* if resize didn't go through, try again */
2591 ec->visible = ec->changes.visible = 1;
2593 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2596 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2597 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2598 e_pixmap_clear(ec->pixmap);
2600 if (cw->real_hid && w && h)
2603 /* force comp theming in case it didn't happen already */
2604 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2605 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2606 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2609 /* only do the show if show is allowed */
2612 if (ec->internal) //internal clients render when they feel like it
2613 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2615 if (!e_client_is_iconified_by_client(ec)||
2616 e_policy_visibility_client_is_uniconic(ec))
2618 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2619 evas_object_show(cw->smart_obj);
2621 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2622 it is rendered in idle callback without native surface and
2623 compositor shows an empty frame if other objects aren't shown
2624 because job callback of e_comp called at the next loop.
2625 it causes a visual defect when windows are switched.
2629 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2630 e_comp_object_dirty(cw->smart_obj);
2631 e_comp_object_render(cw->smart_obj);
2636 wl_signal_emit_mutable(&cw->events.show, NULL);
2640 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2642 E_Comp_Object *cw = data;
2643 E_Client *ec = cw->ec;
2645 E_Input_Rect_Data *input_rect_data;
2646 E_Input_Rect_Smart_Data *input_rect_sd;
2649 if (ec->ignored) return;
2653 //INF("SHOW2 %p", ec);
2654 _e_comp_intercept_show_helper(cw);
2657 //INF("SHOW %p", ec);
2660 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2661 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2662 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2663 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2667 if ((!cw->obj) && (cw->external_content))
2669 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2673 _e_comp_object_setup(cw);
2676 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2677 cw->obj = evas_object_image_filled_add(e_comp->evas);
2678 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2679 e_util_size_debug_set(cw->obj, 1);
2680 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2681 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2682 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2683 evas_object_name_set(cw->obj, "cw->obj");
2684 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2686 _e_comp_object_alpha_set(cw);
2689 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2692 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2693 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2696 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2699 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2701 if (input_rect_data->obj)
2703 evas_object_geometry_set(input_rect_data->obj,
2704 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2705 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2706 input_rect_data->rect.w, input_rect_data->rect.h);
2713 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2715 _e_comp_intercept_show_helper(cw);
2719 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2721 E_Comp_Object *cw = data;
2725 /* note: this is here as it seems there are enough apps that do not even
2726 * expect us to emulate a look of focus but not actually set x input
2727 * focus as we do - so simply abort any focus set on such windows */
2728 /* be strict about accepting focus hint */
2729 /* be strict about accepting focus hint */
2730 if ((!ec->icccm.accepts_focus) &&
2731 (!ec->icccm.take_focus))
2735 if (e_client_focused_get() == ec)
2736 e_client_focused_set(NULL);
2738 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2739 evas_object_focus_set(obj, focus);
2743 if (focus && ec->lock_focus_out) return;
2744 if (e_object_is_del(E_OBJECT(ec)) && focus)
2745 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2747 /* filter focus setting based on current state */
2752 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2753 evas_object_focus_set(obj, focus);
2756 if ((ec->iconic) && (!ec->deskshow))
2758 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2760 /* don't focus an iconified window. that's silly! */
2761 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2762 e_client_uniconify(ec);
2763 e_client_focus_latest_set(ec);
2777 /* not yet visible, wait till the next time... */
2778 ec->want_focus = !ec->hidden;
2783 e_client_focused_set(ec);
2787 if (e_client_focused_get() == ec)
2788 e_client_focused_set(NULL);
2792 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2794 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2796 evas_object_focus_set(obj, focus);
2800 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2802 E_Comp_Object *cw = data;
2804 if (cw->transparent.set)
2806 cw->transparent.user_r = r;
2807 cw->transparent.user_g = g;
2808 cw->transparent.user_b = b;
2809 cw->transparent.user_a = a;
2811 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2813 cw->transparent.user_r,
2814 cw->transparent.user_g,
2815 cw->transparent.user_b,
2816 cw->transparent.user_a);
2820 evas_object_color_set(obj, r, g, b, a);
2823 ////////////////////////////////////////////////////
2826 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2828 int w, h, ox, oy, ow, oh;
2830 Eina_Bool pass_event_flag = EINA_FALSE;
2831 E_Input_Rect_Data *input_rect_data;
2832 E_Input_Rect_Smart_Data *input_rect_sd;
2834 if (cw->frame_object)
2836 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2837 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2838 /* set a fixed size, force edje calc, check size difference */
2839 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2840 edje_object_message_signal_process(cw->frame_object);
2841 edje_object_calc_force(cw->frame_object);
2842 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2843 cw->client_inset.l = ox;
2844 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2845 cw->client_inset.t = oy;
2846 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2847 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2848 evas_object_resize(cw->frame_object, w, h);
2852 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2855 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2857 if (input_rect_data->obj)
2859 pass_event_flag = EINA_TRUE;
2865 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2866 evas_object_pass_events_set(cw->obj, pass_event_flag);
2870 cw->client_inset.l = 0;
2871 cw->client_inset.r = 0;
2872 cw->client_inset.t = 0;
2873 cw->client_inset.b = 0;
2875 cw->client_inset.calc = !!cw->frame_object;
2879 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2881 E_Comp_Object *cw = data;
2885 /* - get current size
2887 * - readjust for new frame size
2890 w = cw->ec->w, h = cw->ec->h;
2891 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2893 _e_comp_object_frame_recalc(cw);
2895 if (!cw->ec->fullscreen)
2896 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2898 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2899 if (cw->ec->fullscreen)
2901 zone = e_comp_zone_find_by_ec(cw->ec);
2903 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2905 else if (cw->ec->new_client)
2907 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2908 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2909 evas_object_resize(cw->ec->frame, w, h);
2911 else if ((w != cw->ec->w) || (h != cw->ec->h))
2912 evas_object_resize(cw->ec->frame, w, h);
2916 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2918 E_Comp_Object *cw = data;
2920 _e_comp_object_shadow_setup(cw);
2921 if (cw->frame_object)
2923 _e_comp_object_shadow(cw);
2924 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2925 _e_comp_object_frame_recalc(cw);
2926 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2931 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2933 E_Comp_Object *cw = data;
2935 if (_e_comp_object_shadow_setup(cw))
2936 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2937 if (cw->frame_object)
2939 _e_comp_object_shadow(cw);
2940 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2941 _e_comp_object_frame_recalc(cw);
2942 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2947 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2949 E_Comp_Object *cw = data;
2951 if (cw->frame_object)
2953 _e_comp_object_shadow(cw);
2954 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2955 _e_comp_object_frame_recalc(cw);
2956 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2961 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2963 E_Comp_Object *cw = data;
2965 if (_e_comp_object_shadow_setup(cw))
2968 cw->ec->changes.size = 1;
2970 if (cw->frame_object)
2972 _e_comp_object_shadow(cw);
2973 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2974 _e_comp_object_frame_recalc(cw);
2975 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2980 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2982 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2986 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2988 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2992 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2994 E_Comp_Object *cw = data;
2996 if (!cw->ec) return; //NYI
2997 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
3001 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3003 E_Comp_Object *cw = data;
3005 if (!cw->ec) return; //NYI
3006 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3010 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3012 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3016 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3018 E_Comp_Object *cw = data;
3020 if (!e_object_is_del(E_OBJECT(cw->ec)))
3021 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3025 _e_comp_input_obj_smart_add(Evas_Object *obj)
3027 E_Input_Rect_Smart_Data *input_rect_sd;
3028 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3030 if (!input_rect_sd) return;
3031 evas_object_smart_data_set(obj, input_rect_sd);
3035 _e_comp_input_obj_smart_del(Evas_Object *obj)
3037 E_Input_Rect_Smart_Data *input_rect_sd;
3038 E_Input_Rect_Data *input_rect_data;
3040 input_rect_sd = evas_object_smart_data_get(obj);
3041 if (!input_rect_sd) return;
3043 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3045 if (input_rect_data->obj)
3047 evas_object_smart_member_del(input_rect_data->obj);
3048 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3050 E_FREE(input_rect_data);
3052 E_FREE(input_rect_sd);
3056 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3058 E_Input_Rect_Smart_Data *input_rect_sd;
3059 E_Input_Rect_Data *input_rect_data;
3063 input_rect_sd = evas_object_smart_data_get(obj);
3064 if (!input_rect_sd) return;
3066 cw = input_rect_sd->cw;
3067 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3069 if (input_rect_data->obj)
3071 evas_object_geometry_set(input_rect_data->obj,
3072 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3073 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3074 input_rect_data->rect.w, input_rect_data->rect.h);
3080 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3082 E_Input_Rect_Smart_Data *input_rect_sd;
3083 E_Input_Rect_Data *input_rect_data;
3087 input_rect_sd = evas_object_smart_data_get(obj);
3088 if (!input_rect_sd) return;
3090 cw = input_rect_sd->cw;
3091 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3093 if (input_rect_data->obj)
3095 evas_object_geometry_set(input_rect_data->obj,
3096 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3097 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3098 input_rect_data->rect.w, input_rect_data->rect.h);
3104 _e_comp_input_obj_smart_show(Evas_Object *obj)
3106 E_Input_Rect_Smart_Data *input_rect_sd;
3107 E_Input_Rect_Data *input_rect_data;
3110 input_rect_sd = evas_object_smart_data_get(obj);
3111 if (!input_rect_sd) return;
3113 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3115 if (input_rect_data->obj)
3117 evas_object_show(input_rect_data->obj);
3123 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3125 E_Input_Rect_Smart_Data *input_rect_sd;
3126 E_Input_Rect_Data *input_rect_data;
3129 input_rect_sd = evas_object_smart_data_get(obj);
3130 if (!input_rect_sd) return;
3132 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3134 if (input_rect_data->obj)
3136 evas_object_hide(input_rect_data->obj);
3142 _e_comp_input_obj_smart_init(void)
3144 if (_e_comp_input_obj_smart) return;
3146 static const Evas_Smart_Class sc =
3148 INPUT_OBJ_SMART_NAME,
3149 EVAS_SMART_CLASS_VERSION,
3150 _e_comp_input_obj_smart_add,
3151 _e_comp_input_obj_smart_del,
3152 _e_comp_input_obj_smart_move,
3153 _e_comp_input_obj_smart_resize,
3154 _e_comp_input_obj_smart_show,
3155 _e_comp_input_obj_smart_hide,
3168 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3174 _e_comp_smart_add(Evas_Object *obj)
3178 cw = E_NEW(E_Comp_Object, 1);
3179 EINA_SAFETY_ON_NULL_RETURN(cw);
3181 wl_signal_init(&cw->events.lower);
3182 #ifdef REFACTOR_DESK_AREA
3183 wl_signal_init(&cw->events.lower_done);
3184 wl_signal_init(&cw->events.raise);
3186 wl_signal_init(&cw->events.show);
3187 wl_signal_init(&cw->events.hide);
3188 #ifdef REFACTOR_DESK_AREA
3189 wl_signal_init(&cw->events.set_layer);
3190 wl_signal_init(&cw->events.stack_above);
3191 wl_signal_init(&cw->events.stack_below);
3194 cw->smart_obj = obj;
3195 cw->x = cw->y = cw->w = cw->h = -1;
3196 evas_object_smart_data_set(obj, cw);
3197 cw->opacity = 255.0;
3198 cw->external_content = 0;
3199 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3200 cw->transform_bg_color.r = 0;
3201 cw->transform_bg_color.g = 0;
3202 cw->transform_bg_color.b = 0;
3203 cw->transform_bg_color.a = 255;
3204 evas_object_data_set(obj, "comp_obj", cw);
3205 evas_object_move(obj, -1, -1);
3206 /* intercept ALL the callbacks! */
3207 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3208 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3209 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3210 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3211 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3212 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3213 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3214 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3215 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3216 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3217 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3219 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3220 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3221 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3222 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3224 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3225 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3227 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3228 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3230 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3232 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3233 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3237 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3240 evas_object_color_set(cw->clip, r, g, b, a);
3241 evas_object_smart_callback_call(obj, "color_set", NULL);
3246 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3249 evas_object_clip_set(cw->clip, clip);
3253 _e_comp_smart_clip_unset(Evas_Object *obj)
3256 evas_object_clip_unset(cw->clip);
3260 _e_comp_smart_hide(Evas_Object *obj)
3262 TRACE_DS_BEGIN(COMP:SMART HIDE);
3267 evas_object_hide(cw->clip);
3268 if (cw->input_obj) evas_object_hide(cw->input_obj);
3269 evas_object_hide(cw->effect_obj);
3270 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3271 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3272 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3279 /* unset native surface if current displaying buffer was destroied */
3280 if (!cw->buffer_destroy_listener.notify)
3282 Evas_Native_Surface *ns;
3283 ns = evas_object_image_native_surface_get(cw->obj);
3284 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3285 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3288 if (!cw->ec->input_only)
3290 edje_object_freeze(cw->effect_obj);
3291 edje_object_freeze(cw->shobj);
3292 edje_object_play_set(cw->shobj, 0);
3293 if (cw->frame_object)
3294 edje_object_play_set(cw->frame_object, 0);
3297 e_comp_render_queue(); //force nocomp recheck
3303 _e_comp_smart_show(Evas_Object *obj)
3311 if ((cw->w < 0) || (cw->h < 0))
3312 CRI("ACK! ec:%p", cw->ec);
3314 TRACE_DS_BEGIN(COMP:SMART SHOW);
3316 e_comp_object_map_update(obj);
3318 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3319 evas_object_show(tmp->frame);
3321 evas_object_show(cw->clip);
3322 if (cw->input_obj) evas_object_show(cw->input_obj);
3323 if (!cw->ec->input_only)
3325 edje_object_thaw(cw->effect_obj);
3326 edje_object_thaw(cw->shobj);
3327 edje_object_play_set(cw->shobj, 1);
3328 if (cw->frame_object)
3329 edje_object_play_set(cw->frame_object, 1);
3331 evas_object_show(cw->effect_obj);
3332 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3333 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3334 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3335 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3336 e_comp_render_queue();
3337 if (cw->ec->input_only)
3342 if (cw->ec->iconic && (!cw->ec->new_client))
3344 if (e_client_is_iconified_by_client(cw->ec))
3346 ELOGF("COMP", "Set launching flag..", cw->ec);
3347 cw->ec->launching = EINA_TRUE;
3350 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3352 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3355 ELOGF("COMP", "Set launching flag..", cw->ec);
3356 cw->ec->launching = EINA_TRUE;
3358 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3359 _e_comp_object_animating_begin(cw);
3360 if (!_e_comp_object_effect_visibility_start(cw, 1))
3366 /* ensure some random effect doesn't lock the client offscreen */
3370 e_comp_object_effect_set(obj, NULL);
3373 _e_comp_object_dim_update(cw);
3379 _e_comp_smart_del(Evas_Object *obj)
3385 if (cw->buffer_destroy_listener.notify)
3387 wl_list_remove(&cw->buffer_destroy_listener.link);
3388 cw->buffer_destroy_listener.notify = NULL;
3391 if (cw->tbm_surface)
3393 tbm_surface_internal_unref(cw->tbm_surface);
3394 cw->tbm_surface = NULL;
3397 if (cw->render_update_lock.buffer_ref.buffer)
3399 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3400 cw->ec, cw->render_update_lock.lock);
3401 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3404 e_comp_object_render_update_del(cw->smart_obj);
3405 E_FREE_FUNC(cw->updates, eina_tiler_free);
3406 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3413 EINA_LIST_FREE(cw->obj_mirror, o)
3415 evas_object_image_data_set(o, NULL);
3416 evas_object_freeze_events_set(o, 1);
3417 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3421 #ifdef REFACTOR_DESK_AREA
3423 _e_comp_object_layers_remove(cw);
3425 l = evas_object_data_get(obj, "comp_object-to_del");
3426 E_FREE_LIST(l, evas_object_del);
3427 _e_comp_object_mouse_event_callback_unset(cw);
3428 evas_object_del(cw->clip);
3429 evas_object_del(cw->obj);
3430 evas_object_del(cw->shobj);
3431 evas_object_del(cw->effect_obj);
3432 evas_object_del(cw->frame_object);
3433 evas_object_del(cw->input_obj);
3434 evas_object_del(cw->mask.obj);
3435 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3436 evas_object_del(cw->transform_bg_obj);
3437 evas_object_del(cw->transform_tranp_obj);
3438 evas_object_del(cw->default_input_obj);
3439 eina_stringshare_del(cw->frame_theme);
3440 eina_stringshare_del(cw->frame_name);
3444 e_comp->animating--;
3446 e_object_unref(E_OBJECT(cw->ec));
3448 cw->ec->frame = NULL;
3453 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3457 cw->x = x, cw->y = y;
3458 evas_object_move(cw->effect_obj, x, y);
3459 evas_object_move(cw->default_input_obj, x, y);
3460 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3462 e_comp_object_map_update(obj);
3466 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3468 Eina_Bool first = EINA_FALSE;
3473 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3475 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3477 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3479 if (cw->w != w || cw->h != h)
3480 e_comp_object_map_update(obj);
3482 first = ((cw->w < 1) || (cw->h < 1));
3483 cw->w = w, cw->h = h;
3487 if (cw->frame_object)
3488 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3491 /* verify pixmap:object size */
3492 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3494 if ((ww != pw) || (hh != ph))
3495 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3497 evas_object_resize(cw->effect_obj, tw, th);
3498 evas_object_resize(cw->default_input_obj, w, h);
3500 evas_object_resize(cw->input_obj, w, h);
3502 evas_object_resize(cw->mask.obj, w, h);
3503 /* resize render update tiler */
3506 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3507 cw->updates_full = 0;
3508 if (cw->updates) eina_tiler_clear(cw->updates);
3512 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3513 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3521 e_comp_render_queue();
3527 _e_comp_smart_init(void)
3529 if (_e_comp_smart) return;
3531 static const Evas_Smart_Class sc =
3534 EVAS_SMART_CLASS_VERSION,
3538 _e_comp_smart_resize,
3541 _e_comp_smart_color_set,
3542 _e_comp_smart_clip_set,
3543 _e_comp_smart_clip_unset,
3553 _e_comp_smart = evas_smart_class_new(&sc);
3558 e_comp_object_init(void)
3560 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3561 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3562 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3563 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3567 e_comp_object_shutdown(void)
3573 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3575 API_ENTRY EINA_FALSE;
3576 return !!cw->force_visible;
3578 /////////////////////////////////////////////////////////
3581 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3584 Eina_Bool comp_object;
3586 comp_object = !!evas_object_data_get(obj, "comp_object");
3591 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3593 e_comp_render_queue();
3595 l = evas_object_data_get(obj, "comp_object-to_del");
3596 E_FREE_LIST(l, evas_object_del);
3600 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3602 if (e_comp_util_object_is_above_nocomp(obj) &&
3603 (!evas_object_data_get(obj, "comp_override")))
3605 evas_object_data_set(obj, "comp_override", (void*)1);
3606 e_comp_override_add();
3611 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3613 Eina_Bool ref = EINA_TRUE;
3614 if (evas_object_visible_get(obj))
3618 d = evas_object_data_del(obj, "comp_hiding");
3620 /* currently trying to hide */
3623 /* already visible */
3627 evas_object_show(obj);
3630 evas_object_ref(obj);
3631 evas_object_data_set(obj, "comp_ref", (void*)1);
3633 edje_object_signal_emit(obj, "e,state,visible", "e");
3634 evas_object_data_set(obj, "comp_showing", (void*)1);
3635 if (e_comp_util_object_is_above_nocomp(obj))
3637 evas_object_data_set(obj, "comp_override", (void*)1);
3638 e_comp_override_add();
3643 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3645 if (!evas_object_visible_get(obj)) return;
3646 /* already hiding */
3647 if (evas_object_data_get(obj, "comp_hiding")) return;
3648 if (!evas_object_data_del(obj, "comp_showing"))
3650 evas_object_ref(obj);
3651 evas_object_data_set(obj, "comp_ref", (void*)1);
3653 edje_object_signal_emit(obj, "e,state,hidden", "e");
3654 evas_object_data_set(obj, "comp_hiding", (void*)1);
3656 if (evas_object_data_del(obj, "comp_override"))
3657 e_comp_override_timed_pop();
3661 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3663 if (!e_util_strcmp(emission, "e,action,hide,done"))
3665 if (!evas_object_data_del(obj, "comp_hiding")) return;
3666 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3667 evas_object_hide(obj);
3668 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3671 evas_object_data_del(obj, "comp_showing");
3672 if (evas_object_data_del(obj, "comp_ref"))
3673 evas_object_unref(obj);
3677 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3683 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3687 E_API E_Comp_Object_Hook *
3688 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3690 E_Comp_Object_Hook *ch;
3692 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3693 ch = E_NEW(E_Comp_Object_Hook, 1);
3694 if (!ch) return NULL;
3695 ch->hookpoint = hookpoint;
3697 ch->data = (void*)data;
3698 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3703 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3706 if (_e_comp_object_hooks_walking == 0)
3708 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3712 _e_comp_object_hooks_delete++;
3715 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3716 E_API E_Comp_Object_Intercept_Hook *
3717 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3719 E_Comp_Object_Intercept_Hook *ch;
3721 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3722 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3723 if (!ch) return NULL;
3724 ch->hookpoint = hookpoint;
3726 ch->data = (void*)data;
3727 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3732 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3735 if (_e_comp_object_intercept_hooks_walking == 0)
3737 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3741 _e_comp_object_intercept_hooks_delete++;
3746 e_comp_object_util_add(Evas_Object *obj)
3750 E_Comp_Config *conf = e_comp_config_get();
3751 Eina_Bool skip = EINA_FALSE;
3757 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3759 name = evas_object_name_get(obj);
3760 vis = evas_object_visible_get(obj);
3761 o = edje_object_add(e_comp->evas);
3762 evas_object_data_set(o, "comp_object", (void*)1);
3764 skip = (!strncmp(name, "noshadow", 8));
3766 evas_object_data_set(o, "comp_object_skip", (void*)1);
3768 if (conf->shadow_style)
3770 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3771 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3774 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3775 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3776 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3778 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3780 evas_object_geometry_get(obj, &x, &y, &w, &h);
3781 evas_object_geometry_set(o, x, y, w, h);
3782 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3784 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3786 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3787 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3788 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3789 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3790 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3791 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3793 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3795 edje_object_part_swallow(o, "e.swallow.content", obj);
3797 _e_comp_object_event_add(o);
3800 evas_object_show(o);
3805 /* utility functions for deleting objects when their "owner" is deleted */
3807 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3812 EINA_SAFETY_ON_NULL_RETURN(to_del);
3813 l = evas_object_data_get(obj, "comp_object-to_del");
3814 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3815 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3816 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3820 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3825 EINA_SAFETY_ON_NULL_RETURN(to_del);
3826 l = evas_object_data_get(obj, "comp_object-to_del");
3828 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3831 /////////////////////////////////////////////////////////
3833 EINTERN Evas_Object *
3834 e_comp_object_client_add(E_Client *ec)
3839 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3840 if (ec->frame) return NULL;
3841 _e_comp_smart_init();
3842 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3843 cw = evas_object_smart_data_get(o);
3844 if (!cw) return NULL;
3845 evas_object_data_set(o, "E_Client", ec);
3848 evas_object_data_set(o, "comp_object", (void*)1);
3850 _e_comp_object_event_add(o);
3855 /* utility functions for getting client inset */
3857 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3860 if (!cw->client_inset.calc)
3866 if (ax) *ax = x - cw->client_inset.l;
3867 if (ay) *ay = y - cw->client_inset.t;
3871 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3874 if (!cw->client_inset.calc)
3880 if (ax) *ax = x + cw->client_inset.l;
3881 if (ay) *ay = y + cw->client_inset.t;
3885 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3888 if (!cw->client_inset.calc)
3894 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3895 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3899 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3902 if (!cw->client_inset.calc)
3908 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3909 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3913 e_comp_object_client_get(Evas_Object *obj)
3918 /* FIXME: remove this when eo is used */
3919 o = evas_object_data_get(obj, "comp_smart_obj");
3921 return e_comp_object_client_get(o);
3922 return cw ? cw->ec : NULL;
3926 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3929 if (cw->frame_extends)
3930 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3935 if (w) *w = cw->ec->w;
3936 if (h) *h = cw->ec->h;
3941 e_comp_object_util_zone_get(Evas_Object *obj)
3943 E_Zone *zone = NULL;
3947 zone = e_comp_zone_find_by_ec(cw->ec);
3952 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3953 zone = e_comp_zone_xy_get(x, y);
3959 e_comp_object_util_center(Evas_Object *obj)
3961 int x, y, w, h, ow, oh;
3966 zone = e_comp_object_util_zone_get(obj);
3967 EINA_SAFETY_ON_NULL_RETURN(zone);
3968 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3969 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3970 ow = cw->ec->w, oh = cw->ec->h;
3972 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3973 x = x + (w - ow) / 2;
3974 y = y + (h - oh) / 2;
3975 evas_object_move(obj, x, y);
3979 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3981 int x, y, w, h, ow, oh;
3984 EINA_SAFETY_ON_NULL_RETURN(on);
3985 evas_object_geometry_get(on, &x, &y, &w, &h);
3986 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3987 ow = cw->ec->w, oh = cw->ec->h;
3989 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3990 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3994 e_comp_object_util_fullscreen(Evas_Object *obj)
3999 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4002 evas_object_move(obj, 0, 0);
4003 evas_object_resize(obj, e_comp->w, e_comp->h);
4008 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4016 ow = cw->w, oh = cw->h;
4018 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4019 zone = e_comp_object_util_zone_get(obj);
4020 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4021 if (x) *x = zx + (zw - ow) / 2;
4022 if (y) *y = zy + (zh - oh) / 2;
4026 e_comp_object_input_objs_del(Evas_Object *obj)
4029 E_Input_Rect_Data *input_rect_data;
4030 E_Input_Rect_Smart_Data *input_rect_sd;
4035 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4036 if (!input_rect_sd) return;
4038 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4040 if (input_rect_data->obj)
4042 evas_object_smart_member_del(input_rect_data->obj);
4043 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4045 E_FREE(input_rect_data);
4050 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4053 E_Input_Rect_Data *input_rect_data = NULL;
4054 E_Input_Rect_Smart_Data *input_rect_sd;
4055 int client_w, client_h;
4057 if (cw->ec->client.w)
4058 client_w = cw->ec->client.w;
4060 client_w = cw->ec->w;
4062 if (cw->ec->client.h)
4063 client_h = cw->ec->client.h;
4065 client_h = cw->ec->h;
4067 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4071 _e_comp_input_obj_smart_init();
4072 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4073 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4074 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4077 input_rect_sd->cw = cw;
4080 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4083 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4084 if (input_rect_data)
4086 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4087 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4091 if ((input_rect_data) &&
4092 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4094 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4095 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4096 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4097 evas_object_clip_set(input_rect_data->obj, cw->clip);
4098 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4099 evas_object_geometry_set(input_rect_data->obj,
4100 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4101 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4102 evas_object_pass_events_set(cw->default_input_obj, 1);
4103 evas_object_pass_events_set(cw->obj, 1);
4106 evas_object_show(input_rect_data->obj);
4107 evas_object_show(cw->input_obj);
4112 evas_object_smart_member_del(cw->input_obj);
4113 E_FREE_FUNC(cw->input_obj, evas_object_del);
4114 evas_object_pass_events_set(cw->default_input_obj, 0);
4115 evas_object_pass_events_set(cw->obj, 0);
4120 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4123 E_Input_Rect_Smart_Data *input_rect_sd;
4124 E_Input_Rect_Data *input_rect_data;
4127 if (!cw->input_obj) return;
4129 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4132 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4134 *list = eina_list_append(*list, &input_rect_data->rect);
4140 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4143 if (l) *l = cw->client_inset.l;
4144 if (r) *r = cw->client_inset.r;
4145 if (t) *t = cw->client_inset.t;
4146 if (b) *b = cw->client_inset.b;
4149 /* set geometry for CSD */
4151 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4157 if (cw->frame_object)
4158 CRI("ACK! ec:%p", cw->ec);
4159 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4160 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4161 calc = cw->client_inset.calc;
4162 cw->client_inset.calc = l || r || t || b;
4163 eina_stringshare_replace(&cw->frame_theme, "borderless");
4164 if (cw->client_inset.calc)
4166 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4167 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4168 e_client_size_set(cw->ec, tw, th);
4170 else if (cw->ec->maximized || cw->ec->fullscreen)
4172 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4173 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4175 if (!cw->ec->new_client)
4177 if (calc && cw->client_inset.calc)
4179 tx = cw->ec->x - (l - cw->client_inset.l);
4180 ty = cw->ec->y - (t - cw->client_inset.t);
4181 e_client_pos_set(cw->ec, tx, ty);
4183 cw->ec->changes.pos = cw->ec->changes.size = 1;
4186 cw->client_inset.l = l;
4187 cw->client_inset.r = r;
4188 cw->client_inset.t = t;
4189 cw->client_inset.b = b;
4193 e_comp_object_frame_allowed(Evas_Object *obj)
4195 API_ENTRY EINA_FALSE;
4196 return (cw->frame_object || (!cw->client_inset.calc));
4200 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4202 API_ENTRY EINA_FALSE;
4203 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4204 eina_stringshare_replace(&cw->frame_name, name);
4205 if (cw->frame_object)
4206 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4211 e_comp_object_frame_exists(Evas_Object *obj)
4213 API_ENTRY EINA_FALSE;
4214 return !!cw->frame_object;
4218 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4220 Evas_Object *o, *pbg;
4223 Eina_Stringshare *theme;
4225 API_ENTRY EINA_FALSE;
4227 if (!e_util_strcmp(cw->frame_theme, name))
4228 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4229 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4230 return _e_comp_object_shadow_setup(cw);
4231 pbg = cw->frame_object;
4232 theme = eina_stringshare_add(name);
4234 if (cw->frame_object)
4238 w = cw->ec->w, h = cw->ec->h;
4239 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4240 if ((cw->ec->w != w) || (cw->ec->h != h))
4242 cw->ec->changes.size = 1;
4245 E_FREE_FUNC(cw->frame_object, evas_object_del);
4246 if (!name) goto reshadow;
4248 o = edje_object_add(e_comp->evas);
4249 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4250 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4251 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4253 cw->frame_object = NULL;
4255 eina_stringshare_del(cw->frame_theme);
4256 cw->frame_theme = theme;
4261 if (theme != e_config->theme_default_border_style)
4263 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4264 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4268 ok = e_theme_edje_object_set(o, "base/theme/border",
4269 "e/widgets/border/default/border");
4270 if (ok && (theme == e_config->theme_default_border_style))
4272 /* Reset default border style to default */
4273 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4274 e_config_save_queue();
4281 cw->frame_object = o;
4282 eina_stringshare_del(cw->frame_theme);
4283 cw->frame_theme = theme;
4284 evas_object_name_set(o, "cw->frame_object");
4287 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4291 cw->ec->changes.icon = 1;
4297 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4302 _e_comp_object_shadow_setup(cw);
4305 int old_x, old_y, new_x = 0, new_y = 0;
4307 old_x = cw->x, old_y = cw->y;
4309 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4311 new_x = cw->ec->x, new_y = cw->ec->y;
4312 else if (cw->ec->placed || (!cw->ec->new_client))
4314 /* if no previous frame:
4315 * - reapply client_inset
4320 if (cw->ec->changes.size)
4328 zone = e_comp_zone_find_by_ec(cw->ec);
4331 x = cw->ec->client.x, y = cw->ec->client.y;
4332 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4333 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4335 new_x = x, new_y = y;
4338 if (old_x != new_x || old_y != new_y)
4340 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4341 cw->y = cw->x = -99999;
4342 evas_object_move(obj, new_x, new_y);
4346 if (cw->ec->maximized)
4348 cw->ec->changes.need_maximize = 1;
4351 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4352 if (cw->frame_object)
4354 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4357 cw->frame_extends = 0;
4358 evas_object_del(pbg);
4363 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4365 E_Comp_Object_Mover *prov;
4368 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4369 edje_object_signal_emit(cw->shobj, sig, src);
4370 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4371 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4372 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4374 /* start with highest priority callback first */
4375 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4377 if (!e_util_glob_match(sig, prov->sig)) continue;
4378 if (prov->func(prov->data, obj, sig)) break;
4383 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4385 /* FIXME: at some point I guess this should use eo to inherit
4386 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4387 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4390 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4394 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4397 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4401 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4404 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4408 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4411 Eina_Rectangle rect;
4414 if (cw->ec->input_only || (!cw->updates)) return;
4415 if (cw->nocomp) return;
4416 rect.x = x, rect.y = y;
4417 rect.w = w, rect.h = h;
4418 evas_object_smart_callback_call(obj, "damage", &rect);
4420 if (e_comp_is_on_overlay(cw->ec))
4422 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4423 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4424 * E module attempts to block screen update due to the particular policy.
4426 if (e_pixmap_resource_get(cw->ec->pixmap))
4427 cw->hwc_need_update = EINA_TRUE;
4430 /* ignore overdraw */
4431 if (cw->updates_full)
4433 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4434 e_comp_object_render_update_add(obj);
4436 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4437 evas_object_show(cw->smart_obj);
4441 /* clip rect to client surface */
4442 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4443 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4444 /* if rect is the total size of the client after clip, clear the updates
4445 * since this is guaranteed to be the whole region anyway
4447 eina_tiler_area_size_get(cw->updates, &tw, &th);
4448 if ((w > tw) || (h > th))
4450 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4451 eina_tiler_clear(cw->updates);
4452 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4454 tw = cw->ec->client.w, th = cw->ec->client.h;
4456 if ((!x) && (!y) && (w == tw) && (h == th))
4458 eina_tiler_clear(cw->updates);
4459 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4460 cw->updates_full = 1;
4461 cw->update_count = 0;
4464 if (cw->update_count > UPDATE_MAX)
4466 /* this is going to get really dumb, so just update the whole thing */
4467 eina_tiler_clear(cw->updates);
4468 cw->update_count = cw->updates_full = 1;
4469 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4470 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4474 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4475 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4477 cw->updates_exist = 1;
4478 e_comp_object_render_update_add(obj);
4480 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4481 evas_object_show(cw->smart_obj);
4485 e_comp_object_damage_exists(Evas_Object *obj)
4487 API_ENTRY EINA_FALSE;
4488 return cw->updates_exist;
4492 e_comp_object_render_update_add(Evas_Object *obj)
4496 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4497 if (cw->render_update_lock.lock) return;
4498 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4502 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4504 e_comp_render_queue();
4508 e_comp_object_render_update_del(Evas_Object *obj)
4512 if (cw->ec->input_only || (!cw->updates)) return;
4513 if (!cw->update) return;
4515 /* this gets called during comp animating to clear the update flag */
4516 if (e_comp->grabbed) return;
4517 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4518 if (!e_comp->updates)
4520 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4521 if (e_comp->render_animator)
4522 ecore_animator_freeze(e_comp->render_animator);
4527 e_comp_object_shape_apply(Evas_Object *obj)
4531 unsigned int i, *pix, *p;
4535 if (!cw->ec) return; //NYI
4536 if (cw->external_content) return;
4539 if ((cw->ec->shape_rects_num >= 1) &&
4540 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4545 ERR("BUGGER: shape with native surface? cw=%p", cw);
4548 evas_object_image_size_get(cw->obj, &w, &h);
4549 if ((w < 1) || (h < 1)) return;
4552 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4553 _e_comp_object_alpha_set(cw);
4554 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4555 evas_object_image_alpha_set(o, 1);
4557 p = pix = evas_object_image_data_get(cw->obj, 1);
4560 evas_object_image_data_set(cw->obj, pix);
4565 unsigned char *spix, *sp;
4567 spix = calloc(w * h, sizeof(unsigned char));
4569 for (i = 0; i < cw->ec->shape_rects_num; i++)
4573 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4574 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4575 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4576 sp = spix + (w * ry) + rx;
4577 for (py = 0; py < rh; py++)
4579 for (px = 0; px < rw; px++)
4587 for (py = 0; py < h; py++)
4589 for (px = 0; px < w; px++)
4591 unsigned int mask, imask;
4593 mask = ((unsigned int)(*sp)) << 24;
4595 imask |= imask >> 8;
4596 imask |= imask >> 8;
4597 *p = mask | (*p & imask);
4598 //if (*sp) *p = 0xff000000 | *p;
4599 //else *p = 0x00000000;
4608 for (py = 0; py < h; py++)
4610 for (px = 0; px < w; px++)
4614 evas_object_image_data_set(cw->obj, pix);
4615 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4616 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4618 evas_object_image_data_set(o, pix);
4619 evas_object_image_data_update_add(o, 0, 0, w, h);
4621 // don't need to fix alpha chanel as blending
4622 // should be totally off here regardless of
4623 // alpha channel content
4627 _e_comp_object_clear(E_Comp_Object *cw)
4632 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4634 if (cw->render_update_lock.lock) return;
4637 e_pixmap_clear(cw->ec->pixmap);
4639 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4640 evas_object_image_size_set(cw->obj, 1, 1);
4641 evas_object_image_data_set(cw->obj, NULL);
4642 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4644 evas_object_image_size_set(o, 1, 1);
4645 evas_object_image_data_set(o, NULL);
4648 e_comp_object_render_update_del(cw->smart_obj);
4652 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4656 API_ENTRY EINA_FALSE;
4658 if (cw->transparent.set == set)
4663 evas_object_color_get(obj, &r, &g, &b, &a);
4664 evas_object_color_set(obj, 0, 0, 0, 0);
4666 cw->transparent.user_r = r;
4667 cw->transparent.user_g = g;
4668 cw->transparent.user_b = b;
4669 cw->transparent.user_a = a;
4671 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4673 cw->transparent.user_r,
4674 cw->transparent.user_g,
4675 cw->transparent.user_b,
4676 cw->transparent.user_a);
4678 cw->transparent.set = EINA_TRUE;
4682 cw->transparent.set = EINA_FALSE;
4684 evas_object_color_set(obj,
4685 cw->transparent.user_r,
4686 cw->transparent.user_g,
4687 cw->transparent.user_b,
4688 cw->transparent.user_a);
4690 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4692 cw->transparent.user_r,
4693 cw->transparent.user_g,
4694 cw->transparent.user_b,
4695 cw->transparent.user_a);
4701 /* helper function to simplify toggling of redirection for display servers which support it */
4703 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4708 if (cw->redirected == set) return;
4709 cw->redirected = set;
4710 if (cw->external_content) return;
4712 e_comp_object_map_update(obj);
4716 if (cw->updates_exist)
4717 e_comp_object_render_update_add(obj);
4719 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4721 _e_comp_object_transparent_set(obj, EINA_FALSE);
4722 evas_object_smart_callback_call(obj, "redirected", NULL);
4726 _e_comp_object_clear(cw);
4727 _e_comp_object_transparent_set(obj, EINA_TRUE);
4728 evas_object_smart_callback_call(obj, "unredirected", NULL);
4733 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4736 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4738 if (cw->buffer_destroy_listener.notify)
4740 cw->buffer_destroy_listener.notify = NULL;
4741 wl_list_remove(&cw->buffer_destroy_listener.link);
4744 if (e_object_is_del(E_OBJECT(cw->ec)))
4746 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4751 /* if it's current displaying buffer, do not remove its content */
4752 if (!evas_object_visible_get(cw->ec->frame))
4753 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4758 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4763 if (cw->buffer_destroy_listener.notify)
4765 wl_list_remove(&cw->buffer_destroy_listener.link);
4766 cw->buffer_destroy_listener.notify = NULL;
4769 if (cw->tbm_surface)
4771 tbm_surface_internal_unref(cw->tbm_surface);
4772 cw->tbm_surface = NULL;
4777 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4779 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4780 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4782 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4784 tbm_surface_internal_ref(ns->data.tbm.buffer);
4785 cw->tbm_surface = ns->data.tbm.buffer;
4789 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4790 evas_object_image_native_surface_set(cw->obj, ns);
4794 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4796 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4797 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4798 evas_object_image_native_surface_set(o, ns);
4805 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4807 Evas_Native_Surface ns;
4810 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4811 if (cw->ec->input_only) return;
4812 if (cw->external_content) return;
4813 if (cw->render_update_lock.lock) return;
4816 memset(&ns, 0, sizeof(Evas_Native_Surface));
4820 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4821 set = (!cw->ec->shaped);
4823 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4827 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4831 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4834 if (cw->ec->input_only) return;
4837 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4838 _e_comp_object_alpha_set(cw);
4840 e_comp_object_native_surface_set(obj, cw->native);
4841 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4845 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4851 if (cw->blanked == set) return;
4853 _e_comp_object_alpha_set(cw);
4856 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4857 evas_object_image_data_set(cw->obj, NULL);
4861 e_comp_object_native_surface_set(obj, 1);
4862 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4866 _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)
4871 if (!_damage_trace) return;
4875 if (!evas_object_visible_get(cw->obj)) return;
4877 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4879 o = evas_object_rectangle_add(e_comp->evas);
4880 evas_object_layer_set(o, E_LAYER_MAX);
4881 evas_object_name_set(o, "damage_trace");
4882 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4883 evas_object_resize(o, dmg_w, dmg_h);
4884 evas_object_color_set(o, 0, 128, 0, 128);
4885 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4886 evas_object_pass_events_set(o, EINA_TRUE);
4887 evas_object_show(o);
4889 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4891 dmg_w, dmg_h, dmg_x, dmg_y,
4892 origin->w, origin->h, origin->x, origin->y);
4894 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4897 /* mark an object as dirty and setup damages */
4899 e_comp_object_dirty(Evas_Object *obj)
4902 Eina_Rectangle *rect;
4906 Eina_Bool dirty, visible;
4910 if (cw->external_content) return;
4911 if (!cw->redirected) return;
4912 if (cw->render_update_lock.lock)
4914 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4917 /* only actually dirty if pixmap is available */
4918 if (!e_pixmap_resource_get(cw->ec->pixmap))
4920 // e_pixmap_size_get returns last attached buffer size
4921 // eventhough it is destroyed
4922 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4925 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4926 visible = cw->visible;
4927 if (!dirty) w = h = 1;
4928 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4930 evas_object_image_data_set(cw->obj, NULL);
4931 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4932 evas_object_image_size_set(cw->obj, tw, th);
4933 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4934 if (cw->pending_updates)
4935 eina_tiler_area_size_set(cw->pending_updates, w, h);
4936 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4938 evas_object_image_pixels_dirty_set(o, dirty);
4940 evas_object_image_data_set(o, NULL);
4941 evas_object_image_size_set(o, tw, th);
4942 visible |= evas_object_visible_get(o);
4946 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4950 e_comp_object_native_surface_set(obj, 1);
4952 m = _e_comp_object_map_damage_transform_get(cw->ec);
4953 it = eina_tiler_iterator_new(cw->updates);
4954 EINA_ITERATOR_FOREACH(it, rect)
4956 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4957 * of evas engine and doesn't convert damage according to evas_map.
4958 * so damage of evas_object_image use surface coordinate.
4962 int damage_x, damage_y, damage_w, damage_h;
4964 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4965 &damage_x, &damage_y, &damage_w, &damage_h);
4966 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4967 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4971 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4972 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4975 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4976 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4977 if (cw->pending_updates)
4978 eina_tiler_rect_add(cw->pending_updates, rect);
4980 eina_iterator_free(it);
4981 if (m) e_map_free(m);
4982 if (cw->pending_updates)
4983 eina_tiler_clear(cw->updates);
4986 cw->pending_updates = cw->updates;
4987 cw->updates = eina_tiler_new(w, h);
4988 eina_tiler_tile_size_set(cw->updates, 1, 1);
4990 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4991 evas_object_smart_callback_call(obj, "dirty", NULL);
4992 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4993 /* force render if main object is hidden but mirrors are visible */
4994 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4995 e_comp_object_render(obj);
4999 e_comp_object_render(Evas_Object *obj)
5006 API_ENTRY EINA_FALSE;
5008 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5009 if (cw->ec->input_only) return EINA_TRUE;
5010 if (cw->external_content) return EINA_TRUE;
5011 if (cw->native) return EINA_FALSE;
5012 /* if comp object is not redirected state, comp object should not be set by newly committed data
5013 because image size of comp object is 1x1 and it should not be shown on canvas */
5014 if (!cw->redirected) return EINA_TRUE;
5015 if (cw->render_update_lock.lock)
5017 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5020 e_comp_object_render_update_del(obj);
5021 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5023 if (!cw->pending_updates)
5025 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5026 evas_object_image_data_set(cw->obj, NULL);
5027 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5028 evas_object_image_data_set(o, NULL);
5032 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5034 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5036 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5039 e_pixmap_image_refresh(cw->ec->pixmap);
5040 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5043 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5044 e_pixmap_image_data_ref(cw->ec->pixmap);
5046 /* set pixel data */
5047 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5048 _e_comp_object_alpha_set(cw);
5049 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5051 evas_object_image_data_set(o, pix);
5052 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5053 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5056 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5058 e_comp_client_post_update_add(cw->ec);
5063 /* create a duplicate of an evas object */
5065 e_comp_object_util_mirror_add(Evas_Object *obj)
5069 unsigned int *pix = NULL;
5070 Eina_Bool argb = EINA_FALSE;
5075 cw = evas_object_data_get(obj, "comp_mirror");
5078 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5079 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5080 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5081 evas_object_image_alpha_set(o, 1);
5082 evas_object_image_source_set(o, obj);
5085 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5086 if (cw->external_content)
5088 ERR("%p of client %p is external content.", obj, cw->ec);
5091 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5092 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5093 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5094 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5095 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5096 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5097 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5098 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5099 evas_object_data_set(o, "comp_mirror", cw);
5101 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5102 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5104 evas_object_image_size_set(o, tw, th);
5107 pix = evas_object_image_data_get(cw->obj, 0);
5113 evas_object_image_native_surface_set(o, cw->ns);
5116 Evas_Native_Surface ns;
5117 memset(&ns, 0, sizeof(Evas_Native_Surface));
5118 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5119 evas_object_image_native_surface_set(o, &ns);
5124 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5125 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5127 (e_pixmap_image_exists(cw->ec->pixmap)))
5128 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5130 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5137 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5138 evas_object_image_pixels_dirty_set(o, dirty);
5139 evas_object_image_data_set(o, pix);
5140 evas_object_image_data_set(cw->obj, pix);
5142 evas_object_image_data_update_add(o, 0, 0, tw, th);
5147 //////////////////////////////////////////////////////
5150 e_comp_object_effect_allowed_get(Evas_Object *obj)
5152 API_ENTRY EINA_FALSE;
5154 if (!cw->shobj) return EINA_FALSE;
5155 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5156 return !e_comp_config_get()->match.disable_borders;
5159 /* setup an api effect for a client */
5161 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5164 Eina_Stringshare *grp;
5165 E_Comp_Config *config;
5166 Eina_Bool loaded = EINA_FALSE;
5168 API_ENTRY EINA_FALSE;
5169 if (!cw->shobj) return EINA_FALSE; //input window
5171 if (!effect) effect = "none";
5172 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5174 config = e_comp_config_get();
5175 if ((config) && (config->effect_file))
5177 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5179 cw->effect_set = EINA_TRUE;
5186 edje_object_file_get(cw->effect_obj, NULL, &grp);
5187 cw->effect_set = !eina_streq(effect, "none");
5188 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5189 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5191 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5192 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5193 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5195 if (cw->effect_running)
5197 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5200 cw->effect_set = EINA_FALSE;
5201 return cw->effect_set;
5205 if (cw->effect_running)
5207 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5210 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5211 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5212 if (cw->effect_clip)
5214 evas_object_clip_unset(cw->clip);
5215 cw->effect_clip = 0;
5217 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5219 _e_comp_object_dim_update(cw);
5221 return cw->effect_set;
5224 /* set params for embryo scripts in effect */
5226 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5228 Edje_Message_Int_Set *msg;
5232 EINA_SAFETY_ON_NULL_RETURN(params);
5233 EINA_SAFETY_ON_FALSE_RETURN(count);
5234 if (!cw->effect_set) return;
5236 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5237 msg->count = (int)count;
5238 for (x = 0; x < count; x++)
5239 msg->val[x] = params[x];
5240 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5241 edje_object_message_signal_process(cw->effect_obj);
5245 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5247 Edje_Signal_Cb end_cb;
5249 E_Comp_Object *cw = data;
5251 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5252 cw->effect_running = 0;
5253 if (!_e_comp_object_animating_end(cw)) return;
5255 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5257 evas_object_data_del(cw->smart_obj, "effect_running");
5258 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5259 e_comp_visibility_calculation_set(EINA_TRUE);
5262 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5263 if (!end_cb) return;
5264 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5265 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5266 end_cb(end_data, cw->smart_obj, emission, source);
5269 /* clip effect to client's zone */
5271 e_comp_object_effect_clip(Evas_Object *obj)
5275 zone = e_comp_zone_find_by_ec(cw->ec);
5277 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5278 if (!cw->effect_clip_able) return;
5279 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5280 cw->effect_clip = 1;
5283 /* unclip effect from client's zone */
5285 e_comp_object_effect_unclip(Evas_Object *obj)
5288 if (!cw->effect_clip) return;
5289 evas_object_clip_unset(cw->smart_obj);
5290 cw->effect_clip = 0;
5293 /* start effect, running end_cb after */
5295 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5297 API_ENTRY EINA_FALSE;
5298 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5299 if (!cw->effect_set) return EINA_FALSE;
5301 if (cw->effect_running)
5303 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5306 e_comp_object_effect_clip(obj);
5307 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5309 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5310 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5311 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5312 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5314 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5315 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5317 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5318 _e_comp_object_animating_begin(cw);
5319 cw->effect_running = 1;
5323 /* stop a currently-running effect immediately */
5325 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5328 Edje_Signal_Cb end_cb_before = NULL;
5329 void *end_data_before = NULL;
5330 API_ENTRY EINA_FALSE;
5332 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5333 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5335 if (end_cb_before != end_cb) return EINA_TRUE;
5336 e_comp_object_effect_unclip(obj);
5337 if (cw->effect_clip)
5339 evas_object_clip_unset(cw->effect_obj);
5340 cw->effect_clip = 0;
5342 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5343 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5345 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5347 evas_object_data_del(cw->smart_obj, "effect_running");
5348 e_comp_visibility_calculation_set(EINA_TRUE);
5351 cw->effect_running = 0;
5352 ret = _e_comp_object_animating_end(cw);
5354 if ((ret) && (end_cb_before))
5356 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5357 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5364 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5366 return a->pri - b->pri;
5369 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5370 E_API E_Comp_Object_Mover *
5371 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5373 E_Comp_Object_Mover *prov;
5375 prov = E_NEW(E_Comp_Object_Mover, 1);
5376 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5377 prov->func = provider;
5378 prov->data = (void*)data;
5381 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5382 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5387 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5389 EINA_SAFETY_ON_NULL_RETURN(prov);
5390 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5395 e_comp_object_effect_object_get(Evas_Object *obj)
5399 return cw->effect_obj;
5403 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5405 API_ENTRY EINA_FALSE;
5406 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5407 if (!cw->effect_set) return EINA_FALSE;
5414 ////////////////////////////////////
5417 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5419 if (e_comp->autoclose.obj)
5421 e_comp_ungrab_input(0, 1);
5422 if (e_comp->autoclose.del_cb)
5423 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5424 else if (!already_del)
5426 evas_object_hide(e_comp->autoclose.obj);
5427 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5429 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5431 e_comp->autoclose.obj = NULL;
5432 e_comp->autoclose.data = NULL;
5433 e_comp->autoclose.del_cb = NULL;
5434 e_comp->autoclose.key_cb = NULL;
5435 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5439 _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)
5441 _e_comp_object_autoclose_cleanup(0);
5445 _e_comp_object_autoclose_setup(Evas_Object *obj)
5447 if (!e_comp->autoclose.rect)
5449 /* create rect just below autoclose object to catch mouse events */
5450 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5451 evas_object_move(e_comp->autoclose.rect, 0, 0);
5452 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5453 evas_object_show(e_comp->autoclose.rect);
5454 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5455 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5456 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5457 e_comp_grab_input(0, 1);
5459 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5460 evas_object_focus_set(obj, 1);
5464 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5466 _e_comp_object_autoclose_setup(obj);
5467 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5471 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5473 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5474 _e_comp_object_autoclose_cleanup(1);
5475 if (e_client_focused_get()) return;
5477 E_Zone *zone = e_zone_current_get();
5480 e_zone_focus_reset(zone);
5484 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5488 if (e_comp->autoclose.obj)
5490 if (e_comp->autoclose.obj == obj) return;
5491 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5492 e_comp->autoclose.obj = obj;
5493 e_comp->autoclose.del_cb = del_cb;
5494 e_comp->autoclose.key_cb = cb;
5495 e_comp->autoclose.data = (void*)data;
5496 if (evas_object_visible_get(obj))
5497 _e_comp_object_autoclose_setup(obj);
5499 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5500 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5503 e_comp->autoclose.obj = obj;
5504 e_comp->autoclose.del_cb = del_cb;
5505 e_comp->autoclose.key_cb = cb;
5506 e_comp->autoclose.data = (void*)data;
5507 if (evas_object_visible_get(obj))
5508 _e_comp_object_autoclose_setup(obj);
5510 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5511 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5515 e_comp_object_is_animating(Evas_Object *obj)
5519 return cw->animating;
5523 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5527 if ((cw->external_content) &&
5528 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5530 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5531 "But current external content is %d object for %p.",
5532 cw->content_type, cw->ec);
5536 cw->user_alpha_set = EINA_TRUE;
5537 cw->user_alpha = alpha;
5539 if (!cw->obj) return;
5541 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5543 evas_object_image_alpha_set(cw->obj, alpha);
5545 if ((!cw->native) && (!cw->external_content))
5546 evas_object_image_data_set(cw->obj, NULL);
5550 e_comp_object_alpha_get(Evas_Object *obj)
5552 API_ENTRY EINA_FALSE;
5554 return evas_object_image_alpha_get(cw->obj);
5558 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5560 Eina_Bool mask_set = EINA_FALSE;
5564 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5565 if (cw->ec->input_only) return;
5572 o = evas_object_rectangle_add(e_comp->evas);
5573 evas_object_color_set(o, 0, 0, 0, 0);
5574 evas_object_clip_set(o, cw->clip);
5575 evas_object_smart_member_add(o, obj);
5576 evas_object_move(o, 0, 0);
5577 evas_object_resize(o, cw->w, cw->h);
5578 /* save render op value to restore when clear a mask.
5580 * NOTE: DO NOT change the render op on ec->frame while mask object
5581 * is set. it will overwrite the changed op value. */
5582 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5583 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5584 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5585 if (cw->visible) evas_object_show(o);
5588 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5589 ELOGF("COMP", " |mask_obj", cw->ec);
5590 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5597 evas_object_smart_member_del(cw->mask.obj);
5598 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5600 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5601 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5607 e_comp_object_mask_has(Evas_Object *obj)
5609 API_ENTRY EINA_FALSE;
5611 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5615 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5620 if ((cw->external_content) &&
5621 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5623 WRN("Can set up size to ONLY evas \"image\" object. "
5624 "But current external content is %d object for %p.",
5625 cw->content_type, cw->ec);
5629 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5631 evas_object_image_size_set(cw->obj, tw, th);
5635 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5637 Eina_Bool transform_set = EINA_FALSE;
5639 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5640 if (cw->ec->input_only) return;
5642 transform_set = !!set;
5646 if (!cw->transform_bg_obj)
5648 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5649 evas_object_move(o, 0, 0);
5650 evas_object_resize(o, 1, 1);
5651 if (cw->transform_bg_color.a >= 255)
5652 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5654 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5655 evas_object_color_set(o,
5656 cw->transform_bg_color.r,
5657 cw->transform_bg_color.g,
5658 cw->transform_bg_color.b,
5659 cw->transform_bg_color.a);
5660 if (cw->visible) evas_object_show(o);
5662 cw->transform_bg_obj = o;
5663 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5665 _e_comp_object_transform_obj_stack_update(obj);
5669 if (cw->transform_bg_obj)
5671 evas_object_smart_member_del(cw->transform_bg_obj);
5672 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5678 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5682 cw->transform_bg_color.r = r;
5683 cw->transform_bg_color.g = g;
5684 cw->transform_bg_color.b = b;
5685 cw->transform_bg_color.a = a;
5687 if (cw->transform_bg_obj)
5689 evas_object_color_set(cw->transform_bg_obj,
5690 cw->transform_bg_color.r,
5691 cw->transform_bg_color.g,
5692 cw->transform_bg_color.b,
5693 cw->transform_bg_color.a);
5698 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5701 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5702 if (cw->ec->input_only) return;
5703 if (!cw->transform_bg_obj) return;
5705 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5709 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5712 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5713 if (cw->ec->input_only) return;
5714 if (!cw->transform_bg_obj) return;
5716 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5720 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5722 Eina_Bool transform_set = EINA_FALSE;
5724 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5725 if (cw->ec->input_only) return;
5727 transform_set = !!set;
5731 if (!cw->transform_tranp_obj)
5733 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5734 evas_object_move(o, 0, 0);
5735 evas_object_resize(o, 1, 1);
5736 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5737 evas_object_color_set(o, 0, 0, 0, 0);
5738 if (cw->visible) evas_object_show(o);
5740 cw->transform_tranp_obj = o;
5741 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5742 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5743 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5745 _e_comp_object_transform_obj_stack_update(obj);
5749 if (cw->transform_tranp_obj)
5751 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5752 evas_object_smart_member_del(cw->transform_tranp_obj);
5753 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5759 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5762 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5763 if (cw->ec->input_only) return;
5764 if (!cw->transform_tranp_obj) return;
5766 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5770 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5773 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5774 if (cw->ec->input_only) return;
5775 if (!cw->transform_tranp_obj) return;
5777 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5780 #ifdef REFACTOR_DESK_AREA
5783 e_comp_object_layer_update(Evas_Object *obj,
5784 Evas_Object *above, Evas_Object *below)
5786 E_Comp_Object *cw2 = NULL;
5787 Evas_Object *o = NULL;
5792 if (cw->ec->layer_block) return;
5793 if ((above) && (below))
5795 ERR("Invalid layer update request! cw=%p", cw);
5803 layer = evas_object_layer_get(o);
5804 cw2 = evas_object_data_get(o, "comp_obj");
5807 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5809 o = evas_object_above_get(o);
5810 if ((!o) || (o == cw->smart_obj)) break;
5811 if (evas_object_layer_get(o) != layer)
5813 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5818 ec = e_client_top_get();
5819 if (ec) o = ec->frame;
5822 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5826 _e_comp_object_layers_remove(cw);
5829 if (cw2->layer > cw->layer)
5830 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5831 else if (cw2->layer == cw->layer)
5834 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5836 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5838 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5841 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5844 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5849 e_comp_object_layer_get(Evas_Object *obj)
5856 e_comp_object_content_set(Evas_Object *obj,
5857 Evas_Object *content,
5858 E_Comp_Object_Content_Type type)
5860 API_ENTRY EINA_FALSE;
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5863 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5864 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5868 ERR("Can't set e.swallow.content to requested content. "
5869 "Previous comp object should not be changed at all.");
5873 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5875 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5876 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5878 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5879 type, content, cw->ec, cw->ec->pixmap);
5883 cw->external_content = EINA_TRUE;
5886 cw->content_type = type;
5887 e_util_size_debug_set(cw->obj, 1);
5888 evas_object_name_set(cw->obj, "cw->obj");
5889 _e_comp_object_alpha_set(cw);
5892 _e_comp_object_shadow_setup(cw);
5898 e_comp_object_content_unset(Evas_Object *obj)
5900 API_ENTRY EINA_FALSE;
5902 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5903 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5905 if (!cw->obj && !cw->ec->visible)
5907 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5911 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5913 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5919 if (cw->frame_object)
5920 edje_object_part_unswallow(cw->frame_object, cw->obj);
5922 edje_object_part_unswallow(cw->shobj, cw->obj);
5924 evas_object_del(cw->obj);
5925 evas_object_hide(cw->obj);
5929 cw->external_content = EINA_FALSE;
5930 if (cw->ec->is_cursor)
5933 DBG("%p is cursor surface..", cw->ec);
5934 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5936 evas_object_resize(cw->ec->frame, pw, ph);
5937 evas_object_hide(cw->ec->frame);
5942 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5943 cw->obj = evas_object_image_filled_add(e_comp->evas);
5944 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5945 e_util_size_debug_set(cw->obj, 1);
5946 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5947 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5948 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5949 evas_object_name_set(cw->obj, "cw->obj");
5950 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5951 _e_comp_object_alpha_set(cw);
5954 _e_comp_object_shadow_setup(cw);
5959 _e_comp_intercept_show_helper(cw);
5963 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5964 e_comp_object_dirty(cw->smart_obj);
5965 e_comp_object_render(cw->smart_obj);
5966 e_comp_object_render_update_add(obj);
5971 EINTERN Evas_Object *
5972 e_comp_object_content_get(Evas_Object *obj)
5976 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5978 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5980 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5987 E_API E_Comp_Object_Content_Type
5988 e_comp_object_content_type_get(Evas_Object *obj)
5990 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5992 return cw->content_type;
5996 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5999 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6000 E_Comp_Config *conf = e_comp_config_get();
6001 if (cw->ec->input_only) return;
6002 if (!conf->dim_rect_enable) return;
6004 cw->dim.mask_set = mask_set;
6010 if (!cw->dim.enable) return;
6011 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6015 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6017 Eina_Bool mask_set = EINA_FALSE;
6021 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6022 E_Comp_Config *conf = e_comp_config_get();
6023 if (cw->ec->input_only) return;
6024 if (!conf->dim_rect_enable) return;
6030 if (cw->dim.mask_obj)
6032 evas_object_smart_member_del(cw->dim.mask_obj);
6033 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6036 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);
6037 o = evas_object_rectangle_add(e_comp->evas);
6038 evas_object_color_set(o, 0, 0, 0, 0);
6039 evas_object_smart_member_add(o, obj);
6040 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6041 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6043 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6044 if (cw->visible) evas_object_show(o);
6046 cw->dim.mask_obj = o;
6047 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6049 evas_object_layer_set(cw->dim.mask_obj, 9998);
6053 if (cw->dim.mask_obj)
6055 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6056 evas_object_smart_member_del(cw->dim.mask_obj);
6057 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6063 e_comp_object_dim_client_set(E_Client *ec)
6065 E_Comp_Config *conf = e_comp_config_get();
6067 if (!conf->dim_rect_enable) return ;
6068 if (dim_client == ec) return;
6070 Eina_Bool prev_dim = EINA_FALSE;
6071 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6073 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6074 prev_dim = EINA_TRUE;
6076 if (prev_dim && dim_client->visible && ec)
6078 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6079 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6083 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6084 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6090 e_comp_object_dim_client_get(void)
6092 E_Comp_Config *conf = e_comp_config_get();
6094 if (!conf->dim_rect_enable ) return NULL;
6100 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6103 char emit[32] = "\0";
6104 E_Comp_Config *conf = e_comp_config_get();
6107 if (!conf->dim_rect_enable) return;
6108 if (!cw->effect_obj) return;
6109 if (enable == cw->dim.enable) return;
6111 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6112 if (noeffect || !conf->dim_rect_effect)
6114 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6118 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6121 cw->dim.enable = enable;
6123 if (cw->dim.mask_set && !enable)
6125 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6126 edje_object_signal_emit(cw->effect_obj, emit, "e");
6128 else if (cw->dim.mask_set && enable)
6130 edje_object_signal_emit(cw->effect_obj, emit, "e");
6131 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6135 edje_object_signal_emit(cw->effect_obj, emit, "e");
6140 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6142 API_ENTRY EINA_FALSE;
6143 E_Comp_Config *conf = e_comp_config_get();
6145 if (!ec) return EINA_FALSE;
6146 if (!conf->dim_rect_enable) return EINA_FALSE;
6148 if (cw->dim.enable) return EINA_TRUE;
6154 _e_comp_object_dim_update(E_Comp_Object *cw)
6156 E_Comp_Config *conf = e_comp_config_get();
6159 if (!conf->dim_rect_enable) return;
6160 if (!cw->effect_obj) return;
6163 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6164 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6166 if (cw->dim.mask_set)
6168 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6174 e_comp_object_clear(Evas_Object *obj)
6178 _e_comp_object_clear(cw);
6182 e_comp_object_hwc_update_exists(Evas_Object *obj)
6184 API_ENTRY EINA_FALSE;
6185 return cw->hwc_need_update;
6190 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6193 cw->hwc_need_update = set;
6197 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6199 API_ENTRY EINA_FALSE;
6200 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6204 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6207 if (cw->indicator.obj != indicator)
6208 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6209 cw->indicator.obj = indicator;
6210 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6214 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6217 if (cw->indicator.obj != indicator) return;
6218 cw->indicator.obj = NULL;
6219 edje_object_part_unswallow(cw->shobj, indicator);
6223 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6226 Edje_Message_Int_Set *msg;
6228 if (!cw->indicator.obj) return;
6230 cw->indicator.w = w;
6231 cw->indicator.h = h;
6233 if (!cw->shobj) return;
6235 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6239 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6240 edje_object_message_signal_process(cw->shobj);
6243 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6245 e_comp_object_map_update(Evas_Object *obj)
6248 E_Client *ec = cw->ec;
6249 E_Comp_Wl_Client_Data *cdata;
6251 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6254 int l, remain = sizeof buffer;
6257 if (e_object_is_del(E_OBJECT(ec))) return;
6258 cdata = e_client_cdata_get(ec);
6261 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6262 * when new buffer is attached.
6264 if (!cdata->buffer_ref.buffer) return;
6266 if ((!cw->redirected) ||
6267 (e_client_video_hw_composition_check(ec)) ||
6268 (!e_comp_wl_output_buffer_transform_get(ec) &&
6269 cdata->scaler.buffer_viewport.buffer.scale == 1))
6271 if (evas_object_map_enable_get(cw->effect_obj))
6273 ELOGF("TRANSFORM", "map: disable", cw->ec);
6274 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6275 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6276 evas_object_resize(cw->effect_obj, tw, th);
6283 EINA_SAFETY_ON_NULL_RETURN(map);
6285 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6291 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6293 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6294 e_map_point_image_uv_set(map, 0, x, y);
6295 l = snprintf(p, remain, "%d,%d", x, y);
6296 p += l, remain -= l;
6298 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6299 e_map_point_image_uv_set(map, 1, x, y);
6300 l = snprintf(p, remain, " %d,%d", x, y);
6301 p += l, remain -= l;
6303 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6304 e_map_point_image_uv_set(map, 2, x, y);
6305 l = snprintf(p, remain, " %d,%d", x, y);
6306 p += l, remain -= l;
6308 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6309 e_map_point_image_uv_set(map, 3, x, y);
6310 l = snprintf(p, remain, " %d,%d", x, y);
6311 p += l, remain -= l;
6313 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6315 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6317 e_comp_object_map_set(cw->effect_obj, map);
6318 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6322 /* if there's screen rotation with comp mode, then ec->effect_obj and
6323 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6325 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6326 evas_object_resize(cw->effect_obj, tw, th);
6330 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6332 API_ENTRY EINA_FALSE;
6334 cw->render_trace = set;
6340 e_comp_object_native_usable_get(Evas_Object *obj)
6342 API_ENTRY EINA_FALSE;
6343 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6345 if (cw->ec->input_only) return EINA_FALSE;
6346 if (cw->external_content) return EINA_FALSE;
6347 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6349 /* just return true value, if it is normal case */
6350 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6353 Evas_Native_Surface *ns;
6354 ns = evas_object_image_native_surface_get(cw->obj);
6356 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6359 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6367 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6369 API_ENTRY EINA_FALSE;
6370 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6371 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6372 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6376 case E_COMP_IMAGE_FILTER_BLUR:
6377 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6379 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6380 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6382 case E_COMP_IMAGE_FILTER_INVERSE:
6383 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6385 case E_COMP_IMAGE_FILTER_NONE:
6387 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6391 cw->image_filter = filter;
6396 EINTERN E_Comp_Image_Filter
6397 e_comp_object_image_filter_get(Evas_Object *obj)
6399 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6400 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6401 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6402 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6404 return cw->image_filter;
6408 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6412 if (!_damage_trace) return;
6414 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6415 evas_object_del(obj);
6417 _damage_trace_post_objs = NULL;
6421 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6423 if (!_damage_trace) return;
6425 _damage_trace_post_objs = _damage_trace_objs;
6426 _damage_trace_objs = NULL;
6430 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6432 if (_damage_trace == onoff) return;
6436 evas_event_callback_add(e_comp->evas,
6437 EVAS_CALLBACK_RENDER_PRE,
6438 _e_comp_object_damage_trace_render_pre_cb,
6441 evas_event_callback_add(e_comp->evas,
6442 EVAS_CALLBACK_RENDER_POST,
6443 _e_comp_object_damage_trace_render_post_cb,
6450 EINA_LIST_FREE(_damage_trace_objs, obj)
6451 evas_object_del(obj);
6453 _damage_trace_objs = NULL;
6455 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6456 evas_object_del(obj);
6458 _damage_trace_post_objs = NULL;
6460 evas_event_callback_del(e_comp->evas,
6461 EVAS_CALLBACK_RENDER_PRE,
6462 _e_comp_object_damage_trace_render_pre_cb);
6464 evas_event_callback_del(e_comp->evas,
6465 EVAS_CALLBACK_RENDER_POST,
6466 _e_comp_object_damage_trace_render_post_cb);
6469 _damage_trace = onoff;
6473 e_comp_object_redirected_get(Evas_Object *obj)
6475 API_ENTRY EINA_FALSE;
6476 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6478 return cw->redirected;
6482 e_comp_object_color_visible_get(Evas_Object *obj)
6484 API_ENTRY EINA_FALSE;
6487 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6489 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6493 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6497 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6501 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6509 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6511 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6513 return e_map_set_to_comp_object(em, obj);
6517 e_comp_object_map_get(const Evas_Object *obj)
6519 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6521 return e_map_get_from_comp_object(obj);
6525 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6527 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6529 evas_object_map_enable_set(obj, enable);
6535 e_comp_object_render_update_lock(Evas_Object *obj)
6537 E_Comp_Wl_Buffer *buffer;
6538 struct wayland_tbm_client_queue *cqueue;
6540 API_ENTRY EINA_FALSE;
6542 if (cw->render_update_lock.lock == 0)
6544 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6546 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6547 if ((buffer) && (buffer->resource))
6549 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6551 wayland_tbm_server_client_queue_flush(cqueue);
6554 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6555 e_comp_object_render_update_del(obj);
6557 ELOGF("COMP", "Render update lock enabled", cw->ec);
6560 cw->render_update_lock.lock++;
6566 e_comp_object_render_update_unlock(Evas_Object *obj)
6570 if (cw->render_update_lock.lock == 0)
6573 cw->render_update_lock.lock--;
6575 if (cw->render_update_lock.lock == 0)
6578 if (cw->render_update_lock.pending_move_set)
6580 evas_object_move(obj,
6581 cw->render_update_lock.pending_move_x,
6582 cw->render_update_lock.pending_move_y);
6583 cw->render_update_lock.pending_move_x = 0;
6584 cw->render_update_lock.pending_move_y = 0;
6585 cw->render_update_lock.pending_move_set = EINA_FALSE;
6588 if (cw->render_update_lock.pending_resize_set)
6590 evas_object_resize(obj,
6591 cw->render_update_lock.pending_resize_w,
6592 cw->render_update_lock.pending_resize_h);
6593 cw->render_update_lock.pending_resize_w = 0;
6594 cw->render_update_lock.pending_resize_h = 0;
6595 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6598 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6600 if ((cw->ec->exp_iconify.buffer_flush) &&
6601 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6602 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6603 e_comp_object_clear(obj);
6605 e_comp_object_render_update_add(obj);
6607 ELOGF("COMP", "Render update lock disabled", cw->ec);
6612 e_comp_object_render_update_lock_get(Evas_Object *obj)
6614 API_ENTRY EINA_FALSE;
6616 if (cw->render_update_lock.lock > 0)
6623 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6627 if (cw->transparent.set)
6629 if (r) *r = cw->transparent.user_r;
6630 if (g) *g = cw->transparent.user_g;
6631 if (b) *b = cw->transparent.user_b;
6632 if (a) *a = cw->transparent.user_a;
6636 evas_object_color_get(obj, r, g, b, a);
6641 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6645 evas_object_render_op_set(cw->obj, op);
6648 EINTERN Evas_Render_Op
6649 e_comp_object_render_op_get(Evas_Object *obj)
6651 API_ENTRY EVAS_RENDER_BLEND;
6653 return evas_object_render_op_get(cw->obj);
6657 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6660 wl_signal_add(&cw->events.lower, listener);
6663 #ifdef REFACTOR_DESK_AREA
6665 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6668 wl_signal_add(&cw->events.lower_done, listener);
6672 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6675 wl_signal_add(&cw->events.raise, listener);
6680 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6683 wl_signal_add(&cw->events.show, listener);
6687 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6690 wl_signal_add(&cw->events.hide, listener);
6693 #ifdef REFACTOR_DESK_AREA
6695 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6698 wl_signal_add(&cw->events.set_layer, listener);
6702 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6705 wl_signal_add(&cw->events.stack_above, listener);
6709 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6712 wl_signal_add(&cw->events.stack_below, listener);