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"
24 = keys that return objects =
25 - E_Client: the client associated with the object (E_Client*)
26 - comp_smart_obj: cw->smart_obj (Evas_Object*)
27 - comp_obj: cw (E_Comp_Object*)
29 = keys that are bool flags =
30 - client_restack: client needs a protocol-level restack
31 - comp_override: object is triggering a nocomp override to force compositing
32 - comp_ref: object has a ref from visibility animations
33 - comp_showing: object is currently running its show animation
34 - comp_hiding: object is currently running its hiding animation
35 - comp_object: object is a compositor-created object
36 - comp_object_skip: object has a name which prohibits theme shadows
37 - comp_object-to_del: list of objects which will be deleted when this object is deleted
38 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
39 - effect_running: object is animating by external module
42 #define UPDATE_MAX 512 // same as evas
43 #define FAILURE_MAX 2 // seems reasonable
44 #define SMART_NAME "e_comp_object"
45 #define INPUT_OBJ_SMART_NAME "input_object"
47 /* for non-util functions */
48 #define API_ENTRY E_Comp_Object *cw; \
49 cw = evas_object_smart_data_get(obj); \
50 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
52 /* for util functions (obj may or may not be E_Comp_Object */
53 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
56 CRI("YOU PASSED NULL! ARGH!"); \
59 cw = evas_object_smart_data_get(obj); \
60 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
62 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
64 /* enable for lots of client size info in console output */
66 # define e_util_size_debug_set(x, y)
69 /* enable along with display-specific damage INF calls to enable render tracing
73 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
75 #define RENDER_DEBUG(...)
78 #ifdef REFACTOR_DESK_AREA
80 typedef struct _E_Comp_Object
84 int x, y, w, h; // geometry
88 E_Comp_Object_Frame client_inset;
90 Eina_Stringshare *frame_theme;
91 Eina_Stringshare *frame_name;
92 Eina_Stringshare *visibility_effect; //effect when toggling visibility
94 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
96 Evas_Object *smart_obj; // smart object
97 Evas_Object *clip; // clipper over effect object
98 Evas_Object *input_obj; // input smart object
99 Evas_Object *obj; // composite object
100 Evas_Object *frame_object; // for client frames
101 Evas_Object *shobj; // shadow object
102 Evas_Object *effect_obj; // effects object
103 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
107 } transform_bg_color;
108 Evas_Object *transform_tranp_obj;// transform transp rect obj
109 Evas_Object *default_input_obj; // default input object
110 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
111 Eina_List *obj_mirror; // extra mirror objects
112 Eina_Tiler *updates; //render update regions
113 Eina_Tiler *pending_updates; //render update regions which are about to render
115 Evas_Native_Surface *ns; //for custom gl rendering
117 struct wl_listener buffer_destroy_listener;
119 unsigned int update_count; // how many updates have happened to this obj
121 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
123 unsigned int animating; // it's busy animating
124 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
125 unsigned int force_visible; //number of visible obj_mirror objects
126 Eina_Bool delete_pending : 1; // delete pending
127 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
128 Eina_Bool showing : 1; // object is currently in "show" animation
129 Eina_Bool hiding : 1; // object is currently in "hide" animation
130 Eina_Bool visible : 1; // is visible
132 Eina_Bool shaped : 1; // is shaped
133 Eina_Bool update : 1; // has updates to fetch
134 Eina_Bool redirected : 1; // has updates to fetch
135 Eina_Bool native : 1; // native
137 Eina_Bool nocomp : 1; // nocomp applied
138 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
139 Eina_Bool real_hid : 1; // last hide was a real window unmap
141 Eina_Bool effect_set : 1; //effect_obj has a valid group
142 Eina_Bool effect_running : 1; //effect_obj is playing an animation
143 Eina_Bool effect_clip : 1; //effect_obj is clipped
144 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
146 Eina_Bool updates_exist : 1;
147 Eina_Bool updates_full : 1; // entire object will be updated
149 Eina_Bool force_move : 1;
150 Eina_Bool frame_extends : 1; //frame may extend beyond object size
151 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
152 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
153 Eina_Bool user_alpha_set : 1;
154 Eina_Bool user_alpha : 1;
158 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
159 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
166 } indicator; //indicator object for internal client
170 Evas_Object *mask_obj;
173 int mask_x, mask_y, mask_w, mask_h;
176 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
178 tbm_surface_h tbm_surface;
179 E_Comp_Image_Filter image_filter;
180 Eina_Bool set_mouse_callbacks;
185 E_Comp_Wl_Buffer_Ref buffer_ref;
186 Eina_Bool pending_move_set;
187 int pending_move_x, pending_move_y;
188 Eina_Bool pending_resize_set;
189 int pending_resize_w, pending_resize_h;
190 } render_update_lock;
203 struct wl_signal lower;
204 //#ifdef REFACTOR_DESK_AREA
205 struct wl_signal raise;
207 struct wl_signal show;
208 struct wl_signal hide;
209 //#ifdef REFACTOR_DESK_AREA
210 struct wl_signal set_layer;
211 struct wl_signal stack_above;
212 struct wl_signal stack_below;
218 typedef struct _E_Input_Rect_Data
224 typedef struct _E_Input_Rect_Smart_Data
226 Eina_List *input_rect_data_list;
228 } E_Input_Rect_Smart_Data;
230 struct E_Comp_Object_Mover
233 E_Comp_Object_Mover_Cb func;
239 static Eina_Inlist *_e_comp_object_movers = NULL;
240 static Evas_Smart *_e_comp_smart = NULL;
241 static Evas_Smart *_e_comp_input_obj_smart = NULL;
243 static int _e_comp_object_hooks_delete = 0;
244 static int _e_comp_object_hooks_walking = 0;
246 static Eina_Inlist *_e_comp_object_hooks[] =
248 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
249 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
250 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
251 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
252 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
253 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
254 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
255 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
258 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
259 static int _e_comp_object_intercept_hooks_delete = 0;
260 static int _e_comp_object_intercept_hooks_walking = 0;
262 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
264 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
265 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
269 static Eina_Bool _damage_trace = EINA_FALSE;
270 static Eina_List *_damage_trace_objs = NULL;
271 static Eina_List *_damage_trace_post_objs = NULL;
273 /* sekrit functionzzz */
274 EINTERN void e_client_focused_set(E_Client *ec);
276 /* emitted every time a new noteworthy comp object is added */
277 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
279 /* ecore event define */
280 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
281 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
282 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
284 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
285 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
286 static void _e_comp_object_dim_update(E_Comp_Object *cw);
287 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
288 #ifdef REFACTOR_DESK_AREA
290 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
293 static E_Client *dim_client = NULL;
296 _e_comp_object_hooks_clean(void)
299 E_Comp_Object_Hook *ch;
302 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
303 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
305 if (!ch->delete_me) continue;
306 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
312 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
314 E_Comp_Object_Hook *ch;
315 Eina_Bool ret = EINA_TRUE;
317 if (e_object_is_del(E_OBJECT(ec)))
319 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
320 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
321 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
322 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
323 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
324 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
325 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
326 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
332 e_object_ref(E_OBJECT(ec));
333 _e_comp_object_hooks_walking++;
334 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
336 if (ch->delete_me) continue;
337 if (!(ch->func(ch->data, ec)))
343 _e_comp_object_hooks_walking--;
344 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
345 _e_comp_object_hooks_clean();
347 e_object_unref(E_OBJECT(ec));
352 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
354 _e_comp_object_intercept_hooks_clean(void)
357 E_Comp_Object_Intercept_Hook *ch;
360 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
361 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
363 if (!ch->delete_me) continue;
364 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
370 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
372 E_Comp_Object_Intercept_Hook *ch;
373 Eina_Bool ret = EINA_TRUE;
375 if (e_object_is_del(E_OBJECT(ec))) return ret;
376 e_object_ref(E_OBJECT(ec));
377 _e_comp_object_intercept_hooks_walking++;
378 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
380 if (ch->delete_me) continue;
381 if (!(ch->func(ch->data, ec)))
387 _e_comp_object_intercept_hooks_walking--;
388 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
389 _e_comp_object_intercept_hooks_clean();
391 e_object_unref(E_OBJECT(ec));
398 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
400 E_Event_Comp_Object *ev = event;
403 ec = evas_object_data_get(ev->comp_object, "E_Client");
407 e_object_unref(E_OBJECT(ec));
409 evas_object_unref(ev->comp_object);
414 _e_comp_object_event_add(Evas_Object *obj)
416 E_Event_Comp_Object *ev;
419 if (stopping) return;
420 ev = E_NEW(E_Event_Comp_Object, 1);
421 EINA_SAFETY_ON_NULL_RETURN(ev);
423 evas_object_ref(obj);
424 ev->comp_object = obj;
425 ec = evas_object_data_get(ev->comp_object, "E_Client");
429 e_object_ref(E_OBJECT(ec));
431 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
435 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
437 E_Event_Comp_Object *ev = event;
440 ec = evas_object_data_get(ev->comp_object, "E_Client");
444 e_object_unref(E_OBJECT(ec));
446 evas_object_unref(ev->comp_object);
451 _e_comp_object_event_simple(Evas_Object *obj, int type)
453 E_Event_Comp_Object *ev;
456 ev = E_NEW(E_Event_Comp_Object, 1);
459 evas_object_ref(obj);
460 ev->comp_object = obj;
461 ec = evas_object_data_get(ev->comp_object, "E_Client");
465 e_object_ref(E_OBJECT(ec));
467 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
469 /////////////////////////////////////
472 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
474 E_Comp_Object *cw = data;
476 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
480 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
482 E_Comp_Object *cw = data;
484 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
485 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
488 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
489 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
493 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
495 E_Comp_Object *cw = data;
498 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
499 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
502 /////////////////////////////////////
504 #ifdef REFACTOR_DESK_AREA
506 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
509 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
514 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
515 if (cw->ec->input_only) return;
517 layer = evas_object_layer_get(obj);
519 if (cw->transform_bg_obj)
521 if (layer != evas_object_layer_get(cw->transform_bg_obj))
523 evas_object_layer_set(cw->transform_bg_obj, layer);
526 evas_object_stack_below(cw->transform_bg_obj, obj);
529 if (cw->transform_tranp_obj)
531 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
533 evas_object_layer_set(cw->transform_tranp_obj, layer);
536 evas_object_stack_below(cw->transform_tranp_obj, obj);
541 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
548 if (!map) return NULL;
550 e_map_util_points_populate_from_object_full(map, obj, 0);
551 e_map_util_points_color_set(map, 255, 255, 255, 255);
553 for (i = 0 ; i < 4 ; ++i)
558 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
559 e_map_point_coord_set(map, i, x, y, 1.0);
566 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
572 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
575 e_comp_object_map_set(obj, map);
576 e_comp_object_map_enable_set(obj, EINA_TRUE);
583 evas_object_map_enable_set(obj, EINA_FALSE);
588 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
594 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
597 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
599 e_comp_object_map_set(obj, map);
600 e_comp_object_map_enable_set(obj, EINA_TRUE);
607 evas_object_map_enable_set(obj, EINA_FALSE);
610 /////////////////////////////////////
612 static inline Eina_Bool
613 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
615 if (num > 1) return EINA_TRUE;
616 if ((rects[0].x == 0) && (rects[0].y == 0) &&
617 ((int)rects[0].w == w) && ((int)rects[0].h == h))
622 /////////////////////////////////////
624 /* add a client to the layer-client list */
625 #ifdef REFACTOR_DESK_AREA
628 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
630 g_rec_mutex_lock(&e_comp->ec_list_mutex);
633 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));
635 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));
636 if ((!above) && (!below))
639 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
640 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
641 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
643 e_comp->layers[cw->layer].clients_count++;
645 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
649 _e_comp_object_layers_remove(E_Comp_Object *cw)
651 g_rec_mutex_lock(&e_comp->ec_list_mutex);
653 if (cw->ec && e_comp->layers[cw->layer].clients)
655 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
656 e_comp->layers[cw->layer].clients_count--;
659 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
663 /////////////////////////////////////
665 _e_comp_object_alpha_set(E_Comp_Object *cw)
667 Eina_Bool alpha = cw->ec->argb;
669 if ((cw->external_content) &&
670 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
675 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
676 if (cw->user_alpha_set) alpha = cw->user_alpha;
678 evas_object_image_alpha_set(cw->obj, alpha);
682 _e_comp_object_shadow(E_Comp_Object *cw)
684 if (e_client_util_shadow_state_get(cw->ec))
685 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
687 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
688 if (cw->frame_object)
689 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
690 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
693 /* convert from the surface coordinates to the buffer coordinates */
695 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
697 E_Comp_Wl_Buffer_Viewport *vp;
698 E_Comp_Wl_Client_Data *cdata;
702 cdata = e_client_cdata_get(ec);
704 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
711 vp = &cdata->scaler.buffer_viewport;
712 transform = e_comp_wl_output_buffer_transform_get(ec);
714 e_pixmap_size_get(ec->pixmap, &bw, &bh);
716 /* for subsurface, it should be swap 90 and 270 */
717 if (e_comp_wl_subsurface_check(ec))
720 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
721 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
722 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
723 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
729 case WL_OUTPUT_TRANSFORM_NORMAL:
730 default: tx = sx, ty = sy; break;
731 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
732 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
733 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
734 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
735 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
736 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
737 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
740 tx *= vp->buffer.scale;
741 ty *= vp->buffer.scale;
748 _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)
756 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
757 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
764 if (dw) *dw = MAX(x1, x2) - mx;
765 if (dh) *dh = MAX(y1, y2) - my;
769 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
770 int *dx, int *dy, int *dw, int *dh)
772 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
773 E_Util_Transform_Rect_Vertex sv, dv;
777 e_pixmap_size_get(ec->pixmap, &bw, &bh);
779 sv = e_util_transform_rect_to_vertices(&rect);
781 for (i = 0; i < 4; i++)
783 double x = 0.0, y = 0.0;
785 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
787 /* if evas decide coordinate is outside of map, it returns (0, 0)
788 in this case, full damage is added.
790 if ((i != 0) && (x == 0.0) && (y == 0.0))
793 dv.vertices[i].vertex[0] = x;
794 dv.vertices[i].vertex[1] = y;
795 dv.vertices[i].vertex[2] = 1.0;
796 dv.vertices[i].vertex[3] = 1.0;
799 rect = e_util_transform_vertices_to_rect(&dv);
801 if (dx) *dx = rect.x;
802 if (dy) *dy = rect.y;
803 if (dw) *dw = rect.w;
804 if (dh) *dh = rect.h;
818 _e_comp_object_map_damage_transform_get(E_Client *ec)
825 if (!e_client_transform_core_enable_get(ec))
828 m = e_client_map_get(ec);
832 e_pixmap_size_get(ec->pixmap, &bw, &bh);
833 if ((bw == 0) || (bh == 0))
846 e_map_point_coord_set(m2, 0, 0, 0, 0);
847 e_map_point_coord_set(m2, 1, bw, 0, 0);
848 e_map_point_coord_set(m2, 2, bw, bh, 0);
849 e_map_point_coord_set(m2, 3, 0, bh, 0);
851 for (i = 0; i < 4; i++)
855 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
856 e_map_point_image_uv_set(m2, i, map_x, map_y);
863 /////////////////////////////////////
865 /* handle evas mouse-in events on client object */
867 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
869 Evas_Event_Mouse_In *ev = event_info;
870 E_Comp_Object *cw = data;
872 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
875 /* handle evas mouse-out events on client object */
877 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
879 Evas_Event_Mouse_Out *ev = event_info;
880 E_Comp_Object *cw = data;
882 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
885 /* handle evas mouse wheel events on client object */
887 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
889 Evas_Event_Mouse_Wheel *ev = event_info;
890 E_Comp_Object *cw = data;
891 E_Binding_Event_Wheel ev2;
894 if (e_client_action_get()) return;
895 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
896 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
899 /* handle evas mouse down events on client object */
901 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
903 Evas_Event_Mouse_Down *ev = event_info;
904 E_Comp_Object *cw = data;
905 E_Binding_Event_Mouse_Button ev2;
908 if (e_client_action_get()) return;
909 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
910 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
913 /* handle evas mouse up events on client object */
915 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
917 Evas_Event_Mouse_Up *ev = event_info;
918 E_Comp_Object *cw = data;
919 E_Binding_Event_Mouse_Button ev2;
922 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
923 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
924 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
927 /* handle evas mouse movement events on client object */
929 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
931 Evas_Event_Mouse_Move *ev = event_info;
932 E_Comp_Object *cw = data;
935 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
936 e_client_mouse_move(cw->ec, &ev->cur.output);
938 /////////////////////////////////////
940 /* helper function for checking compositor themes based on user-defined matches */
942 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
944 if (((m->title) && (!ec->netwm.name)) ||
945 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
947 #if defined(__cplusplus) || defined(c_plusplus)
948 if (((m->clas) && (!ec->icccm.cpp_class)) ||
949 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
952 if (((m->clas) && (!ec->icccm.class)) ||
953 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
957 if (((m->role) && (!ec->icccm.window_role)) ||
958 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
964 if ((int)ec->netwm.type != m->primary_type)
967 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
970 if (m->borderless != 0)
974 if (e_client_util_borderless(ec))
976 if (!(((m->borderless == -1) && (!borderless)) ||
977 ((m->borderless == 1) && (borderless))))
984 if (((ec->icccm.transient_for != 0) ||
987 if (!(((m->dialog == -1) && (!dialog)) ||
988 ((m->dialog == 1) && (dialog))))
991 if (m->accepts_focus != 0)
993 int accepts_focus = 0;
995 if (ec->icccm.accepts_focus)
997 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
998 ((m->accepts_focus == 1) && (accepts_focus))))
1007 if (!(((m->vkbd == -1) && (!vkbd)) ||
1008 ((m->vkbd == 1) && (vkbd))))
1013 if (!(((m->argb == -1) && (!ec->argb)) ||
1014 ((m->argb == 1) && (ec->argb))))
1017 if (m->fullscreen != 0)
1019 int fullscreen = ec->fullscreen;
1021 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1022 ((m->fullscreen == 1) && (fullscreen))))
1027 if (!(m->modal == -1))
1033 /* function for setting up a client's compositor frame theme (cw->shobj) */
1035 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1039 Eina_List *list = NULL, *l;
1040 E_Input_Rect_Data *input_rect_data;
1041 E_Input_Rect_Smart_Data *input_rect_sd;
1043 Eina_Stringshare *reshadow_group = NULL;
1044 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1045 Eina_Stringshare *name, *title;
1046 E_Comp_Config *conf = e_comp_config_get();
1048 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1049 /* match correct client type */
1050 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1051 name = cw->ec->icccm.name;
1052 title = cw->ec->icccm.title;
1053 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1054 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1056 /* skipping here is mostly a hack for systray because I hate it */
1059 EINA_LIST_FOREACH(list, l, m)
1061 if (((m->name) && (!name)) ||
1062 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1064 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1067 no_shadow = m->no_shadow;
1068 if (m->shadow_style)
1070 /* fast effects are just themes with "/fast" appended and shorter effect times */
1073 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1074 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1076 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1078 /* default to non-fast style if fast not available */
1081 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1082 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1084 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1086 if (ok && m->visibility_effect)
1087 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1094 if (skip || (cw->ec->e.state.video))
1096 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1098 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1101 if (conf->shadow_style)
1105 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1106 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1108 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1112 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1113 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1122 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1124 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1128 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1130 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1135 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1140 if (cw->ec->override)
1142 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1143 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1145 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1146 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1152 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1153 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1156 _e_comp_object_shadow(cw);
1159 if (focus || cw->ec->focused || cw->ec->override)
1160 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1162 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1167 /* visibility must always be enabled for re_manage clients to prevent
1168 * pop-in animations every time the user sees a persistent client again;
1169 * applying visibility for iconic clients prevents the client from getting
1172 if (cw->visible || cw->ec->re_manage)
1173 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1175 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1177 /* breaks animation counter */
1178 if (cw->frame_object)
1180 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1181 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1182 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1183 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1189 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1193 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1196 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1198 if (input_rect_data->obj)
1200 pass_event_flag = EINA_TRUE;
1206 if (cw->indicator.obj)
1208 Evas_Object *indicator;
1209 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1210 if (indicator != cw->indicator.obj)
1212 edje_object_part_unswallow(cw->shobj, indicator);
1213 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1214 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1218 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1219 evas_object_pass_events_set(cw->obj, pass_event_flag);
1224 /////////////////////////////////////////////
1227 _e_comp_object_animating_begin(E_Comp_Object *cw)
1230 if (cw->animating == 1)
1232 e_comp->animating++;
1234 e_object_ref(E_OBJECT(cw->ec));
1239 _e_comp_object_animating_end(E_Comp_Object *cw)
1248 if (cw->ec->launching)
1250 if (!cw->ec->extra_animating)
1252 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1253 cw->ec->launching = EINA_FALSE;
1254 if (cw->ec->first_mapped)
1256 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1257 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1260 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1264 e_comp->animating--;
1265 cw->showing = cw->hiding = 0;
1267 if (e_comp->animating == 0)
1268 e_comp_visibility_calculation_set(EINA_TRUE);
1269 /* remove ref from animation start, account for possibility of deletion from unref */
1270 return !!e_object_unref(E_OBJECT(cw->ec));
1276 /* handle the end of a compositor animation */
1278 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1280 E_Comp_Object *cw = data;
1282 /* visible clients which have never been sized are a bug */
1283 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1284 CRI("ACK! ec:%p", cw->ec);
1285 if (!_e_comp_object_animating_end(cw)) return;
1286 if (cw->animating) return;
1287 /* hide only after animation finishes to guarantee a full run of the animation */
1288 if (!cw->defer_hide) return;
1289 if ((!strcmp(emission, "e,action,hide,done")) ||
1290 (!strcmp(emission, "e,action,done")) ||
1291 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1293 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1294 evas_object_hide(cw->smart_obj);
1298 /* run a visibility compositor effect if available, return false if object is dead */
1300 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1306 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1307 if (!cw->effect_running)
1308 _e_comp_object_animating_begin(cw);
1309 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1310 return _e_comp_object_animating_end(cw);
1311 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1312 return _e_comp_object_animating_end(cw);
1314 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1317 zone = e_comp_zone_find_by_ec(cw->ec);
1319 zw = zone->w, zh = zone->h;
1324 zone = e_comp_object_util_zone_get(cw->smart_obj);
1325 if (!zone) zone = e_zone_current_get();
1332 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1333 cw->w, cw->h, zw, zh, x, y}, 8);
1334 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1335 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1338 /////////////////////////////////////////////
1340 /* create necessary objects for clients that e manages */
1342 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1344 if (cw->set_mouse_callbacks) return;
1345 if (!cw->smart_obj) return;
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1348 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1350 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1351 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1352 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1354 cw->set_mouse_callbacks = EINA_TRUE;
1358 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1360 if (!cw->set_mouse_callbacks) return;
1361 if (!cw->smart_obj) return;
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1364 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1366 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1367 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1368 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1370 cw->set_mouse_callbacks = EINA_FALSE;
1374 _e_comp_object_setup(E_Comp_Object *cw)
1376 cw->clip = evas_object_rectangle_add(e_comp->evas);
1377 evas_object_move(cw->clip, -9999, -9999);
1378 evas_object_resize(cw->clip, 999999, 999999);
1379 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1380 cw->effect_obj = edje_object_add(e_comp->evas);
1381 evas_object_move(cw->effect_obj, cw->x, cw->y);
1382 evas_object_clip_set(cw->effect_obj, cw->clip);
1383 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1384 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1385 cw->shobj = edje_object_add(e_comp->evas);
1386 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1387 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1388 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1390 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1391 if (cw->ec->override)
1393 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1394 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1395 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1397 else if (!cw->ec->input_only)
1399 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1400 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1401 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1403 cw->real_hid = !cw->ec->input_only;
1404 if (!cw->ec->input_only)
1406 e_util_size_debug_set(cw->effect_obj, 1);
1407 _e_comp_object_mouse_event_callback_set(cw);
1410 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1411 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1412 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1413 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1414 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1415 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1417 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1420 /////////////////////////////////////////////
1422 /* for fast path evas rendering; only called during render */
1424 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1426 E_Comp_Object *cw = data;
1427 E_Client *ec = cw->ec;
1429 int bx, by, bxx, byy;
1431 if (e_object_is_del(E_OBJECT(ec))) return;
1432 if (cw->external_content) return;
1433 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1434 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1437 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1438 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1440 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1442 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1443 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1447 bx = by = bxx = byy = 0;
1448 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1451 Edje_Message_Int_Set *msg;
1452 Edje_Message_Int msg2;
1453 Eina_Bool id = (bx || by || bxx || byy);
1455 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1461 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1463 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1467 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1468 e_comp_client_post_update_add(cw->ec);
1470 else if (e_comp_object_render(ec->frame))
1472 /* apply shape mask if necessary */
1473 if ((!cw->native) && (ec->shaped))
1474 e_comp_object_shape_apply(ec->frame);
1476 /* shaped clients get precise mouse events to handle transparent pixels */
1477 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1479 /* queue another render if client is still dirty; cannot refresh here. */
1480 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1481 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1483 if (cw->render_trace)
1485 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1491 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1493 E_Comp_Object *cw = data;
1494 E_Client *ec = cw->ec;
1496 if (e_object_is_del(E_OBJECT(ec))) return;
1497 if (cw->external_content) return;
1498 if (!e_comp->hwc) return;
1500 e_comp_client_render_list_add(cw->ec);
1502 if (!ec->hwc_window) return;
1504 e_hwc_windows_rendered_window_add(ec->hwc_window);
1507 /////////////////////////////////////////////
1510 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1512 E_Comp_Object *cw = data;
1515 if (cw->render_update_lock.lock)
1517 cw->render_update_lock.pending_move_x = x;
1518 cw->render_update_lock.pending_move_y = y;
1519 cw->render_update_lock.pending_move_set = EINA_TRUE;
1523 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1524 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1525 (cw->external_content))
1527 /* delay to move until the external content is unset */
1528 cw->ec->changes.pos = 1;
1533 if (cw->ec->move_after_resize)
1535 if ((x != cw->ec->x) || (y != cw->ec->y))
1537 if (!cw->ec->is_cursor)
1538 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1539 e_client_pos_set(cw->ec, x, y);
1540 cw->ec->changes.pos = 1;
1546 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1547 (cw->ec->manage_resize.resize_obj))
1549 e_client_pos_set(cw->ec, x, y);
1550 cw->ec->client.x = x + cw->client_inset.l;
1551 cw->ec->client.y = y + cw->client_inset.t;
1552 e_policy_visibility_client_defer_move(cw->ec);
1556 /* if frame_object does not exist, client_inset indicates CSD.
1557 * this means that ec->client matches cw->x/y, the opposite
1560 fx = (!cw->frame_object) * cw->client_inset.l;
1561 fy = (!cw->frame_object) * cw->client_inset.t;
1562 if ((cw->x == x + fx) && (cw->y == y + fy))
1564 if ((cw->ec->x != x) || (cw->ec->y != y))
1566 /* handle case where client tries to move to position and back very quickly */
1567 e_client_pos_set(cw->ec, x, y);
1568 cw->ec->client.x = x + cw->client_inset.l;
1569 cw->ec->client.y = y + cw->client_inset.t;
1573 if (!cw->ec->maximize_override)
1575 /* prevent moving in some directions while directionally maximized */
1576 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1578 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1581 ix = x + cw->client_inset.l;
1582 iy = y + cw->client_inset.t;
1583 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1584 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1585 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1587 /* prevent moving at all if move isn't allowed in current maximize state */
1588 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1589 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1592 zone = e_comp_zone_find_by_ec(cw->ec);
1595 cw->ec->changes.need_unmaximize = 1;
1596 cw->ec->saved.x = ix - zone->x;
1597 cw->ec->saved.y = iy - zone->y;
1598 cw->ec->saved.w = cw->ec->client.w;
1599 cw->ec->saved.h = cw->ec->client.h;
1603 /* only update during resize if triggered by resize */
1604 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1605 /* delay to move while surface waits paired commit serial*/
1606 if (e_client_pending_geometry_has(cw->ec))
1608 /* do nothing while waiting paired commit serial*/
1612 e_client_pos_set(cw->ec, x, y);
1613 if (cw->ec->new_client)
1615 /* don't actually do anything until first client idler loop */
1616 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1617 cw->ec->changes.pos = 1;
1622 /* only update xy position of client to avoid invalid
1623 * first damage region if it is not a new_client. */
1624 cw->ec->client.x = ix;
1625 cw->ec->client.y = iy;
1628 if (!cw->frame_object)
1630 evas_object_move(obj, x, y);
1635 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1637 E_Comp_Object *cw = data;
1638 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1641 if (cw->render_update_lock.lock)
1643 cw->render_update_lock.pending_resize_w = w;
1644 cw->render_update_lock.pending_resize_h = h;
1645 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1649 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1651 e_client_size_set(cw->ec, w, h);
1652 evas_object_resize(obj, w, h);
1656 /* if frame_object does not exist, client_inset indicates CSD.
1657 * this means that ec->client matches cw->w/h, the opposite
1660 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1661 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1662 if ((cw->w == w + fw) && (cw->h == h + fh))
1664 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1665 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1666 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1668 /* handle case where client tries to resize itself and back very quickly */
1669 e_client_size_set(cw->ec, w, h);
1670 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1671 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1672 evas_object_smart_callback_call(obj, "client_resize", NULL);
1676 /* guarantee that fullscreen is fullscreen */
1677 zone = e_comp_zone_find_by_ec(cw->ec);
1679 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1681 if (!e_client_transform_core_enable_get(cw->ec))
1684 /* calculate client size */
1685 iw = w - cw->client_inset.l - cw->client_inset.r;
1686 ih = h - cw->client_inset.t - cw->client_inset.b;
1687 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1689 /* prevent resizing while maximized depending on direction and config */
1690 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1692 Eina_Bool reject = EINA_FALSE;
1693 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1695 if (cw->ec->client.h != ih)
1697 cw->ec->saved.h = ih;
1698 cw->ec->saved.y = cw->ec->client.y - zone->y;
1699 reject = cw->ec->changes.need_unmaximize = 1;
1702 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1704 if (cw->ec->client.w != iw)
1706 cw->ec->saved.w = iw;
1707 cw->ec->saved.x = cw->ec->client.x - zone->x;
1708 reject = cw->ec->changes.need_unmaximize = 1;
1717 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1719 /* do nothing until client idler loops */
1720 if ((cw->ec->w != w) || (cw->ec->h != h))
1722 e_client_size_set(cw->ec, w, h);
1723 cw->ec->changes.size = 1;
1728 if (e_client_pending_geometry_has(cw->ec))
1730 /* do nothing while waiting paired commit serial*/
1734 e_client_size_set(cw->ec, w, h);
1736 cw->ec->client.w = iw;
1737 cw->ec->client.h = ih;
1738 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1740 /* The size of non-compositing window can be changed, so there is a
1741 * need to check that cw is H/W composited if cw is not redirected.
1742 * And of course we have to change size of evas object of H/W composited cw,
1743 * otherwise cw can't receive input events even if it is shown on the screen.
1745 Eina_Bool redirected = cw->redirected;
1747 redirected = e_comp_is_on_overlay(cw->ec);
1749 if ((!cw->ec->input_only) && (redirected) &&
1750 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1751 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1752 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1753 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1756 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1757 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1759 prev_w = cw->w, prev_h = cw->h;
1760 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1761 /* check shading and clamp to pixmap size for regular clients */
1762 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1763 (((w - fw != pw) || (h - fh != ph))))
1765 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1766 evas_object_smart_callback_call(obj, "client_resize", NULL);
1768 if (cw->frame_object || cw->ec->input_only)
1769 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1772 if ((cw->w == w) && (cw->h == h))
1774 /* going to be a noop resize which won't trigger smart resize */
1775 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1776 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1778 evas_object_resize(obj, w, h);
1782 evas_object_smart_callback_call(obj, "client_resize", NULL);
1785 if ((!cw->frame_object) && (!cw->ec->input_only))
1787 /* "just do it" for overrides */
1788 evas_object_resize(obj, w, h);
1790 if (!cw->ec->override)
1792 /* shape probably changed for non-overrides */
1797 /* this fixes positioning jiggles when using a resize mode
1798 * which also changes the client's position
1801 if (cw->frame_object)
1802 x = cw->x, y = cw->y;
1804 x = cw->ec->x, y = cw->ec->y;
1805 switch (cw->ec->resize_mode)
1807 case E_POINTER_RESIZE_BL:
1808 case E_POINTER_RESIZE_L:
1809 evas_object_move(obj, x + prev_w - cw->w, y);
1811 case E_POINTER_RESIZE_TL:
1812 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1814 case E_POINTER_RESIZE_T:
1815 case E_POINTER_RESIZE_TR:
1816 evas_object_move(obj, x, y + prev_h - cw->h);
1825 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1827 #ifdef REFACTOR_DESK_AREA
1828 E_Comp_Object *cw = data;
1829 E_Comp_Object_Data_Set_Layer layer_set_data;
1831 layer_set_data.cw = cw;
1832 layer_set_data.layer = layer;
1834 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1838 e_comp_render_queue();
1839 _e_comp_object_transform_obj_stack_update(obj);
1843 E_Comp_Object *cw = data;
1844 E_Comp_Wl_Client_Data *child_cdata;
1845 unsigned int l = e_comp_canvas_layer_map(layer);
1848 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1850 /* doing a compositor effect, follow directions */
1851 _e_comp_object_layer_set(obj, layer);
1852 if (layer == cw->ec->layer) //trying to put layer back
1856 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1857 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1858 if (cw->layer != l) goto layer_set;
1862 e_comp_render_queue();
1864 ec = e_client_above_get(cw->ec);
1865 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1866 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1867 ec = e_client_above_get(ec);
1868 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1870 ec = e_client_below_get(cw->ec);
1871 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1872 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1873 ec = e_client_below_get(ec);
1874 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1876 evas_object_stack_above(obj, ec->frame);
1881 if (ec && (cw->ec->parent == ec))
1883 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1884 evas_object_stack_above(obj, ec->frame);
1886 evas_object_stack_below(obj, ec->frame);
1889 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1895 if (cw->layer == l) return;
1896 if (e_comp_canvas_client_layer_map(layer) == 9999)
1897 return; //invalid layer for clients not doing comp effects
1898 if (cw->ec->fullscreen)
1900 cw->ec->saved.layer = layer;
1903 oldraise = e_config->transient.raise;
1905 /* clamp to valid client layer */
1906 layer = e_comp_canvas_client_layer_map_nearest(layer);
1907 cw->ec->layer = layer;
1908 if (e_config->transient.layer)
1911 Eina_List *list = eina_list_clone(cw->ec->transients);
1913 /* We need to set raise to one, else the child wont
1914 * follow to the new layer. It should be like this,
1915 * even if the user usually doesn't want to raise
1918 e_config->transient.raise = 1;
1919 EINA_LIST_FREE(list, child)
1921 child_cdata = e_client_cdata_get(child);
1922 if (child_cdata && !child_cdata->mapped)
1924 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1927 e_client_layer_set(child, layer);
1931 e_config->transient.raise = oldraise;
1933 _e_comp_object_layers_remove(cw);
1934 cw->layer = e_comp_canvas_layer_map(layer);
1935 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1936 //if (cw->ec->new_client)
1937 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1938 _e_comp_object_layer_set(obj, layer);
1939 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1940 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1941 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1943 /* can't stack a client above its own layer marker */
1944 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1946 if (!cw->visible) return;
1947 e_comp_render_queue();
1948 _e_comp_object_transform_obj_stack_update(obj);
1952 #ifdef REFACTOR_DESK_AREA
1954 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1957 #ifdef REFACTOR_DESK_AREA
1959 _e_comp_object_raise(Evas_Object *obj)
1962 _e_comp_object_raise(Evas_Object *obj)
1965 evas_object_raise(obj);
1967 if (evas_object_smart_smart_get(obj))
1969 E_Client *ec = e_comp_object_client_get(obj);
1971 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1975 #ifdef REFACTOR_DESK_AREA
1977 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1980 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1983 evas_object_lower(obj);
1985 if (evas_object_smart_smart_get(obj))
1987 E_Client *ec = e_comp_object_client_get(obj);
1990 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1991 #ifdef REFACTOR_DESK_AREA
1992 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1994 wl_signal_emit_mutable(&cw->events.lower, NULL);
2000 #ifdef REFACTOR_DESK_AREA
2002 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2005 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2008 evas_object_stack_above(obj, target);
2010 if (evas_object_smart_smart_get(obj))
2012 E_Client *ec = e_comp_object_client_get(obj);
2014 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2018 #ifdef REFACTOR_DESK_AREA
2020 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2023 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2026 evas_object_stack_below(obj, target);
2028 if (evas_object_smart_smart_get(obj))
2030 E_Client *ec = e_comp_object_client_get(obj);
2032 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2036 #ifdef REFACTOR_DESK_AREA
2038 e_comp_object_layer_set(Evas_Object *obj, short layer)
2041 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2044 evas_object_layer_set(obj, layer);
2046 if (evas_object_smart_smart_get(obj))
2048 E_Client *ec = e_comp_object_client_get(obj);
2050 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2054 #ifdef REFACTOR_DESK_AREA
2057 _e_comp_object_is_pending(E_Client *ec)
2061 if (!ec) return EINA_FALSE;
2063 topmost = e_comp_wl_topmost_parent_get(ec);
2065 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2069 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2071 E_Comp_Object *cw2 = NULL;
2074 Evas_Object *o = stack;
2075 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2077 /* We should consider topmost's layer_pending for subsurface */
2078 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2080 if (_e_comp_object_is_pending(cw->ec))
2081 e_comp_object_layer_update(cw->smart_obj,
2082 raising? stack : NULL,
2083 raising? NULL : stack);
2085 /* obey compositor effects! */
2086 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2087 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2088 stack_cb(cw->smart_obj, stack);
2089 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2090 evas_object_data_del(cw->smart_obj, "client_restack");
2094 cw2 = evas_object_data_get(o, "comp_obj");
2096 /* assume someone knew what they were doing during client init */
2097 if (cw->ec->new_client)
2098 layer = cw->ec->layer;
2099 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2100 layer = cw2->ec->layer;
2102 layer = evas_object_layer_get(stack);
2103 ecstack = e_client_below_get(cw->ec);
2104 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2106 evas_object_layer_set(cw->smart_obj, layer);
2107 /* we got our layer wrangled, return now! */
2108 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2111 /* check if we're stacking below another client */
2114 /* check for non-client layer object */
2115 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2117 /* find an existing client to use for layering
2118 * by walking up the object stack
2120 * this is guaranteed to be pretty quick since we'll either:
2121 * - run out of client layers
2122 * - find a stacking client
2124 o = evas_object_above_get(o);
2125 if ((!o) || (o == cw->smart_obj)) break;
2126 if (evas_object_layer_get(o) != layer)
2128 /* reached the top client layer somehow
2129 * use top client object
2131 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2134 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2135 * return here since the top client layer window
2140 ec = e_client_top_get();
2145 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2148 if (cw2 && cw->layer != cw2->layer)
2151 /* remove existing layers */
2152 _e_comp_object_layers_remove(cw);
2155 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2156 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2157 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2158 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2159 else //if no stacking objects found, either raise or lower
2160 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2163 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2165 /* find new object for stacking if cw2 is on state of layer_pending */
2166 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2168 E_Client *new_stack = NULL, *current_ec = NULL;
2169 current_ec = cw2->ec;
2172 while ((new_stack = e_client_below_get(current_ec)))
2174 current_ec = new_stack;
2175 if (new_stack == cw->ec) continue;
2176 if (new_stack->layer != cw2->ec->layer) break;
2177 if (!_e_comp_object_is_pending(new_stack)) break;
2179 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2180 stack = new_stack->frame;
2183 /* stack it above layer object */
2185 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2186 stack = e_comp->layers[below_layer].obj;
2191 while ((new_stack = e_client_above_get(current_ec)))
2193 current_ec = new_stack;
2194 if (new_stack == cw->ec) continue;
2195 if (new_stack->layer != cw2->ec->layer) break;
2196 if (!_e_comp_object_is_pending(new_stack)) break;
2198 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2199 stack = new_stack->frame;
2201 stack = e_comp->layers[cw2->layer].obj;
2205 /* set restack if stacking has changed */
2206 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2207 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2208 stack_cb(cw->smart_obj, stack);
2209 if (e_comp->layers[cw->layer].obj)
2210 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2212 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2214 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2215 evas_object_data_del(cw->smart_obj, "client_restack");
2216 if (!cw->visible) return;
2217 e_comp_render_queue();
2222 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2224 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2226 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2228 #ifdef REFACTOR_DESK_AREA
2229 E_Comp_Object *cw = data;
2230 E_Comp_Object_Data_Stack_Above stack_above_data;
2232 stack_above_data.cw = cw;
2233 stack_above_data.above_obj = above;
2235 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2237 if (evas_object_below_get(obj) == above)
2239 e_comp_object_layer_update(obj, above, NULL);
2243 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2245 _e_comp_object_transform_obj_stack_update(obj);
2246 _e_comp_object_transform_obj_stack_update(above);
2253 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2255 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2257 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2259 #ifdef REFACTOR_DESK_AREA
2260 E_Comp_Object *cw = data;
2261 E_Comp_Object_Data_Stack_Below stack_below_data;
2263 stack_below_data.cw = cw;
2264 stack_below_data.below_obj = below;
2266 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2269 e_comp_render_queue();
2271 if (evas_object_above_get(obj) == below)
2273 e_comp_object_layer_update(obj, NULL, below);
2277 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2279 if (evas_object_smart_smart_get(obj))
2280 _e_comp_object_transform_obj_stack_update(obj);
2281 if (evas_object_smart_smart_get(below))
2282 _e_comp_object_transform_obj_stack_update(below);
2289 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2291 E_Comp_Object *cw = data;
2293 #ifdef REFACTOR_DESK_AREA
2298 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2300 #ifdef REFACTOR_DESK_AREA
2301 wl_signal_emit_mutable(&cw->events.lower, cw);
2303 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2305 if (cw->ec->layer_pending)
2306 e_comp_object_layer_update(obj, NULL, obj);
2308 _e_comp_object_lower(cw, obj);
2311 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2312 o = evas_object_below_get(obj);
2313 _e_comp_object_layers_remove(cw);
2314 /* prepend to client list since this client should be the first item now */
2315 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2316 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2317 evas_object_data_set(obj, "client_restack", (void*)1);
2318 _e_comp_object_lower(cw, obj);
2319 evas_object_data_del(obj, "client_restack");
2320 if (!cw->visible) goto end;
2321 e_comp_render_queue();
2322 _e_comp_object_transform_obj_stack_update(obj);
2330 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2332 E_Comp_Object *cw = data;
2333 #ifdef REFACTOR_DESK_AREA
2339 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2341 #ifdef REFACTOR_DESK_AREA
2342 wl_signal_emit_mutable(&cw->events.raise, cw);
2344 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2346 if (cw->ec->layer_pending)
2348 int obj_layer = evas_object_layer_get(obj);
2349 if (cw->ec->layer != obj_layer)
2350 e_comp_object_layer_update(obj, NULL, NULL);
2353 _e_comp_object_raise(obj);
2356 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2357 o = evas_object_above_get(obj);
2358 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2360 /* still stack below override below the layer marker */
2361 for (op = o = e_comp->layers[cw->layer].obj;
2362 o && o != e_comp->layers[cw->layer - 1].obj;
2363 op = o, o = evas_object_below_get(o))
2365 if (evas_object_smart_smart_get(o))
2369 ec = e_comp_object_client_get(o);
2370 if (ec && (!ec->override)) break;
2373 _e_comp_object_stack_below(obj, op);
2374 e_client_focus_defer_set(cw->ec);
2376 if (!cw->visible) goto end;
2377 e_comp_render_queue();
2378 _e_comp_object_transform_obj_stack_update(obj);
2386 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2388 E_Comp_Object *cw = data;
2390 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2391 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2393 ELOGF("COMP", "Hide. intercepted", cw->ec);
2398 if (cw->ec->launching == EINA_TRUE)
2400 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2401 cw->ec->launching = EINA_FALSE;
2406 /* hidden flag = just do it */
2407 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2408 evas_object_hide(obj);
2410 wl_signal_emit_mutable(&cw->events.hide, NULL);
2415 if (cw->ec->input_only)
2417 /* input_only = who cares */
2418 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2419 evas_object_hide(obj);
2421 wl_signal_emit_mutable(&cw->events.hide, NULL);
2425 /* already hidden or currently animating */
2426 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2428 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2432 /* don't try hiding during shutdown */
2433 cw->defer_hide |= stopping;
2434 if (!cw->defer_hide)
2436 if ((!cw->ec->iconic) && (!cw->ec->override))
2437 /* unset delete requested so the client doesn't break */
2438 cw->ec->delete_requested = 0;
2439 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2441 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2442 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2445 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2448 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2450 _e_comp_object_animating_begin(cw);
2451 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2453 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2454 cw->defer_hide = !!cw->animating;
2456 e_comp_object_effect_set(obj, NULL);
2459 if (cw->animating) return;
2460 /* if we have no animations running, go ahead and hide */
2462 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2463 evas_object_hide(obj);
2465 wl_signal_emit_mutable(&cw->events.hide, NULL);
2469 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2471 E_Client *ec = cw->ec;
2474 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2476 if (ec->show_pending.count > 0)
2478 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2479 ec->show_pending.running = EINA_TRUE;
2483 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2484 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2486 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2491 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,
2492 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2493 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2496 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2499 if (ec->iconic && cw->animating)
2501 /* triggered during iconify animation */
2502 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2505 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2508 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2509 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2511 evas_object_move(cw->smart_obj, ec->x, ec->y);
2512 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2513 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2515 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2516 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2519 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2520 evas_object_show(cw->smart_obj);
2523 e_client_focus_defer_set(ec);
2527 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2531 pw = ec->client.w, ph = ec->client.h;
2533 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2535 ec->changes.visible = !ec->hidden;
2538 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2542 cw->updates = eina_tiler_new(pw, ph);
2545 ec->changes.visible = !ec->hidden;
2548 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2553 eina_tiler_tile_size_set(cw->updates, 1, 1);
2556 /* ignore until client idler first run */
2557 ec->changes.visible = !ec->hidden;
2560 ELOGF("COMP", "show_helper. return. new_client", ec);
2567 evas_object_move(cw->smart_obj, ec->x, ec->y);
2568 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2569 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2570 evas_object_show(cw->smart_obj);
2573 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2575 /* start_drag not received */
2576 ec->changes.visible = 1;
2579 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2582 /* re-set geometry */
2583 evas_object_move(cw->smart_obj, ec->x, ec->y);
2584 /* force resize in case it hasn't happened yet, or just to update size */
2585 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2586 if ((cw->w < 1) || (cw->h < 1))
2588 /* if resize didn't go through, try again */
2589 ec->visible = ec->changes.visible = 1;
2591 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2594 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2595 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2596 e_pixmap_clear(ec->pixmap);
2598 if (cw->real_hid && w && h)
2601 /* force comp theming in case it didn't happen already */
2602 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2603 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2604 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2607 /* only do the show if show is allowed */
2610 if (ec->internal) //internal clients render when they feel like it
2611 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2613 if (!e_client_is_iconified_by_client(ec)||
2614 e_policy_visibility_client_is_uniconic(ec))
2616 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2617 evas_object_show(cw->smart_obj);
2619 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2620 it is rendered in idle callback without native surface and
2621 compositor shows an empty frame if other objects aren't shown
2622 because job callback of e_comp called at the next loop.
2623 it causes a visual defect when windows are switched.
2627 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2628 e_comp_object_dirty(cw->smart_obj);
2629 e_comp_object_render(cw->smart_obj);
2634 wl_signal_emit_mutable(&cw->events.show, NULL);
2638 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2640 E_Comp_Object *cw = data;
2641 E_Client *ec = cw->ec;
2643 E_Input_Rect_Data *input_rect_data;
2644 E_Input_Rect_Smart_Data *input_rect_sd;
2647 if (ec->ignored) return;
2651 //INF("SHOW2 %p", ec);
2652 _e_comp_intercept_show_helper(cw);
2655 //INF("SHOW %p", ec);
2658 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2659 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2660 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2661 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2665 if ((!cw->obj) && (cw->external_content))
2667 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2671 _e_comp_object_setup(cw);
2674 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2675 cw->obj = evas_object_image_filled_add(e_comp->evas);
2676 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2677 e_util_size_debug_set(cw->obj, 1);
2678 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2679 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2680 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2681 evas_object_name_set(cw->obj, "cw->obj");
2682 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2684 _e_comp_object_alpha_set(cw);
2687 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2690 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2691 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2694 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2697 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2699 if (input_rect_data->obj)
2701 evas_object_geometry_set(input_rect_data->obj,
2702 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2703 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2704 input_rect_data->rect.w, input_rect_data->rect.h);
2711 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2713 _e_comp_intercept_show_helper(cw);
2717 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2719 E_Comp_Object *cw = data;
2723 /* note: this is here as it seems there are enough apps that do not even
2724 * expect us to emulate a look of focus but not actually set x input
2725 * focus as we do - so simply abort any focus set on such windows */
2726 /* be strict about accepting focus hint */
2727 /* be strict about accepting focus hint */
2728 if ((!ec->icccm.accepts_focus) &&
2729 (!ec->icccm.take_focus))
2733 if (e_client_focused_get() == ec)
2734 e_client_focused_set(NULL);
2736 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2737 evas_object_focus_set(obj, focus);
2741 if (focus && ec->lock_focus_out) return;
2742 if (e_object_is_del(E_OBJECT(ec)) && focus)
2743 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2745 /* filter focus setting based on current state */
2750 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2751 evas_object_focus_set(obj, focus);
2754 if ((ec->iconic) && (!ec->deskshow))
2756 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2758 /* don't focus an iconified window. that's silly! */
2759 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2760 e_client_uniconify(ec);
2761 e_client_focus_latest_set(ec);
2775 /* not yet visible, wait till the next time... */
2776 ec->want_focus = !ec->hidden;
2781 e_client_focused_set(ec);
2785 if (e_client_focused_get() == ec)
2786 e_client_focused_set(NULL);
2790 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2792 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2794 evas_object_focus_set(obj, focus);
2798 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2800 E_Comp_Object *cw = data;
2802 if (cw->transparent.set)
2804 cw->transparent.user_r = r;
2805 cw->transparent.user_g = g;
2806 cw->transparent.user_b = b;
2807 cw->transparent.user_a = a;
2809 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2811 cw->transparent.user_r,
2812 cw->transparent.user_g,
2813 cw->transparent.user_b,
2814 cw->transparent.user_a);
2818 evas_object_color_set(obj, r, g, b, a);
2821 ////////////////////////////////////////////////////
2824 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2826 int w, h, ox, oy, ow, oh;
2828 Eina_Bool pass_event_flag = EINA_FALSE;
2829 E_Input_Rect_Data *input_rect_data;
2830 E_Input_Rect_Smart_Data *input_rect_sd;
2832 if (cw->frame_object)
2834 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2835 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2836 /* set a fixed size, force edje calc, check size difference */
2837 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2838 edje_object_message_signal_process(cw->frame_object);
2839 edje_object_calc_force(cw->frame_object);
2840 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2841 cw->client_inset.l = ox;
2842 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2843 cw->client_inset.t = oy;
2844 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2845 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2846 evas_object_resize(cw->frame_object, w, h);
2850 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2853 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2855 if (input_rect_data->obj)
2857 pass_event_flag = EINA_TRUE;
2863 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2864 evas_object_pass_events_set(cw->obj, pass_event_flag);
2868 cw->client_inset.l = 0;
2869 cw->client_inset.r = 0;
2870 cw->client_inset.t = 0;
2871 cw->client_inset.b = 0;
2873 cw->client_inset.calc = !!cw->frame_object;
2877 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2879 E_Comp_Object *cw = data;
2883 /* - get current size
2885 * - readjust for new frame size
2888 w = cw->ec->w, h = cw->ec->h;
2889 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2891 _e_comp_object_frame_recalc(cw);
2893 if (!cw->ec->fullscreen)
2894 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2896 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2897 if (cw->ec->fullscreen)
2899 zone = e_comp_zone_find_by_ec(cw->ec);
2901 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2903 else if (cw->ec->new_client)
2905 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2906 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2907 evas_object_resize(cw->ec->frame, w, h);
2909 else if ((w != cw->ec->w) || (h != cw->ec->h))
2910 evas_object_resize(cw->ec->frame, w, h);
2914 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2916 E_Comp_Object *cw = data;
2918 _e_comp_object_shadow_setup(cw);
2919 if (cw->frame_object)
2921 _e_comp_object_shadow(cw);
2922 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2923 _e_comp_object_frame_recalc(cw);
2924 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2929 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2931 E_Comp_Object *cw = data;
2933 if (_e_comp_object_shadow_setup(cw))
2934 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2935 if (cw->frame_object)
2937 _e_comp_object_shadow(cw);
2938 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2939 _e_comp_object_frame_recalc(cw);
2940 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2945 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2947 E_Comp_Object *cw = data;
2949 if (cw->frame_object)
2951 _e_comp_object_shadow(cw);
2952 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2953 _e_comp_object_frame_recalc(cw);
2954 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2959 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2961 E_Comp_Object *cw = data;
2963 if (_e_comp_object_shadow_setup(cw))
2966 cw->ec->changes.size = 1;
2968 if (cw->frame_object)
2970 _e_comp_object_shadow(cw);
2971 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2972 _e_comp_object_frame_recalc(cw);
2973 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2978 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2980 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2984 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2986 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2990 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2992 E_Comp_Object *cw = data;
2994 if (!cw->ec) return; //NYI
2995 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2999 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3001 E_Comp_Object *cw = data;
3003 if (!cw->ec) return; //NYI
3004 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3008 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3010 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3014 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3016 E_Comp_Object *cw = data;
3018 if (!e_object_is_del(E_OBJECT(cw->ec)))
3019 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3023 _e_comp_input_obj_smart_add(Evas_Object *obj)
3025 E_Input_Rect_Smart_Data *input_rect_sd;
3026 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3028 if (!input_rect_sd) return;
3029 evas_object_smart_data_set(obj, input_rect_sd);
3033 _e_comp_input_obj_smart_del(Evas_Object *obj)
3035 E_Input_Rect_Smart_Data *input_rect_sd;
3036 E_Input_Rect_Data *input_rect_data;
3038 input_rect_sd = evas_object_smart_data_get(obj);
3039 if (!input_rect_sd) return;
3041 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3043 if (input_rect_data->obj)
3045 evas_object_smart_member_del(input_rect_data->obj);
3046 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3048 E_FREE(input_rect_data);
3050 E_FREE(input_rect_sd);
3054 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3056 E_Input_Rect_Smart_Data *input_rect_sd;
3057 E_Input_Rect_Data *input_rect_data;
3061 input_rect_sd = evas_object_smart_data_get(obj);
3062 if (!input_rect_sd) return;
3064 cw = input_rect_sd->cw;
3065 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3067 if (input_rect_data->obj)
3069 evas_object_geometry_set(input_rect_data->obj,
3070 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3071 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3072 input_rect_data->rect.w, input_rect_data->rect.h);
3078 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3080 E_Input_Rect_Smart_Data *input_rect_sd;
3081 E_Input_Rect_Data *input_rect_data;
3085 input_rect_sd = evas_object_smart_data_get(obj);
3086 if (!input_rect_sd) return;
3088 cw = input_rect_sd->cw;
3089 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3091 if (input_rect_data->obj)
3093 evas_object_geometry_set(input_rect_data->obj,
3094 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3095 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3096 input_rect_data->rect.w, input_rect_data->rect.h);
3102 _e_comp_input_obj_smart_show(Evas_Object *obj)
3104 E_Input_Rect_Smart_Data *input_rect_sd;
3105 E_Input_Rect_Data *input_rect_data;
3108 input_rect_sd = evas_object_smart_data_get(obj);
3109 if (!input_rect_sd) return;
3111 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3113 if (input_rect_data->obj)
3115 evas_object_show(input_rect_data->obj);
3121 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3123 E_Input_Rect_Smart_Data *input_rect_sd;
3124 E_Input_Rect_Data *input_rect_data;
3127 input_rect_sd = evas_object_smart_data_get(obj);
3128 if (!input_rect_sd) return;
3130 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3132 if (input_rect_data->obj)
3134 evas_object_hide(input_rect_data->obj);
3140 _e_comp_input_obj_smart_init(void)
3142 if (_e_comp_input_obj_smart) return;
3144 static const Evas_Smart_Class sc =
3146 INPUT_OBJ_SMART_NAME,
3147 EVAS_SMART_CLASS_VERSION,
3148 _e_comp_input_obj_smart_add,
3149 _e_comp_input_obj_smart_del,
3150 _e_comp_input_obj_smart_move,
3151 _e_comp_input_obj_smart_resize,
3152 _e_comp_input_obj_smart_show,
3153 _e_comp_input_obj_smart_hide,
3166 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3172 _e_comp_smart_add(Evas_Object *obj)
3176 cw = E_NEW(E_Comp_Object, 1);
3177 EINA_SAFETY_ON_NULL_RETURN(cw);
3179 wl_signal_init(&cw->events.lower);
3180 #ifdef REFACTOR_DESK_AREA
3181 wl_signal_init(&cw->events.lower_done);
3182 wl_signal_init(&cw->events.raise);
3184 wl_signal_init(&cw->events.show);
3185 wl_signal_init(&cw->events.hide);
3186 #ifdef REFACTOR_DESK_AREA
3187 wl_signal_init(&cw->events.set_layer);
3188 wl_signal_init(&cw->events.stack_above);
3189 wl_signal_init(&cw->events.stack_below);
3192 cw->smart_obj = obj;
3193 cw->x = cw->y = cw->w = cw->h = -1;
3194 evas_object_smart_data_set(obj, cw);
3195 cw->opacity = 255.0;
3196 cw->external_content = 0;
3197 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3198 cw->transform_bg_color.r = 0;
3199 cw->transform_bg_color.g = 0;
3200 cw->transform_bg_color.b = 0;
3201 cw->transform_bg_color.a = 255;
3202 evas_object_data_set(obj, "comp_obj", cw);
3203 evas_object_move(obj, -1, -1);
3204 /* intercept ALL the callbacks! */
3205 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3206 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3207 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3208 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3209 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3210 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3211 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3212 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3213 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3214 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3215 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3217 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3218 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3219 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3220 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3222 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3223 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3225 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3226 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3228 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3230 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3231 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3235 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3238 evas_object_color_set(cw->clip, r, g, b, a);
3239 evas_object_smart_callback_call(obj, "color_set", NULL);
3244 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3247 evas_object_clip_set(cw->clip, clip);
3251 _e_comp_smart_clip_unset(Evas_Object *obj)
3254 evas_object_clip_unset(cw->clip);
3258 _e_comp_smart_hide(Evas_Object *obj)
3260 TRACE_DS_BEGIN(COMP:SMART HIDE);
3265 evas_object_hide(cw->clip);
3266 if (cw->input_obj) evas_object_hide(cw->input_obj);
3267 evas_object_hide(cw->effect_obj);
3268 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3269 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3270 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3277 /* unset native surface if current displaying buffer was destroied */
3278 if (!cw->buffer_destroy_listener.notify)
3280 Evas_Native_Surface *ns;
3281 ns = evas_object_image_native_surface_get(cw->obj);
3282 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3283 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3286 if (!cw->ec->input_only)
3288 edje_object_freeze(cw->effect_obj);
3289 edje_object_freeze(cw->shobj);
3290 edje_object_play_set(cw->shobj, 0);
3291 if (cw->frame_object)
3292 edje_object_play_set(cw->frame_object, 0);
3295 e_comp_render_queue(); //force nocomp recheck
3301 _e_comp_smart_show(Evas_Object *obj)
3309 if ((cw->w < 0) || (cw->h < 0))
3310 CRI("ACK! ec:%p", cw->ec);
3312 TRACE_DS_BEGIN(COMP:SMART SHOW);
3314 e_comp_object_map_update(obj);
3316 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3317 evas_object_show(tmp->frame);
3319 evas_object_show(cw->clip);
3320 if (cw->input_obj) evas_object_show(cw->input_obj);
3321 if (!cw->ec->input_only)
3323 edje_object_thaw(cw->effect_obj);
3324 edje_object_thaw(cw->shobj);
3325 edje_object_play_set(cw->shobj, 1);
3326 if (cw->frame_object)
3327 edje_object_play_set(cw->frame_object, 1);
3329 evas_object_show(cw->effect_obj);
3330 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3331 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3332 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3333 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3334 e_comp_render_queue();
3335 if (cw->ec->input_only)
3340 if (cw->ec->iconic && (!cw->ec->new_client))
3342 if (e_client_is_iconified_by_client(cw->ec))
3344 ELOGF("COMP", "Set launching flag..", cw->ec);
3345 cw->ec->launching = EINA_TRUE;
3348 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3350 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3353 ELOGF("COMP", "Set launching flag..", cw->ec);
3354 cw->ec->launching = EINA_TRUE;
3356 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3357 _e_comp_object_animating_begin(cw);
3358 if (!_e_comp_object_effect_visibility_start(cw, 1))
3364 /* ensure some random effect doesn't lock the client offscreen */
3368 e_comp_object_effect_set(obj, NULL);
3371 _e_comp_object_dim_update(cw);
3377 _e_comp_smart_del(Evas_Object *obj)
3383 if (cw->buffer_destroy_listener.notify)
3385 wl_list_remove(&cw->buffer_destroy_listener.link);
3386 cw->buffer_destroy_listener.notify = NULL;
3389 if (cw->tbm_surface)
3391 tbm_surface_internal_unref(cw->tbm_surface);
3392 cw->tbm_surface = NULL;
3395 if (cw->render_update_lock.buffer_ref.buffer)
3397 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3398 cw->ec, cw->render_update_lock.lock);
3399 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3402 e_comp_object_render_update_del(cw->smart_obj);
3403 E_FREE_FUNC(cw->updates, eina_tiler_free);
3404 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3411 EINA_LIST_FREE(cw->obj_mirror, o)
3413 evas_object_image_data_set(o, NULL);
3414 evas_object_freeze_events_set(o, 1);
3415 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3419 #ifdef REFACTOR_DESK_AREA
3421 _e_comp_object_layers_remove(cw);
3423 l = evas_object_data_get(obj, "comp_object-to_del");
3424 E_FREE_LIST(l, evas_object_del);
3425 _e_comp_object_mouse_event_callback_unset(cw);
3426 evas_object_del(cw->clip);
3427 evas_object_del(cw->obj);
3428 evas_object_del(cw->shobj);
3429 evas_object_del(cw->effect_obj);
3430 evas_object_del(cw->frame_object);
3431 evas_object_del(cw->input_obj);
3432 evas_object_del(cw->mask.obj);
3433 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3434 evas_object_del(cw->transform_bg_obj);
3435 evas_object_del(cw->transform_tranp_obj);
3436 evas_object_del(cw->default_input_obj);
3437 eina_stringshare_del(cw->frame_theme);
3438 eina_stringshare_del(cw->frame_name);
3442 e_comp->animating--;
3444 e_object_unref(E_OBJECT(cw->ec));
3446 cw->ec->frame = NULL;
3451 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3455 cw->x = x, cw->y = y;
3456 evas_object_move(cw->effect_obj, x, y);
3457 evas_object_move(cw->default_input_obj, x, y);
3458 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3460 e_comp_object_map_update(obj);
3464 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3466 Eina_Bool first = EINA_FALSE;
3471 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3473 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3475 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3477 if (cw->w != w || cw->h != h)
3478 e_comp_object_map_update(obj);
3480 first = ((cw->w < 1) || (cw->h < 1));
3481 cw->w = w, cw->h = h;
3485 if (cw->frame_object)
3486 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3489 /* verify pixmap:object size */
3490 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3492 if ((ww != pw) || (hh != ph))
3493 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3495 evas_object_resize(cw->effect_obj, tw, th);
3496 evas_object_resize(cw->default_input_obj, w, h);
3498 evas_object_resize(cw->input_obj, w, h);
3500 evas_object_resize(cw->mask.obj, w, h);
3501 /* resize render update tiler */
3504 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3505 cw->updates_full = 0;
3506 if (cw->updates) eina_tiler_clear(cw->updates);
3510 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3511 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3519 e_comp_render_queue();
3525 _e_comp_smart_init(void)
3527 if (_e_comp_smart) return;
3529 static const Evas_Smart_Class sc =
3532 EVAS_SMART_CLASS_VERSION,
3536 _e_comp_smart_resize,
3539 _e_comp_smart_color_set,
3540 _e_comp_smart_clip_set,
3541 _e_comp_smart_clip_unset,
3551 _e_comp_smart = evas_smart_class_new(&sc);
3556 e_comp_object_init(void)
3558 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3559 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3560 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3561 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3565 e_comp_object_shutdown(void)
3571 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3573 API_ENTRY EINA_FALSE;
3574 return !!cw->force_visible;
3576 /////////////////////////////////////////////////////////
3579 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3582 Eina_Bool comp_object;
3584 comp_object = !!evas_object_data_get(obj, "comp_object");
3589 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3591 e_comp_render_queue();
3593 l = evas_object_data_get(obj, "comp_object-to_del");
3594 E_FREE_LIST(l, evas_object_del);
3598 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3600 if (e_comp_util_object_is_above_nocomp(obj) &&
3601 (!evas_object_data_get(obj, "comp_override")))
3603 evas_object_data_set(obj, "comp_override", (void*)1);
3604 e_comp_override_add();
3609 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3611 Eina_Bool ref = EINA_TRUE;
3612 if (evas_object_visible_get(obj))
3616 d = evas_object_data_del(obj, "comp_hiding");
3618 /* currently trying to hide */
3621 /* already visible */
3625 evas_object_show(obj);
3628 evas_object_ref(obj);
3629 evas_object_data_set(obj, "comp_ref", (void*)1);
3631 edje_object_signal_emit(obj, "e,state,visible", "e");
3632 evas_object_data_set(obj, "comp_showing", (void*)1);
3633 if (e_comp_util_object_is_above_nocomp(obj))
3635 evas_object_data_set(obj, "comp_override", (void*)1);
3636 e_comp_override_add();
3641 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3643 if (!evas_object_visible_get(obj)) return;
3644 /* already hiding */
3645 if (evas_object_data_get(obj, "comp_hiding")) return;
3646 if (!evas_object_data_del(obj, "comp_showing"))
3648 evas_object_ref(obj);
3649 evas_object_data_set(obj, "comp_ref", (void*)1);
3651 edje_object_signal_emit(obj, "e,state,hidden", "e");
3652 evas_object_data_set(obj, "comp_hiding", (void*)1);
3654 if (evas_object_data_del(obj, "comp_override"))
3655 e_comp_override_timed_pop();
3659 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3661 if (!e_util_strcmp(emission, "e,action,hide,done"))
3663 if (!evas_object_data_del(obj, "comp_hiding")) return;
3664 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3665 evas_object_hide(obj);
3666 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3669 evas_object_data_del(obj, "comp_showing");
3670 if (evas_object_data_del(obj, "comp_ref"))
3671 evas_object_unref(obj);
3675 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3681 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3685 E_API E_Comp_Object_Hook *
3686 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3688 E_Comp_Object_Hook *ch;
3690 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3691 ch = E_NEW(E_Comp_Object_Hook, 1);
3692 if (!ch) return NULL;
3693 ch->hookpoint = hookpoint;
3695 ch->data = (void*)data;
3696 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3701 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3704 if (_e_comp_object_hooks_walking == 0)
3706 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3710 _e_comp_object_hooks_delete++;
3713 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3714 E_API E_Comp_Object_Intercept_Hook *
3715 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3717 E_Comp_Object_Intercept_Hook *ch;
3719 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3720 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3721 if (!ch) return NULL;
3722 ch->hookpoint = hookpoint;
3724 ch->data = (void*)data;
3725 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3730 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3733 if (_e_comp_object_intercept_hooks_walking == 0)
3735 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3739 _e_comp_object_intercept_hooks_delete++;
3744 e_comp_object_util_add(Evas_Object *obj)
3748 E_Comp_Config *conf = e_comp_config_get();
3749 Eina_Bool skip = EINA_FALSE;
3755 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3757 name = evas_object_name_get(obj);
3758 vis = evas_object_visible_get(obj);
3759 o = edje_object_add(e_comp->evas);
3760 evas_object_data_set(o, "comp_object", (void*)1);
3762 skip = (!strncmp(name, "noshadow", 8));
3764 evas_object_data_set(o, "comp_object_skip", (void*)1);
3766 if (conf->shadow_style)
3768 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3769 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3772 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3773 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3774 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3776 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3778 evas_object_geometry_get(obj, &x, &y, &w, &h);
3779 evas_object_geometry_set(o, x, y, w, h);
3780 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3782 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3784 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3785 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3787 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3788 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3789 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3791 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3793 edje_object_part_swallow(o, "e.swallow.content", obj);
3795 _e_comp_object_event_add(o);
3798 evas_object_show(o);
3803 /* utility functions for deleting objects when their "owner" is deleted */
3805 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3810 EINA_SAFETY_ON_NULL_RETURN(to_del);
3811 l = evas_object_data_get(obj, "comp_object-to_del");
3812 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3813 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3814 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3818 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3823 EINA_SAFETY_ON_NULL_RETURN(to_del);
3824 l = evas_object_data_get(obj, "comp_object-to_del");
3826 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3829 /////////////////////////////////////////////////////////
3831 EINTERN Evas_Object *
3832 e_comp_object_client_add(E_Client *ec)
3837 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3838 if (ec->frame) return NULL;
3839 _e_comp_smart_init();
3840 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3841 cw = evas_object_smart_data_get(o);
3842 if (!cw) return NULL;
3843 evas_object_data_set(o, "E_Client", ec);
3846 evas_object_data_set(o, "comp_object", (void*)1);
3848 _e_comp_object_event_add(o);
3853 /* utility functions for getting client inset */
3855 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3858 if (!cw->client_inset.calc)
3864 if (ax) *ax = x - cw->client_inset.l;
3865 if (ay) *ay = y - cw->client_inset.t;
3869 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3872 if (!cw->client_inset.calc)
3878 if (ax) *ax = x + cw->client_inset.l;
3879 if (ay) *ay = y + cw->client_inset.t;
3883 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3886 if (!cw->client_inset.calc)
3892 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3893 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3897 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3900 if (!cw->client_inset.calc)
3906 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3907 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3911 e_comp_object_client_get(Evas_Object *obj)
3916 /* FIXME: remove this when eo is used */
3917 o = evas_object_data_get(obj, "comp_smart_obj");
3919 return e_comp_object_client_get(o);
3920 return cw ? cw->ec : NULL;
3924 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3927 if (cw->frame_extends)
3928 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3933 if (w) *w = cw->ec->w;
3934 if (h) *h = cw->ec->h;
3939 e_comp_object_util_zone_get(Evas_Object *obj)
3941 E_Zone *zone = NULL;
3945 zone = e_comp_zone_find_by_ec(cw->ec);
3950 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3951 zone = e_comp_zone_xy_get(x, y);
3957 e_comp_object_util_center(Evas_Object *obj)
3959 int x, y, w, h, ow, oh;
3964 zone = e_comp_object_util_zone_get(obj);
3965 EINA_SAFETY_ON_NULL_RETURN(zone);
3966 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3967 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3968 ow = cw->ec->w, oh = cw->ec->h;
3970 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3971 x = x + (w - ow) / 2;
3972 y = y + (h - oh) / 2;
3973 evas_object_move(obj, x, y);
3977 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3979 int x, y, w, h, ow, oh;
3982 EINA_SAFETY_ON_NULL_RETURN(on);
3983 evas_object_geometry_get(on, &x, &y, &w, &h);
3984 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3985 ow = cw->ec->w, oh = cw->ec->h;
3987 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3988 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3992 e_comp_object_util_fullscreen(Evas_Object *obj)
3997 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4000 evas_object_move(obj, 0, 0);
4001 evas_object_resize(obj, e_comp->w, e_comp->h);
4006 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4014 ow = cw->w, oh = cw->h;
4016 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4017 zone = e_comp_object_util_zone_get(obj);
4018 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4019 if (x) *x = zx + (zw - ow) / 2;
4020 if (y) *y = zy + (zh - oh) / 2;
4024 e_comp_object_input_objs_del(Evas_Object *obj)
4027 E_Input_Rect_Data *input_rect_data;
4028 E_Input_Rect_Smart_Data *input_rect_sd;
4033 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4034 if (!input_rect_sd) return;
4036 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4038 if (input_rect_data->obj)
4040 evas_object_smart_member_del(input_rect_data->obj);
4041 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4043 E_FREE(input_rect_data);
4048 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4051 E_Input_Rect_Data *input_rect_data = NULL;
4052 E_Input_Rect_Smart_Data *input_rect_sd;
4053 int client_w, client_h;
4055 if (cw->ec->client.w)
4056 client_w = cw->ec->client.w;
4058 client_w = cw->ec->w;
4060 if (cw->ec->client.h)
4061 client_h = cw->ec->client.h;
4063 client_h = cw->ec->h;
4065 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4069 _e_comp_input_obj_smart_init();
4070 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4071 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4072 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4075 input_rect_sd->cw = cw;
4078 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4081 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4082 if (input_rect_data)
4084 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4085 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4089 if ((input_rect_data) &&
4090 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4092 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4093 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4094 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4095 evas_object_clip_set(input_rect_data->obj, cw->clip);
4096 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4097 evas_object_geometry_set(input_rect_data->obj,
4098 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4099 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4100 evas_object_pass_events_set(cw->default_input_obj, 1);
4101 evas_object_pass_events_set(cw->obj, 1);
4104 evas_object_show(input_rect_data->obj);
4105 evas_object_show(cw->input_obj);
4110 evas_object_smart_member_del(cw->input_obj);
4111 E_FREE_FUNC(cw->input_obj, evas_object_del);
4112 evas_object_pass_events_set(cw->default_input_obj, 0);
4113 evas_object_pass_events_set(cw->obj, 0);
4118 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4121 E_Input_Rect_Smart_Data *input_rect_sd;
4122 E_Input_Rect_Data *input_rect_data;
4125 if (!cw->input_obj) return;
4127 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4130 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4132 *list = eina_list_append(*list, &input_rect_data->rect);
4138 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4141 if (l) *l = cw->client_inset.l;
4142 if (r) *r = cw->client_inset.r;
4143 if (t) *t = cw->client_inset.t;
4144 if (b) *b = cw->client_inset.b;
4147 /* set geometry for CSD */
4149 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4155 if (cw->frame_object)
4156 CRI("ACK! ec:%p", cw->ec);
4157 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4158 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4159 calc = cw->client_inset.calc;
4160 cw->client_inset.calc = l || r || t || b;
4161 eina_stringshare_replace(&cw->frame_theme, "borderless");
4162 if (cw->client_inset.calc)
4164 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4165 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4166 e_client_size_set(cw->ec, tw, th);
4168 else if (cw->ec->maximized || cw->ec->fullscreen)
4170 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4171 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4173 if (!cw->ec->new_client)
4175 if (calc && cw->client_inset.calc)
4177 tx = cw->ec->x - (l - cw->client_inset.l);
4178 ty = cw->ec->y - (t - cw->client_inset.t);
4179 e_client_pos_set(cw->ec, tx, ty);
4181 cw->ec->changes.pos = cw->ec->changes.size = 1;
4184 cw->client_inset.l = l;
4185 cw->client_inset.r = r;
4186 cw->client_inset.t = t;
4187 cw->client_inset.b = b;
4191 e_comp_object_frame_allowed(Evas_Object *obj)
4193 API_ENTRY EINA_FALSE;
4194 return (cw->frame_object || (!cw->client_inset.calc));
4198 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4200 API_ENTRY EINA_FALSE;
4201 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4202 eina_stringshare_replace(&cw->frame_name, name);
4203 if (cw->frame_object)
4204 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4209 e_comp_object_frame_exists(Evas_Object *obj)
4211 API_ENTRY EINA_FALSE;
4212 return !!cw->frame_object;
4216 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4218 Evas_Object *o, *pbg;
4221 Eina_Stringshare *theme;
4223 API_ENTRY EINA_FALSE;
4225 if (!e_util_strcmp(cw->frame_theme, name))
4226 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4227 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4228 return _e_comp_object_shadow_setup(cw);
4229 pbg = cw->frame_object;
4230 theme = eina_stringshare_add(name);
4232 if (cw->frame_object)
4236 w = cw->ec->w, h = cw->ec->h;
4237 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4238 if ((cw->ec->w != w) || (cw->ec->h != h))
4240 cw->ec->changes.size = 1;
4243 E_FREE_FUNC(cw->frame_object, evas_object_del);
4244 if (!name) goto reshadow;
4246 o = edje_object_add(e_comp->evas);
4247 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4248 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4249 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4251 cw->frame_object = NULL;
4253 eina_stringshare_del(cw->frame_theme);
4254 cw->frame_theme = theme;
4259 if (theme != e_config->theme_default_border_style)
4261 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4262 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4266 ok = e_theme_edje_object_set(o, "base/theme/border",
4267 "e/widgets/border/default/border");
4268 if (ok && (theme == e_config->theme_default_border_style))
4270 /* Reset default border style to default */
4271 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4272 e_config_save_queue();
4279 cw->frame_object = o;
4280 eina_stringshare_del(cw->frame_theme);
4281 cw->frame_theme = theme;
4282 evas_object_name_set(o, "cw->frame_object");
4285 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4289 cw->ec->changes.icon = 1;
4295 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4300 _e_comp_object_shadow_setup(cw);
4303 int old_x, old_y, new_x = 0, new_y = 0;
4305 old_x = cw->x, old_y = cw->y;
4307 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4309 new_x = cw->ec->x, new_y = cw->ec->y;
4310 else if (cw->ec->placed || (!cw->ec->new_client))
4312 /* if no previous frame:
4313 * - reapply client_inset
4318 if (cw->ec->changes.size)
4326 zone = e_comp_zone_find_by_ec(cw->ec);
4329 x = cw->ec->client.x, y = cw->ec->client.y;
4330 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4331 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4333 new_x = x, new_y = y;
4336 if (old_x != new_x || old_y != new_y)
4338 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4339 cw->y = cw->x = -99999;
4340 evas_object_move(obj, new_x, new_y);
4344 if (cw->ec->maximized)
4346 cw->ec->changes.need_maximize = 1;
4349 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4350 if (cw->frame_object)
4352 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4355 cw->frame_extends = 0;
4356 evas_object_del(pbg);
4361 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4363 E_Comp_Object_Mover *prov;
4366 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4367 edje_object_signal_emit(cw->shobj, sig, src);
4368 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4369 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4370 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4372 /* start with highest priority callback first */
4373 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4375 if (!e_util_glob_match(sig, prov->sig)) continue;
4376 if (prov->func(prov->data, obj, sig)) break;
4381 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4383 /* FIXME: at some point I guess this should use eo to inherit
4384 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4385 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4388 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4392 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4395 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4399 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4402 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4406 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4409 Eina_Rectangle rect;
4412 if (cw->ec->input_only || (!cw->updates)) return;
4413 if (cw->nocomp) return;
4414 rect.x = x, rect.y = y;
4415 rect.w = w, rect.h = h;
4416 evas_object_smart_callback_call(obj, "damage", &rect);
4418 if (e_comp_is_on_overlay(cw->ec))
4420 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4421 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4422 * E module attempts to block screen update due to the particular policy.
4424 if (e_pixmap_resource_get(cw->ec->pixmap))
4425 cw->hwc_need_update = EINA_TRUE;
4428 /* ignore overdraw */
4429 if (cw->updates_full)
4431 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4432 e_comp_object_render_update_add(obj);
4434 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4435 evas_object_show(cw->smart_obj);
4439 /* clip rect to client surface */
4440 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4441 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4442 /* if rect is the total size of the client after clip, clear the updates
4443 * since this is guaranteed to be the whole region anyway
4445 eina_tiler_area_size_get(cw->updates, &tw, &th);
4446 if ((w > tw) || (h > th))
4448 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4449 eina_tiler_clear(cw->updates);
4450 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4452 tw = cw->ec->client.w, th = cw->ec->client.h;
4454 if ((!x) && (!y) && (w == tw) && (h == th))
4456 eina_tiler_clear(cw->updates);
4457 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4458 cw->updates_full = 1;
4459 cw->update_count = 0;
4462 if (cw->update_count > UPDATE_MAX)
4464 /* this is going to get really dumb, so just update the whole thing */
4465 eina_tiler_clear(cw->updates);
4466 cw->update_count = cw->updates_full = 1;
4467 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4468 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4472 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4473 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4475 cw->updates_exist = 1;
4476 e_comp_object_render_update_add(obj);
4478 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4479 evas_object_show(cw->smart_obj);
4483 e_comp_object_damage_exists(Evas_Object *obj)
4485 API_ENTRY EINA_FALSE;
4486 return cw->updates_exist;
4490 e_comp_object_render_update_add(Evas_Object *obj)
4494 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4495 if (cw->render_update_lock.lock) return;
4496 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4500 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4502 e_comp_render_queue();
4506 e_comp_object_render_update_del(Evas_Object *obj)
4510 if (cw->ec->input_only || (!cw->updates)) return;
4511 if (!cw->update) return;
4513 /* this gets called during comp animating to clear the update flag */
4514 if (e_comp->grabbed) return;
4515 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4516 if (!e_comp->updates)
4518 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4519 if (e_comp->render_animator)
4520 ecore_animator_freeze(e_comp->render_animator);
4525 e_comp_object_shape_apply(Evas_Object *obj)
4529 unsigned int i, *pix, *p;
4533 if (!cw->ec) return; //NYI
4534 if (cw->external_content) return;
4537 if ((cw->ec->shape_rects_num >= 1) &&
4538 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4543 ERR("BUGGER: shape with native surface? cw=%p", cw);
4546 evas_object_image_size_get(cw->obj, &w, &h);
4547 if ((w < 1) || (h < 1)) return;
4550 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4551 _e_comp_object_alpha_set(cw);
4552 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4553 evas_object_image_alpha_set(o, 1);
4555 p = pix = evas_object_image_data_get(cw->obj, 1);
4558 evas_object_image_data_set(cw->obj, pix);
4563 unsigned char *spix, *sp;
4565 spix = calloc(w * h, sizeof(unsigned char));
4567 for (i = 0; i < cw->ec->shape_rects_num; i++)
4571 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4572 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4573 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4574 sp = spix + (w * ry) + rx;
4575 for (py = 0; py < rh; py++)
4577 for (px = 0; px < rw; px++)
4585 for (py = 0; py < h; py++)
4587 for (px = 0; px < w; px++)
4589 unsigned int mask, imask;
4591 mask = ((unsigned int)(*sp)) << 24;
4593 imask |= imask >> 8;
4594 imask |= imask >> 8;
4595 *p = mask | (*p & imask);
4596 //if (*sp) *p = 0xff000000 | *p;
4597 //else *p = 0x00000000;
4606 for (py = 0; py < h; py++)
4608 for (px = 0; px < w; px++)
4612 evas_object_image_data_set(cw->obj, pix);
4613 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4614 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4616 evas_object_image_data_set(o, pix);
4617 evas_object_image_data_update_add(o, 0, 0, w, h);
4619 // don't need to fix alpha chanel as blending
4620 // should be totally off here regardless of
4621 // alpha channel content
4625 _e_comp_object_clear(E_Comp_Object *cw)
4630 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4632 if (cw->render_update_lock.lock) return;
4635 e_pixmap_clear(cw->ec->pixmap);
4637 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4638 evas_object_image_size_set(cw->obj, 1, 1);
4639 evas_object_image_data_set(cw->obj, NULL);
4640 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4642 evas_object_image_size_set(o, 1, 1);
4643 evas_object_image_data_set(o, NULL);
4646 e_comp_object_render_update_del(cw->smart_obj);
4650 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4654 API_ENTRY EINA_FALSE;
4656 if (cw->transparent.set == set)
4661 evas_object_color_get(obj, &r, &g, &b, &a);
4662 evas_object_color_set(obj, 0, 0, 0, 0);
4664 cw->transparent.user_r = r;
4665 cw->transparent.user_g = g;
4666 cw->transparent.user_b = b;
4667 cw->transparent.user_a = a;
4669 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4671 cw->transparent.user_r,
4672 cw->transparent.user_g,
4673 cw->transparent.user_b,
4674 cw->transparent.user_a);
4676 cw->transparent.set = EINA_TRUE;
4680 cw->transparent.set = EINA_FALSE;
4682 evas_object_color_set(obj,
4683 cw->transparent.user_r,
4684 cw->transparent.user_g,
4685 cw->transparent.user_b,
4686 cw->transparent.user_a);
4688 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4690 cw->transparent.user_r,
4691 cw->transparent.user_g,
4692 cw->transparent.user_b,
4693 cw->transparent.user_a);
4699 /* helper function to simplify toggling of redirection for display servers which support it */
4701 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4706 if (cw->redirected == set) return;
4707 cw->redirected = set;
4708 if (cw->external_content) return;
4710 e_comp_object_map_update(obj);
4714 if (cw->updates_exist)
4715 e_comp_object_render_update_add(obj);
4717 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4719 _e_comp_object_transparent_set(obj, EINA_FALSE);
4720 evas_object_smart_callback_call(obj, "redirected", NULL);
4724 _e_comp_object_clear(cw);
4725 _e_comp_object_transparent_set(obj, EINA_TRUE);
4726 evas_object_smart_callback_call(obj, "unredirected", NULL);
4731 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4734 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4736 if (cw->buffer_destroy_listener.notify)
4738 cw->buffer_destroy_listener.notify = NULL;
4739 wl_list_remove(&cw->buffer_destroy_listener.link);
4742 if (e_object_is_del(E_OBJECT(cw->ec)))
4744 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4749 /* if it's current displaying buffer, do not remove its content */
4750 if (!evas_object_visible_get(cw->ec->frame))
4751 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4756 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4761 if (cw->buffer_destroy_listener.notify)
4763 wl_list_remove(&cw->buffer_destroy_listener.link);
4764 cw->buffer_destroy_listener.notify = NULL;
4767 if (cw->tbm_surface)
4769 tbm_surface_internal_unref(cw->tbm_surface);
4770 cw->tbm_surface = NULL;
4775 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4777 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4778 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4780 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4782 tbm_surface_internal_ref(ns->data.tbm.buffer);
4783 cw->tbm_surface = ns->data.tbm.buffer;
4787 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4788 evas_object_image_native_surface_set(cw->obj, ns);
4792 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4794 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4795 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4796 evas_object_image_native_surface_set(o, ns);
4803 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4805 Evas_Native_Surface ns;
4808 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4809 if (cw->ec->input_only) return;
4810 if (cw->external_content) return;
4811 if (cw->render_update_lock.lock) return;
4814 memset(&ns, 0, sizeof(Evas_Native_Surface));
4818 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4819 set = (!cw->ec->shaped);
4821 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4825 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4829 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4832 if (cw->ec->input_only) return;
4835 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4836 _e_comp_object_alpha_set(cw);
4838 e_comp_object_native_surface_set(obj, cw->native);
4839 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4843 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4849 if (cw->blanked == set) return;
4851 _e_comp_object_alpha_set(cw);
4854 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4855 evas_object_image_data_set(cw->obj, NULL);
4859 e_comp_object_native_surface_set(obj, 1);
4860 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4864 _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)
4869 if (!_damage_trace) return;
4873 if (!evas_object_visible_get(cw->obj)) return;
4875 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4877 o = evas_object_rectangle_add(e_comp->evas);
4878 evas_object_layer_set(o, E_LAYER_MAX);
4879 evas_object_name_set(o, "damage_trace");
4880 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4881 evas_object_resize(o, dmg_w, dmg_h);
4882 evas_object_color_set(o, 0, 128, 0, 128);
4883 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4884 evas_object_pass_events_set(o, EINA_TRUE);
4885 evas_object_show(o);
4887 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4889 dmg_w, dmg_h, dmg_x, dmg_y,
4890 origin->w, origin->h, origin->x, origin->y);
4892 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4895 /* mark an object as dirty and setup damages */
4897 e_comp_object_dirty(Evas_Object *obj)
4900 Eina_Rectangle *rect;
4904 Eina_Bool dirty, visible;
4908 if (cw->external_content) return;
4909 if (!cw->redirected) return;
4910 if (cw->render_update_lock.lock)
4912 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4915 /* only actually dirty if pixmap is available */
4916 if (!e_pixmap_resource_get(cw->ec->pixmap))
4918 // e_pixmap_size_get returns last attached buffer size
4919 // eventhough it is destroyed
4920 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4923 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4924 visible = cw->visible;
4925 if (!dirty) w = h = 1;
4926 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4928 evas_object_image_data_set(cw->obj, NULL);
4929 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4930 evas_object_image_size_set(cw->obj, tw, th);
4931 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4932 if (cw->pending_updates)
4933 eina_tiler_area_size_set(cw->pending_updates, w, h);
4934 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4936 evas_object_image_pixels_dirty_set(o, dirty);
4938 evas_object_image_data_set(o, NULL);
4939 evas_object_image_size_set(o, tw, th);
4940 visible |= evas_object_visible_get(o);
4944 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4948 e_comp_object_native_surface_set(obj, 1);
4950 m = _e_comp_object_map_damage_transform_get(cw->ec);
4951 it = eina_tiler_iterator_new(cw->updates);
4952 EINA_ITERATOR_FOREACH(it, rect)
4954 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4955 * of evas engine and doesn't convert damage according to evas_map.
4956 * so damage of evas_object_image use surface coordinate.
4960 int damage_x, damage_y, damage_w, damage_h;
4962 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4963 &damage_x, &damage_y, &damage_w, &damage_h);
4964 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4965 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4969 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4970 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4973 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4974 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4975 if (cw->pending_updates)
4976 eina_tiler_rect_add(cw->pending_updates, rect);
4978 eina_iterator_free(it);
4979 if (m) e_map_free(m);
4980 if (cw->pending_updates)
4981 eina_tiler_clear(cw->updates);
4984 cw->pending_updates = cw->updates;
4985 cw->updates = eina_tiler_new(w, h);
4986 eina_tiler_tile_size_set(cw->updates, 1, 1);
4988 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4989 evas_object_smart_callback_call(obj, "dirty", NULL);
4990 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4991 /* force render if main object is hidden but mirrors are visible */
4992 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4993 e_comp_object_render(obj);
4997 e_comp_object_render(Evas_Object *obj)
5004 API_ENTRY EINA_FALSE;
5006 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5007 if (cw->ec->input_only) return EINA_TRUE;
5008 if (cw->external_content) return EINA_TRUE;
5009 if (cw->native) return EINA_FALSE;
5010 /* if comp object is not redirected state, comp object should not be set by newly committed data
5011 because image size of comp object is 1x1 and it should not be shown on canvas */
5012 if (!cw->redirected) return EINA_TRUE;
5013 if (cw->render_update_lock.lock)
5015 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5018 e_comp_object_render_update_del(obj);
5019 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5021 if (!cw->pending_updates)
5023 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5024 evas_object_image_data_set(cw->obj, NULL);
5025 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5026 evas_object_image_data_set(o, NULL);
5030 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5032 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5034 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5037 e_pixmap_image_refresh(cw->ec->pixmap);
5038 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5041 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5042 e_pixmap_image_data_ref(cw->ec->pixmap);
5044 /* set pixel data */
5045 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5046 _e_comp_object_alpha_set(cw);
5047 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5049 evas_object_image_data_set(o, pix);
5050 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5051 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5054 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5056 e_comp_client_post_update_add(cw->ec);
5061 /* create a duplicate of an evas object */
5063 e_comp_object_util_mirror_add(Evas_Object *obj)
5067 unsigned int *pix = NULL;
5068 Eina_Bool argb = EINA_FALSE;
5073 cw = evas_object_data_get(obj, "comp_mirror");
5076 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5077 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5078 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5079 evas_object_image_alpha_set(o, 1);
5080 evas_object_image_source_set(o, obj);
5083 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5084 if (cw->external_content)
5086 ERR("%p of client %p is external content.", obj, cw->ec);
5089 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5090 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5091 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5092 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5093 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5094 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5095 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5096 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5097 evas_object_data_set(o, "comp_mirror", cw);
5099 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5100 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5102 evas_object_image_size_set(o, tw, th);
5105 pix = evas_object_image_data_get(cw->obj, 0);
5111 evas_object_image_native_surface_set(o, cw->ns);
5114 Evas_Native_Surface ns;
5115 memset(&ns, 0, sizeof(Evas_Native_Surface));
5116 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5117 evas_object_image_native_surface_set(o, &ns);
5122 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5123 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5125 (e_pixmap_image_exists(cw->ec->pixmap)))
5126 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5128 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5135 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5136 evas_object_image_pixels_dirty_set(o, dirty);
5137 evas_object_image_data_set(o, pix);
5138 evas_object_image_data_set(cw->obj, pix);
5140 evas_object_image_data_update_add(o, 0, 0, tw, th);
5145 //////////////////////////////////////////////////////
5148 e_comp_object_effect_allowed_get(Evas_Object *obj)
5150 API_ENTRY EINA_FALSE;
5152 if (!cw->shobj) return EINA_FALSE;
5153 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5154 return !e_comp_config_get()->match.disable_borders;
5157 /* setup an api effect for a client */
5159 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5162 Eina_Stringshare *grp;
5163 E_Comp_Config *config;
5164 Eina_Bool loaded = EINA_FALSE;
5166 API_ENTRY EINA_FALSE;
5167 if (!cw->shobj) return EINA_FALSE; //input window
5169 if (!effect) effect = "none";
5170 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5172 config = e_comp_config_get();
5173 if ((config) && (config->effect_file))
5175 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5177 cw->effect_set = EINA_TRUE;
5184 edje_object_file_get(cw->effect_obj, NULL, &grp);
5185 cw->effect_set = !eina_streq(effect, "none");
5186 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5187 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5189 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5190 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5191 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5193 if (cw->effect_running)
5195 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5198 cw->effect_set = EINA_FALSE;
5199 return cw->effect_set;
5203 if (cw->effect_running)
5205 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5208 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5209 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5210 if (cw->effect_clip)
5212 evas_object_clip_unset(cw->clip);
5213 cw->effect_clip = 0;
5215 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5217 _e_comp_object_dim_update(cw);
5219 return cw->effect_set;
5222 /* set params for embryo scripts in effect */
5224 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5226 Edje_Message_Int_Set *msg;
5230 EINA_SAFETY_ON_NULL_RETURN(params);
5231 EINA_SAFETY_ON_FALSE_RETURN(count);
5232 if (!cw->effect_set) return;
5234 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5235 msg->count = (int)count;
5236 for (x = 0; x < count; x++)
5237 msg->val[x] = params[x];
5238 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5239 edje_object_message_signal_process(cw->effect_obj);
5243 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5245 Edje_Signal_Cb end_cb;
5247 E_Comp_Object *cw = data;
5249 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5250 cw->effect_running = 0;
5251 if (!_e_comp_object_animating_end(cw)) return;
5253 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5255 evas_object_data_del(cw->smart_obj, "effect_running");
5256 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5257 e_comp_visibility_calculation_set(EINA_TRUE);
5260 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5261 if (!end_cb) return;
5262 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5263 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5264 end_cb(end_data, cw->smart_obj, emission, source);
5267 /* clip effect to client's zone */
5269 e_comp_object_effect_clip(Evas_Object *obj)
5273 zone = e_comp_zone_find_by_ec(cw->ec);
5275 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5276 if (!cw->effect_clip_able) return;
5277 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5278 cw->effect_clip = 1;
5281 /* unclip effect from client's zone */
5283 e_comp_object_effect_unclip(Evas_Object *obj)
5286 if (!cw->effect_clip) return;
5287 evas_object_clip_unset(cw->smart_obj);
5288 cw->effect_clip = 0;
5291 /* start effect, running end_cb after */
5293 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5295 API_ENTRY EINA_FALSE;
5296 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5297 if (!cw->effect_set) return EINA_FALSE;
5299 if (cw->effect_running)
5301 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5304 e_comp_object_effect_clip(obj);
5305 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5307 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5308 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5309 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5310 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5312 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5313 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5315 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5316 _e_comp_object_animating_begin(cw);
5317 cw->effect_running = 1;
5321 /* stop a currently-running effect immediately */
5323 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5326 Edje_Signal_Cb end_cb_before = NULL;
5327 void *end_data_before = NULL;
5328 API_ENTRY EINA_FALSE;
5330 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5331 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5333 if (end_cb_before != end_cb) return EINA_TRUE;
5334 e_comp_object_effect_unclip(obj);
5335 if (cw->effect_clip)
5337 evas_object_clip_unset(cw->effect_obj);
5338 cw->effect_clip = 0;
5340 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5341 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5343 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5345 evas_object_data_del(cw->smart_obj, "effect_running");
5346 e_comp_visibility_calculation_set(EINA_TRUE);
5349 cw->effect_running = 0;
5350 ret = _e_comp_object_animating_end(cw);
5352 if ((ret) && (end_cb_before))
5354 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5355 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5362 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5364 return a->pri - b->pri;
5367 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5368 E_API E_Comp_Object_Mover *
5369 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5371 E_Comp_Object_Mover *prov;
5373 prov = E_NEW(E_Comp_Object_Mover, 1);
5374 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5375 prov->func = provider;
5376 prov->data = (void*)data;
5379 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5380 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5385 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5387 EINA_SAFETY_ON_NULL_RETURN(prov);
5388 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5393 e_comp_object_effect_object_get(Evas_Object *obj)
5397 return cw->effect_obj;
5401 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5403 API_ENTRY EINA_FALSE;
5404 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5405 if (!cw->effect_set) return EINA_FALSE;
5412 ////////////////////////////////////
5415 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5417 if (e_comp->autoclose.obj)
5419 e_comp_ungrab_input(0, 1);
5420 if (e_comp->autoclose.del_cb)
5421 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5422 else if (!already_del)
5424 evas_object_hide(e_comp->autoclose.obj);
5425 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5427 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5429 e_comp->autoclose.obj = NULL;
5430 e_comp->autoclose.data = NULL;
5431 e_comp->autoclose.del_cb = NULL;
5432 e_comp->autoclose.key_cb = NULL;
5433 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5437 _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)
5439 _e_comp_object_autoclose_cleanup(0);
5443 _e_comp_object_autoclose_setup(Evas_Object *obj)
5445 if (!e_comp->autoclose.rect)
5447 /* create rect just below autoclose object to catch mouse events */
5448 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5449 evas_object_move(e_comp->autoclose.rect, 0, 0);
5450 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5451 evas_object_show(e_comp->autoclose.rect);
5452 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5453 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5454 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5455 e_comp_grab_input(0, 1);
5457 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5458 evas_object_focus_set(obj, 1);
5462 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5464 _e_comp_object_autoclose_setup(obj);
5465 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5469 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5471 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5472 _e_comp_object_autoclose_cleanup(1);
5473 if (e_client_focused_get()) return;
5475 E_Zone *zone = e_zone_current_get();
5478 e_zone_focus_reset(zone);
5482 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5486 if (e_comp->autoclose.obj)
5488 if (e_comp->autoclose.obj == obj) return;
5489 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5490 e_comp->autoclose.obj = obj;
5491 e_comp->autoclose.del_cb = del_cb;
5492 e_comp->autoclose.key_cb = cb;
5493 e_comp->autoclose.data = (void*)data;
5494 if (evas_object_visible_get(obj))
5495 _e_comp_object_autoclose_setup(obj);
5497 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5498 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5501 e_comp->autoclose.obj = obj;
5502 e_comp->autoclose.del_cb = del_cb;
5503 e_comp->autoclose.key_cb = cb;
5504 e_comp->autoclose.data = (void*)data;
5505 if (evas_object_visible_get(obj))
5506 _e_comp_object_autoclose_setup(obj);
5508 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5509 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5513 e_comp_object_is_animating(Evas_Object *obj)
5517 return cw->animating;
5521 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5525 if ((cw->external_content) &&
5526 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5528 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5529 "But current external content is %d object for %p.",
5530 cw->content_type, cw->ec);
5534 cw->user_alpha_set = EINA_TRUE;
5535 cw->user_alpha = alpha;
5537 if (!cw->obj) return;
5539 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5541 evas_object_image_alpha_set(cw->obj, alpha);
5543 if ((!cw->native) && (!cw->external_content))
5544 evas_object_image_data_set(cw->obj, NULL);
5548 e_comp_object_alpha_get(Evas_Object *obj)
5550 API_ENTRY EINA_FALSE;
5552 return evas_object_image_alpha_get(cw->obj);
5556 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5558 Eina_Bool mask_set = EINA_FALSE;
5562 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5563 if (cw->ec->input_only) return;
5570 o = evas_object_rectangle_add(e_comp->evas);
5571 evas_object_color_set(o, 0, 0, 0, 0);
5572 evas_object_clip_set(o, cw->clip);
5573 evas_object_smart_member_add(o, obj);
5574 evas_object_move(o, 0, 0);
5575 evas_object_resize(o, cw->w, cw->h);
5576 /* save render op value to restore when clear a mask.
5578 * NOTE: DO NOT change the render op on ec->frame while mask object
5579 * is set. it will overwrite the changed op value. */
5580 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5581 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5582 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5583 if (cw->visible) evas_object_show(o);
5586 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5587 ELOGF("COMP", " |mask_obj", cw->ec);
5588 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5595 evas_object_smart_member_del(cw->mask.obj);
5596 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5598 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5599 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5605 e_comp_object_mask_has(Evas_Object *obj)
5607 API_ENTRY EINA_FALSE;
5609 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5613 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5618 if ((cw->external_content) &&
5619 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5621 WRN("Can set up size to ONLY evas \"image\" object. "
5622 "But current external content is %d object for %p.",
5623 cw->content_type, cw->ec);
5627 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5629 evas_object_image_size_set(cw->obj, tw, th);
5633 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5635 Eina_Bool transform_set = EINA_FALSE;
5637 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5638 if (cw->ec->input_only) return;
5640 transform_set = !!set;
5644 if (!cw->transform_bg_obj)
5646 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5647 evas_object_move(o, 0, 0);
5648 evas_object_resize(o, 1, 1);
5649 if (cw->transform_bg_color.a >= 255)
5650 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5652 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5653 evas_object_color_set(o,
5654 cw->transform_bg_color.r,
5655 cw->transform_bg_color.g,
5656 cw->transform_bg_color.b,
5657 cw->transform_bg_color.a);
5658 if (cw->visible) evas_object_show(o);
5660 cw->transform_bg_obj = o;
5661 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5663 _e_comp_object_transform_obj_stack_update(obj);
5667 if (cw->transform_bg_obj)
5669 evas_object_smart_member_del(cw->transform_bg_obj);
5670 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5676 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5680 cw->transform_bg_color.r = r;
5681 cw->transform_bg_color.g = g;
5682 cw->transform_bg_color.b = b;
5683 cw->transform_bg_color.a = a;
5685 if (cw->transform_bg_obj)
5687 evas_object_color_set(cw->transform_bg_obj,
5688 cw->transform_bg_color.r,
5689 cw->transform_bg_color.g,
5690 cw->transform_bg_color.b,
5691 cw->transform_bg_color.a);
5696 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5699 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5700 if (cw->ec->input_only) return;
5701 if (!cw->transform_bg_obj) return;
5703 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5707 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5710 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5711 if (cw->ec->input_only) return;
5712 if (!cw->transform_bg_obj) return;
5714 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5718 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5720 Eina_Bool transform_set = EINA_FALSE;
5722 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5723 if (cw->ec->input_only) return;
5725 transform_set = !!set;
5729 if (!cw->transform_tranp_obj)
5731 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5732 evas_object_move(o, 0, 0);
5733 evas_object_resize(o, 1, 1);
5734 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5735 evas_object_color_set(o, 0, 0, 0, 0);
5736 if (cw->visible) evas_object_show(o);
5738 cw->transform_tranp_obj = o;
5739 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5740 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5741 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5743 _e_comp_object_transform_obj_stack_update(obj);
5747 if (cw->transform_tranp_obj)
5749 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5750 evas_object_smart_member_del(cw->transform_tranp_obj);
5751 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5757 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5760 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5761 if (cw->ec->input_only) return;
5762 if (!cw->transform_tranp_obj) return;
5764 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5768 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5771 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5772 if (cw->ec->input_only) return;
5773 if (!cw->transform_tranp_obj) return;
5775 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5778 #ifdef REFACTOR_DESK_AREA
5781 e_comp_object_layer_update(Evas_Object *obj,
5782 Evas_Object *above, Evas_Object *below)
5784 E_Comp_Object *cw2 = NULL;
5785 Evas_Object *o = NULL;
5790 if (cw->ec->layer_block) return;
5791 if ((above) && (below))
5793 ERR("Invalid layer update request! cw=%p", cw);
5801 layer = evas_object_layer_get(o);
5802 cw2 = evas_object_data_get(o, "comp_obj");
5805 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5807 o = evas_object_above_get(o);
5808 if ((!o) || (o == cw->smart_obj)) break;
5809 if (evas_object_layer_get(o) != layer)
5811 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5816 ec = e_client_top_get();
5817 if (ec) o = ec->frame;
5820 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5824 _e_comp_object_layers_remove(cw);
5827 if (cw2->layer > cw->layer)
5828 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5829 else if (cw2->layer == cw->layer)
5832 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5834 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5836 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5839 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5842 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5847 e_comp_object_layer_get(Evas_Object *obj)
5854 e_comp_object_content_set(Evas_Object *obj,
5855 Evas_Object *content,
5856 E_Comp_Object_Content_Type type)
5858 API_ENTRY EINA_FALSE;
5860 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5861 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5866 ERR("Can't set e.swallow.content to requested content. "
5867 "Previous comp object should not be changed at all.");
5871 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5873 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5874 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5876 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5877 type, content, cw->ec, cw->ec->pixmap);
5881 cw->external_content = EINA_TRUE;
5884 cw->content_type = type;
5885 e_util_size_debug_set(cw->obj, 1);
5886 evas_object_name_set(cw->obj, "cw->obj");
5887 _e_comp_object_alpha_set(cw);
5890 _e_comp_object_shadow_setup(cw);
5896 e_comp_object_content_unset(Evas_Object *obj)
5898 API_ENTRY EINA_FALSE;
5900 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5901 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5903 if (!cw->obj && !cw->ec->visible)
5905 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5909 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5911 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5917 if (cw->frame_object)
5918 edje_object_part_unswallow(cw->frame_object, cw->obj);
5920 edje_object_part_unswallow(cw->shobj, cw->obj);
5922 evas_object_del(cw->obj);
5923 evas_object_hide(cw->obj);
5927 cw->external_content = EINA_FALSE;
5928 if (cw->ec->is_cursor)
5931 DBG("%p is cursor surface..", cw->ec);
5932 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5934 evas_object_resize(cw->ec->frame, pw, ph);
5935 evas_object_hide(cw->ec->frame);
5940 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5941 cw->obj = evas_object_image_filled_add(e_comp->evas);
5942 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5943 e_util_size_debug_set(cw->obj, 1);
5944 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5945 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5946 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5947 evas_object_name_set(cw->obj, "cw->obj");
5948 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5949 _e_comp_object_alpha_set(cw);
5952 _e_comp_object_shadow_setup(cw);
5957 _e_comp_intercept_show_helper(cw);
5961 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5962 e_comp_object_dirty(cw->smart_obj);
5963 e_comp_object_render(cw->smart_obj);
5964 e_comp_object_render_update_add(obj);
5969 EINTERN Evas_Object *
5970 e_comp_object_content_get(Evas_Object *obj)
5974 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5976 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5978 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5985 E_API E_Comp_Object_Content_Type
5986 e_comp_object_content_type_get(Evas_Object *obj)
5988 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5990 return cw->content_type;
5994 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5997 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5998 E_Comp_Config *conf = e_comp_config_get();
5999 if (cw->ec->input_only) return;
6000 if (!conf->dim_rect_enable) return;
6002 cw->dim.mask_set = mask_set;
6008 if (!cw->dim.enable) return;
6009 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6013 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6015 Eina_Bool mask_set = EINA_FALSE;
6019 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6020 E_Comp_Config *conf = e_comp_config_get();
6021 if (cw->ec->input_only) return;
6022 if (!conf->dim_rect_enable) return;
6028 if (cw->dim.mask_obj)
6030 evas_object_smart_member_del(cw->dim.mask_obj);
6031 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6034 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);
6035 o = evas_object_rectangle_add(e_comp->evas);
6036 evas_object_color_set(o, 0, 0, 0, 0);
6037 evas_object_smart_member_add(o, obj);
6038 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6039 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6041 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6042 if (cw->visible) evas_object_show(o);
6044 cw->dim.mask_obj = o;
6045 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6047 evas_object_layer_set(cw->dim.mask_obj, 9998);
6051 if (cw->dim.mask_obj)
6053 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6054 evas_object_smart_member_del(cw->dim.mask_obj);
6055 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6061 e_comp_object_dim_client_set(E_Client *ec)
6063 E_Comp_Config *conf = e_comp_config_get();
6065 if (!conf->dim_rect_enable) return ;
6066 if (dim_client == ec) return;
6068 Eina_Bool prev_dim = EINA_FALSE;
6069 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6071 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6072 prev_dim = EINA_TRUE;
6074 if (prev_dim && dim_client->visible && ec)
6076 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6077 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6081 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6082 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6088 e_comp_object_dim_client_get(void)
6090 E_Comp_Config *conf = e_comp_config_get();
6092 if (!conf->dim_rect_enable ) return NULL;
6098 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6101 char emit[32] = "\0";
6102 E_Comp_Config *conf = e_comp_config_get();
6105 if (!conf->dim_rect_enable) return;
6106 if (!cw->effect_obj) return;
6107 if (enable == cw->dim.enable) return;
6109 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6110 if (noeffect || !conf->dim_rect_effect)
6112 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6116 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6119 cw->dim.enable = enable;
6121 if (cw->dim.mask_set && !enable)
6123 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6124 edje_object_signal_emit(cw->effect_obj, emit, "e");
6126 else if (cw->dim.mask_set && enable)
6128 edje_object_signal_emit(cw->effect_obj, emit, "e");
6129 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6133 edje_object_signal_emit(cw->effect_obj, emit, "e");
6138 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6140 API_ENTRY EINA_FALSE;
6141 E_Comp_Config *conf = e_comp_config_get();
6143 if (!ec) return EINA_FALSE;
6144 if (!conf->dim_rect_enable) return EINA_FALSE;
6146 if (cw->dim.enable) return EINA_TRUE;
6152 _e_comp_object_dim_update(E_Comp_Object *cw)
6154 E_Comp_Config *conf = e_comp_config_get();
6157 if (!conf->dim_rect_enable) return;
6158 if (!cw->effect_obj) return;
6161 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6162 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6164 if (cw->dim.mask_set)
6166 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6172 e_comp_object_clear(Evas_Object *obj)
6176 _e_comp_object_clear(cw);
6180 e_comp_object_hwc_update_exists(Evas_Object *obj)
6182 API_ENTRY EINA_FALSE;
6183 return cw->hwc_need_update;
6188 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6191 cw->hwc_need_update = set;
6195 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6197 API_ENTRY EINA_FALSE;
6198 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6202 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6205 if (cw->indicator.obj != indicator)
6206 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6207 cw->indicator.obj = indicator;
6208 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6212 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6215 if (cw->indicator.obj != indicator) return;
6216 cw->indicator.obj = NULL;
6217 edje_object_part_unswallow(cw->shobj, indicator);
6221 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6224 Edje_Message_Int_Set *msg;
6226 if (!cw->indicator.obj) return;
6228 cw->indicator.w = w;
6229 cw->indicator.h = h;
6231 if (!cw->shobj) return;
6233 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6237 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6238 edje_object_message_signal_process(cw->shobj);
6241 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6243 e_comp_object_map_update(Evas_Object *obj)
6246 E_Client *ec = cw->ec;
6247 E_Comp_Wl_Client_Data *cdata;
6249 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6252 int l, remain = sizeof buffer;
6255 if (e_object_is_del(E_OBJECT(ec))) return;
6256 cdata = e_client_cdata_get(ec);
6259 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6260 * when new buffer is attached.
6262 if (!cdata->buffer_ref.buffer) return;
6264 if ((!cw->redirected) ||
6265 (e_client_video_hw_composition_check(ec)) ||
6266 (!e_comp_wl_output_buffer_transform_get(ec) &&
6267 cdata->scaler.buffer_viewport.buffer.scale == 1))
6269 if (evas_object_map_enable_get(cw->effect_obj))
6271 ELOGF("TRANSFORM", "map: disable", cw->ec);
6272 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6273 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6274 evas_object_resize(cw->effect_obj, tw, th);
6281 EINA_SAFETY_ON_NULL_RETURN(map);
6283 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6289 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6291 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6292 e_map_point_image_uv_set(map, 0, x, y);
6293 l = snprintf(p, remain, "%d,%d", x, y);
6294 p += l, remain -= l;
6296 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6297 e_map_point_image_uv_set(map, 1, x, y);
6298 l = snprintf(p, remain, " %d,%d", x, y);
6299 p += l, remain -= l;
6301 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6302 e_map_point_image_uv_set(map, 2, x, y);
6303 l = snprintf(p, remain, " %d,%d", x, y);
6304 p += l, remain -= l;
6306 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6307 e_map_point_image_uv_set(map, 3, x, y);
6308 l = snprintf(p, remain, " %d,%d", x, y);
6309 p += l, remain -= l;
6311 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6313 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6315 e_comp_object_map_set(cw->effect_obj, map);
6316 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6320 /* if there's screen rotation with comp mode, then ec->effect_obj and
6321 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6323 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6324 evas_object_resize(cw->effect_obj, tw, th);
6328 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6330 API_ENTRY EINA_FALSE;
6332 cw->render_trace = set;
6338 e_comp_object_native_usable_get(Evas_Object *obj)
6340 API_ENTRY EINA_FALSE;
6341 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6343 if (cw->ec->input_only) return EINA_FALSE;
6344 if (cw->external_content) return EINA_FALSE;
6345 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6347 /* just return true value, if it is normal case */
6348 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6351 Evas_Native_Surface *ns;
6352 ns = evas_object_image_native_surface_get(cw->obj);
6354 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6357 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6365 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6367 API_ENTRY EINA_FALSE;
6368 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6369 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6370 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6374 case E_COMP_IMAGE_FILTER_BLUR:
6375 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6377 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6378 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6380 case E_COMP_IMAGE_FILTER_INVERSE:
6381 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6383 case E_COMP_IMAGE_FILTER_NONE:
6385 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6389 cw->image_filter = filter;
6394 EINTERN E_Comp_Image_Filter
6395 e_comp_object_image_filter_get(Evas_Object *obj)
6397 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6398 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6399 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6400 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6402 return cw->image_filter;
6406 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6410 if (!_damage_trace) return;
6412 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6413 evas_object_del(obj);
6415 _damage_trace_post_objs = NULL;
6419 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6421 if (!_damage_trace) return;
6423 _damage_trace_post_objs = _damage_trace_objs;
6424 _damage_trace_objs = NULL;
6428 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6430 if (_damage_trace == onoff) return;
6434 evas_event_callback_add(e_comp->evas,
6435 EVAS_CALLBACK_RENDER_PRE,
6436 _e_comp_object_damage_trace_render_pre_cb,
6439 evas_event_callback_add(e_comp->evas,
6440 EVAS_CALLBACK_RENDER_POST,
6441 _e_comp_object_damage_trace_render_post_cb,
6448 EINA_LIST_FREE(_damage_trace_objs, obj)
6449 evas_object_del(obj);
6451 _damage_trace_objs = NULL;
6453 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6454 evas_object_del(obj);
6456 _damage_trace_post_objs = NULL;
6458 evas_event_callback_del(e_comp->evas,
6459 EVAS_CALLBACK_RENDER_PRE,
6460 _e_comp_object_damage_trace_render_pre_cb);
6462 evas_event_callback_del(e_comp->evas,
6463 EVAS_CALLBACK_RENDER_POST,
6464 _e_comp_object_damage_trace_render_post_cb);
6467 _damage_trace = onoff;
6471 e_comp_object_redirected_get(Evas_Object *obj)
6473 API_ENTRY EINA_FALSE;
6474 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6476 return cw->redirected;
6480 e_comp_object_color_visible_get(Evas_Object *obj)
6482 API_ENTRY EINA_FALSE;
6485 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6487 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6491 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6495 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6499 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6507 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6509 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6511 return e_map_set_to_comp_object(em, obj);
6515 e_comp_object_map_get(const Evas_Object *obj)
6517 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6519 return e_map_get_from_comp_object(obj);
6523 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6525 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6527 evas_object_map_enable_set(obj, enable);
6533 e_comp_object_render_update_lock(Evas_Object *obj)
6535 E_Comp_Wl_Buffer *buffer;
6536 struct wayland_tbm_client_queue *cqueue;
6538 API_ENTRY EINA_FALSE;
6540 if (cw->render_update_lock.lock == 0)
6542 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6544 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6545 if ((buffer) && (buffer->resource))
6547 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6549 wayland_tbm_server_client_queue_flush(cqueue);
6552 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6553 e_comp_object_render_update_del(obj);
6555 ELOGF("COMP", "Render update lock enabled", cw->ec);
6558 cw->render_update_lock.lock++;
6564 e_comp_object_render_update_unlock(Evas_Object *obj)
6568 if (cw->render_update_lock.lock == 0)
6571 cw->render_update_lock.lock--;
6573 if (cw->render_update_lock.lock == 0)
6576 if (cw->render_update_lock.pending_move_set)
6578 evas_object_move(obj,
6579 cw->render_update_lock.pending_move_x,
6580 cw->render_update_lock.pending_move_y);
6581 cw->render_update_lock.pending_move_x = 0;
6582 cw->render_update_lock.pending_move_y = 0;
6583 cw->render_update_lock.pending_move_set = EINA_FALSE;
6586 if (cw->render_update_lock.pending_resize_set)
6588 evas_object_resize(obj,
6589 cw->render_update_lock.pending_resize_w,
6590 cw->render_update_lock.pending_resize_h);
6591 cw->render_update_lock.pending_resize_w = 0;
6592 cw->render_update_lock.pending_resize_h = 0;
6593 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6596 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6598 if ((cw->ec->exp_iconify.buffer_flush) &&
6599 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6600 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6601 e_comp_object_clear(obj);
6603 e_comp_object_render_update_add(obj);
6605 ELOGF("COMP", "Render update lock disabled", cw->ec);
6610 e_comp_object_render_update_lock_get(Evas_Object *obj)
6612 API_ENTRY EINA_FALSE;
6614 if (cw->render_update_lock.lock > 0)
6621 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6625 if (cw->transparent.set)
6627 if (r) *r = cw->transparent.user_r;
6628 if (g) *g = cw->transparent.user_g;
6629 if (b) *b = cw->transparent.user_b;
6630 if (a) *a = cw->transparent.user_a;
6634 evas_object_color_get(obj, r, g, b, a);
6639 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6643 evas_object_render_op_set(cw->obj, op);
6646 EINTERN Evas_Render_Op
6647 e_comp_object_render_op_get(Evas_Object *obj)
6649 API_ENTRY EVAS_RENDER_BLEND;
6651 return evas_object_render_op_get(cw->obj);
6655 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6658 wl_signal_add(&cw->events.lower, listener);
6661 #ifdef REFACTOR_DESK_AREA
6663 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6666 wl_signal_add(&cw->events.lower_done, listener);
6670 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6673 wl_signal_add(&cw->events.raise, listener);
6678 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6681 wl_signal_add(&cw->events.show, listener);
6685 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6688 wl_signal_add(&cw->events.hide, listener);
6691 #ifdef REFACTOR_DESK_AREA
6693 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6696 wl_signal_add(&cw->events.set_layer, listener);
6700 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6703 wl_signal_add(&cw->events.stack_above, listener);
6707 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6710 wl_signal_add(&cw->events.stack_below, listener);