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"
17 = keys that return objects =
18 - E_Client: the client associated with the object (E_Client*)
19 - comp_smart_obj: cw->smart_obj (Evas_Object*)
20 - comp_obj: cw (E_Comp_Object*)
22 = keys that are bool flags =
23 - client_restack: client needs a protocol-level restack
24 - comp_override: object is triggering a nocomp override to force compositing
25 - comp_ref: object has a ref from visibility animations
26 - comp_showing: object is currently running its show animation
27 - comp_hiding: object is currently running its hiding animation
28 - comp_object: object is a compositor-created object
29 - comp_object_skip: object has a name which prohibits theme shadows
30 - comp_object-to_del: list of objects which will be deleted when this object is deleted
31 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
32 - effect_running: object is animating by external module
35 #define UPDATE_MAX 512 // same as evas
36 #define FAILURE_MAX 2 // seems reasonable
37 #define SMART_NAME "e_comp_object"
38 #define INPUT_OBJ_SMART_NAME "input_object"
40 /* for non-util functions */
41 #define API_ENTRY E_Comp_Object *cw; \
42 cw = evas_object_smart_data_get(obj); \
43 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
45 /* for util functions (obj may or may not be E_Comp_Object */
46 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
49 CRI("YOU PASSED NULL! ARGH!"); \
52 cw = evas_object_smart_data_get(obj); \
53 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
55 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
57 /* enable for lots of client size info in console output */
59 # define e_util_size_debug_set(x, y)
62 /* enable along with display-specific damage INF calls to enable render tracing
66 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
68 #define RENDER_DEBUG(...)
71 #ifdef REFACTOR_DESK_AREA
73 typedef struct _E_Comp_Object
77 int x, y, w, h; // geometry
81 E_Comp_Object_Frame client_inset;
83 Eina_Stringshare *frame_theme;
84 Eina_Stringshare *frame_name;
85 Eina_Stringshare *visibility_effect; //effect when toggling visibility
87 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
89 Evas_Object *smart_obj; // smart object
90 Evas_Object *clip; // clipper over effect object
91 Evas_Object *input_obj; // input smart object
92 Evas_Object *obj; // composite object
93 Evas_Object *frame_object; // for client frames
94 Evas_Object *shobj; // shadow object
95 Evas_Object *effect_obj; // effects object
96 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
100 } transform_bg_color;
101 Evas_Object *transform_tranp_obj;// transform transp rect obj
102 Evas_Object *default_input_obj; // default input object
103 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
104 Eina_List *obj_mirror; // extra mirror objects
105 Eina_Tiler *updates; //render update regions
106 Eina_Tiler *pending_updates; //render update regions which are about to render
108 Evas_Native_Surface *ns; //for custom gl rendering
110 struct wl_listener buffer_destroy_listener;
112 unsigned int update_count; // how many updates have happened to this obj
114 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
116 unsigned int animating; // it's busy animating
117 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
118 unsigned int force_visible; //number of visible obj_mirror objects
119 Eina_Bool delete_pending : 1; // delete pending
120 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
121 Eina_Bool showing : 1; // object is currently in "show" animation
122 Eina_Bool hiding : 1; // object is currently in "hide" animation
123 Eina_Bool visible : 1; // is visible
125 Eina_Bool shaped : 1; // is shaped
126 Eina_Bool update : 1; // has updates to fetch
127 Eina_Bool redirected : 1; // has updates to fetch
128 Eina_Bool native : 1; // native
130 Eina_Bool nocomp : 1; // nocomp applied
131 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
132 Eina_Bool real_hid : 1; // last hide was a real window unmap
134 Eina_Bool effect_set : 1; //effect_obj has a valid group
135 Eina_Bool effect_running : 1; //effect_obj is playing an animation
136 Eina_Bool effect_clip : 1; //effect_obj is clipped
137 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
139 Eina_Bool updates_exist : 1;
140 Eina_Bool updates_full : 1; // entire object will be updated
142 Eina_Bool force_move : 1;
143 Eina_Bool frame_extends : 1; //frame may extend beyond object size
144 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
145 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
146 Eina_Bool user_alpha_set : 1;
147 Eina_Bool user_alpha : 1;
151 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
152 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
159 } indicator; //indicator object for internal client
163 Evas_Object *mask_obj;
166 int mask_x, mask_y, mask_w, mask_h;
169 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
171 tbm_surface_h tbm_surface;
172 E_Comp_Image_Filter image_filter;
173 Eina_Bool set_mouse_callbacks;
178 E_Comp_Wl_Buffer_Ref buffer_ref;
179 Eina_Bool pending_move_set;
180 int pending_move_x, pending_move_y;
181 Eina_Bool pending_resize_set;
182 int pending_resize_w, pending_resize_h;
183 } render_update_lock;
196 struct wl_signal lower;
197 //#ifdef REFACTOR_DESK_AREA
198 struct wl_signal raise;
200 struct wl_signal show;
201 struct wl_signal hide;
202 //#ifdef REFACTOR_DESK_AREA
203 struct wl_signal set_layer;
204 struct wl_signal stack_above;
205 struct wl_signal stack_below;
211 typedef struct _E_Input_Rect_Data
217 typedef struct _E_Input_Rect_Smart_Data
219 Eina_List *input_rect_data_list;
221 } E_Input_Rect_Smart_Data;
223 struct E_Comp_Object_Mover
226 E_Comp_Object_Mover_Cb func;
232 static Eina_Inlist *_e_comp_object_movers = NULL;
233 static Evas_Smart *_e_comp_smart = NULL;
234 static Evas_Smart *_e_comp_input_obj_smart = NULL;
236 static int _e_comp_object_hooks_delete = 0;
237 static int _e_comp_object_hooks_walking = 0;
239 static Eina_Inlist *_e_comp_object_hooks[] =
241 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
242 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
243 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
244 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
245 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
246 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
247 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
248 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
251 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
252 static int _e_comp_object_intercept_hooks_delete = 0;
253 static int _e_comp_object_intercept_hooks_walking = 0;
255 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
257 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
258 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
262 static Eina_Bool _damage_trace = EINA_FALSE;
263 static Eina_List *_damage_trace_objs = NULL;
264 static Eina_List *_damage_trace_post_objs = NULL;
266 /* sekrit functionzzz */
267 EINTERN void e_client_focused_set(E_Client *ec);
269 /* emitted every time a new noteworthy comp object is added */
270 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
272 /* ecore event define */
273 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
274 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
275 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
277 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
278 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
279 static void _e_comp_object_dim_update(E_Comp_Object *cw);
280 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
281 #ifdef REFACTOR_DESK_AREA
283 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
286 static E_Client *dim_client = NULL;
289 _e_comp_object_hooks_clean(void)
292 E_Comp_Object_Hook *ch;
295 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
296 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
298 if (!ch->delete_me) continue;
299 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
305 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
307 E_Comp_Object_Hook *ch;
308 Eina_Bool ret = EINA_TRUE;
310 if (e_object_is_del(E_OBJECT(ec)))
312 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
313 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
314 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
315 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
316 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
317 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
318 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
319 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
325 e_object_ref(E_OBJECT(ec));
326 _e_comp_object_hooks_walking++;
327 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
329 if (ch->delete_me) continue;
330 if (!(ch->func(ch->data, ec)))
336 _e_comp_object_hooks_walking--;
337 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
338 _e_comp_object_hooks_clean();
340 e_object_unref(E_OBJECT(ec));
345 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
347 _e_comp_object_intercept_hooks_clean(void)
350 E_Comp_Object_Intercept_Hook *ch;
353 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
354 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
356 if (!ch->delete_me) continue;
357 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
363 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
365 E_Comp_Object_Intercept_Hook *ch;
366 Eina_Bool ret = EINA_TRUE;
368 if (e_object_is_del(E_OBJECT(ec))) return ret;
369 e_object_ref(E_OBJECT(ec));
370 _e_comp_object_intercept_hooks_walking++;
371 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
373 if (ch->delete_me) continue;
374 if (!(ch->func(ch->data, ec)))
380 _e_comp_object_intercept_hooks_walking--;
381 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
382 _e_comp_object_intercept_hooks_clean();
384 e_object_unref(E_OBJECT(ec));
391 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
393 E_Event_Comp_Object *ev = event;
396 ec = evas_object_data_get(ev->comp_object, "E_Client");
400 e_object_unref(E_OBJECT(ec));
402 evas_object_unref(ev->comp_object);
407 _e_comp_object_event_add(Evas_Object *obj)
409 E_Event_Comp_Object *ev;
412 if (stopping) return;
413 ev = E_NEW(E_Event_Comp_Object, 1);
414 EINA_SAFETY_ON_NULL_RETURN(ev);
416 evas_object_ref(obj);
417 ev->comp_object = obj;
418 ec = evas_object_data_get(ev->comp_object, "E_Client");
422 e_object_ref(E_OBJECT(ec));
424 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
428 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
430 E_Event_Comp_Object *ev = event;
433 ec = evas_object_data_get(ev->comp_object, "E_Client");
437 e_object_unref(E_OBJECT(ec));
439 evas_object_unref(ev->comp_object);
444 _e_comp_object_event_simple(Evas_Object *obj, int type)
446 E_Event_Comp_Object *ev;
449 ev = E_NEW(E_Event_Comp_Object, 1);
452 evas_object_ref(obj);
453 ev->comp_object = obj;
454 ec = evas_object_data_get(ev->comp_object, "E_Client");
458 e_object_ref(E_OBJECT(ec));
460 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
462 /////////////////////////////////////
465 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
467 E_Comp_Object *cw = data;
469 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
473 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
475 E_Comp_Object *cw = data;
477 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
478 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
481 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
482 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
486 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
488 E_Comp_Object *cw = data;
491 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
492 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
495 /////////////////////////////////////
497 #ifdef REFACTOR_DESK_AREA
499 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
502 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
507 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
508 if (cw->ec->input_only) return;
510 layer = evas_object_layer_get(obj);
512 if (cw->transform_bg_obj)
514 if (layer != evas_object_layer_get(cw->transform_bg_obj))
516 evas_object_layer_set(cw->transform_bg_obj, layer);
519 evas_object_stack_below(cw->transform_bg_obj, obj);
522 if (cw->transform_tranp_obj)
524 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
526 evas_object_layer_set(cw->transform_tranp_obj, layer);
529 evas_object_stack_below(cw->transform_tranp_obj, obj);
534 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
541 if (!map) return NULL;
543 e_map_util_points_populate_from_object_full(map, obj, 0);
544 e_map_util_points_color_set(map, 255, 255, 255, 255);
546 for (i = 0 ; i < 4 ; ++i)
551 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
552 e_map_point_coord_set(map, i, x, y, 1.0);
559 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
565 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
568 e_comp_object_map_set(obj, map);
569 e_comp_object_map_enable_set(obj, EINA_TRUE);
576 evas_object_map_enable_set(obj, EINA_FALSE);
581 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
587 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
590 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
592 e_comp_object_map_set(obj, map);
593 e_comp_object_map_enable_set(obj, EINA_TRUE);
600 evas_object_map_enable_set(obj, EINA_FALSE);
603 /////////////////////////////////////
605 static inline Eina_Bool
606 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
608 if (num > 1) return EINA_TRUE;
609 if ((rects[0].x == 0) && (rects[0].y == 0) &&
610 ((int)rects[0].w == w) && ((int)rects[0].h == h))
615 /////////////////////////////////////
617 /* add a client to the layer-client list */
618 #ifdef REFACTOR_DESK_AREA
621 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
623 g_rec_mutex_lock(&e_comp->ec_list_mutex);
626 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));
628 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));
629 if ((!above) && (!below))
632 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
633 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
634 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
636 e_comp->layers[cw->layer].clients_count++;
638 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
642 _e_comp_object_layers_remove(E_Comp_Object *cw)
644 g_rec_mutex_lock(&e_comp->ec_list_mutex);
646 if (cw->ec && e_comp->layers[cw->layer].clients)
648 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
649 e_comp->layers[cw->layer].clients_count--;
652 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
656 /////////////////////////////////////
658 _e_comp_object_alpha_set(E_Comp_Object *cw)
660 Eina_Bool alpha = cw->ec->argb;
662 if ((cw->external_content) &&
663 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
668 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
669 if (cw->user_alpha_set) alpha = cw->user_alpha;
671 evas_object_image_alpha_set(cw->obj, alpha);
675 _e_comp_object_shadow(E_Comp_Object *cw)
677 if (e_client_util_shadow_state_get(cw->ec))
678 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
680 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
681 if (cw->frame_object)
682 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
683 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
686 /* convert from the surface coordinates to the buffer coordinates */
688 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
690 E_Comp_Wl_Buffer_Viewport *vp;
691 E_Comp_Wl_Client_Data *cdata;
695 cdata = e_client_cdata_get(ec);
697 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
704 vp = &cdata->scaler.buffer_viewport;
705 transform = e_comp_wl_output_buffer_transform_get(ec);
707 e_pixmap_size_get(ec->pixmap, &bw, &bh);
709 /* for subsurface, it should be swap 90 and 270 */
710 if (e_comp_wl_subsurface_check(ec))
713 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
714 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
715 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
716 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
722 case WL_OUTPUT_TRANSFORM_NORMAL:
723 default: tx = sx, ty = sy; break;
724 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
725 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
726 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
727 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
728 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
729 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
730 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
733 tx *= vp->buffer.scale;
734 ty *= vp->buffer.scale;
741 _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)
749 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
750 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
757 if (dw) *dw = MAX(x1, x2) - mx;
758 if (dh) *dh = MAX(y1, y2) - my;
762 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
763 int *dx, int *dy, int *dw, int *dh)
765 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
766 E_Util_Transform_Rect_Vertex sv, dv;
770 e_pixmap_size_get(ec->pixmap, &bw, &bh);
772 sv = e_util_transform_rect_to_vertices(&rect);
774 for (i = 0; i < 4; i++)
776 double x = 0.0, y = 0.0;
778 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
780 /* if evas decide coordinate is outside of map, it returns (0, 0)
781 in this case, full damage is added.
783 if ((i != 0) && (x == 0.0) && (y == 0.0))
786 dv.vertices[i].vertex[0] = x;
787 dv.vertices[i].vertex[1] = y;
788 dv.vertices[i].vertex[2] = 1.0;
789 dv.vertices[i].vertex[3] = 1.0;
792 rect = e_util_transform_vertices_to_rect(&dv);
794 if (dx) *dx = rect.x;
795 if (dy) *dy = rect.y;
796 if (dw) *dw = rect.w;
797 if (dh) *dh = rect.h;
811 _e_comp_object_map_damage_transform_get(E_Client *ec)
818 if (!e_client_transform_core_enable_get(ec))
821 m = e_client_map_get(ec);
825 e_pixmap_size_get(ec->pixmap, &bw, &bh);
826 if ((bw == 0) || (bh == 0))
839 e_map_point_coord_set(m2, 0, 0, 0, 0);
840 e_map_point_coord_set(m2, 1, bw, 0, 0);
841 e_map_point_coord_set(m2, 2, bw, bh, 0);
842 e_map_point_coord_set(m2, 3, 0, bh, 0);
844 for (i = 0; i < 4; i++)
848 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
849 e_map_point_image_uv_set(m2, i, map_x, map_y);
856 /////////////////////////////////////
858 /* handle evas mouse-in events on client object */
860 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
862 Evas_Event_Mouse_In *ev = event_info;
863 E_Comp_Object *cw = data;
865 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
868 /* handle evas mouse-out events on client object */
870 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
872 Evas_Event_Mouse_Out *ev = event_info;
873 E_Comp_Object *cw = data;
875 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
878 /* handle evas mouse wheel events on client object */
880 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
882 Evas_Event_Mouse_Wheel *ev = event_info;
883 E_Comp_Object *cw = data;
884 E_Binding_Event_Wheel ev2;
887 if (e_client_action_get()) return;
888 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
889 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
892 /* handle evas mouse down events on client object */
894 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
896 Evas_Event_Mouse_Down *ev = event_info;
897 E_Comp_Object *cw = data;
898 E_Binding_Event_Mouse_Button ev2;
901 if (e_client_action_get()) return;
902 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
903 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
906 /* handle evas mouse up events on client object */
908 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
910 Evas_Event_Mouse_Up *ev = event_info;
911 E_Comp_Object *cw = data;
912 E_Binding_Event_Mouse_Button ev2;
915 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
916 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
917 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
920 /* handle evas mouse movement events on client object */
922 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
924 Evas_Event_Mouse_Move *ev = event_info;
925 E_Comp_Object *cw = data;
928 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
929 e_client_mouse_move(cw->ec, &ev->cur.output);
931 /////////////////////////////////////
933 /* helper function for checking compositor themes based on user-defined matches */
935 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
937 if (((m->title) && (!ec->netwm.name)) ||
938 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
940 #if defined(__cplusplus) || defined(c_plusplus)
941 if (((m->clas) && (!ec->icccm.cpp_class)) ||
942 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
945 if (((m->clas) && (!ec->icccm.class)) ||
946 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
950 if (((m->role) && (!ec->icccm.window_role)) ||
951 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
957 if ((int)ec->netwm.type != m->primary_type)
960 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
963 if (m->borderless != 0)
967 if (e_client_util_borderless(ec))
969 if (!(((m->borderless == -1) && (!borderless)) ||
970 ((m->borderless == 1) && (borderless))))
977 if (((ec->icccm.transient_for != 0) ||
980 if (!(((m->dialog == -1) && (!dialog)) ||
981 ((m->dialog == 1) && (dialog))))
984 if (m->accepts_focus != 0)
986 int accepts_focus = 0;
988 if (ec->icccm.accepts_focus)
990 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
991 ((m->accepts_focus == 1) && (accepts_focus))))
1000 if (!(((m->vkbd == -1) && (!vkbd)) ||
1001 ((m->vkbd == 1) && (vkbd))))
1006 if (!(((m->argb == -1) && (!ec->argb)) ||
1007 ((m->argb == 1) && (ec->argb))))
1010 if (m->fullscreen != 0)
1012 int fullscreen = ec->fullscreen;
1014 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1015 ((m->fullscreen == 1) && (fullscreen))))
1020 if (!(m->modal == -1))
1026 /* function for setting up a client's compositor frame theme (cw->shobj) */
1028 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1032 Eina_List *list = NULL, *l;
1033 E_Input_Rect_Data *input_rect_data;
1034 E_Input_Rect_Smart_Data *input_rect_sd;
1036 Eina_Stringshare *reshadow_group = NULL;
1037 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1038 Eina_Stringshare *name, *title;
1039 E_Comp_Config *conf = e_comp_config_get();
1041 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1042 /* match correct client type */
1043 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1044 name = cw->ec->icccm.name;
1045 title = cw->ec->icccm.title;
1046 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1047 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1049 /* skipping here is mostly a hack for systray because I hate it */
1052 EINA_LIST_FOREACH(list, l, m)
1054 if (((m->name) && (!name)) ||
1055 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1057 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1060 no_shadow = m->no_shadow;
1061 if (m->shadow_style)
1063 /* fast effects are just themes with "/fast" appended and shorter effect times */
1066 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1067 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1069 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1071 /* default to non-fast style if fast not available */
1074 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1075 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1077 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1079 if (ok && m->visibility_effect)
1080 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1087 if (skip || (cw->ec->e.state.video))
1089 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1091 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1094 if (conf->shadow_style)
1098 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1099 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1101 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1105 snprintf(buf, sizeof(buf), "e/comp/frame/%s", 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);
1115 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1117 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1121 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1123 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1128 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1133 if (cw->ec->override)
1135 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1136 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1138 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1139 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
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);
1149 _e_comp_object_shadow(cw);
1152 if (focus || cw->ec->focused || cw->ec->override)
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1160 /* visibility must always be enabled for re_manage clients to prevent
1161 * pop-in animations every time the user sees a persistent client again;
1162 * applying visibility for iconic clients prevents the client from getting
1165 if (cw->visible || cw->ec->re_manage)
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1168 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1170 /* breaks animation counter */
1171 if (cw->frame_object)
1173 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1175 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1176 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1182 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1186 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1189 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1191 if (input_rect_data->obj)
1193 pass_event_flag = EINA_TRUE;
1199 if (cw->indicator.obj)
1201 Evas_Object *indicator;
1202 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1203 if (indicator != cw->indicator.obj)
1205 edje_object_part_unswallow(cw->shobj, indicator);
1206 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1207 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1211 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1212 evas_object_pass_events_set(cw->obj, pass_event_flag);
1217 /////////////////////////////////////////////
1220 _e_comp_object_animating_begin(E_Comp_Object *cw)
1223 if (cw->animating == 1)
1225 e_comp->animating++;
1227 e_object_ref(E_OBJECT(cw->ec));
1232 _e_comp_object_animating_end(E_Comp_Object *cw)
1241 if (cw->ec->launching)
1243 if (!cw->ec->extra_animating)
1245 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1246 cw->ec->launching = EINA_FALSE;
1247 if (cw->ec->first_mapped)
1249 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1250 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1253 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1257 e_comp->animating--;
1258 cw->showing = cw->hiding = 0;
1260 if (e_comp->animating == 0)
1261 e_comp_visibility_calculation_set(EINA_TRUE);
1262 /* remove ref from animation start, account for possibility of deletion from unref */
1263 return !!e_object_unref(E_OBJECT(cw->ec));
1269 /* handle the end of a compositor animation */
1271 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1273 E_Comp_Object *cw = data;
1275 /* visible clients which have never been sized are a bug */
1276 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1277 CRI("ACK! ec:%p", cw->ec);
1278 if (!_e_comp_object_animating_end(cw)) return;
1279 if (cw->animating) return;
1280 /* hide only after animation finishes to guarantee a full run of the animation */
1281 if (!cw->defer_hide) return;
1282 if ((!strcmp(emission, "e,action,hide,done")) ||
1283 (!strcmp(emission, "e,action,done")) ||
1284 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1286 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1287 evas_object_hide(cw->smart_obj);
1291 /* run a visibility compositor effect if available, return false if object is dead */
1293 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1299 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1300 if (!cw->effect_running)
1301 _e_comp_object_animating_begin(cw);
1302 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1303 return _e_comp_object_animating_end(cw);
1304 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1305 return _e_comp_object_animating_end(cw);
1307 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1310 zone = e_comp_zone_find_by_ec(cw->ec);
1312 zw = zone->w, zh = zone->h;
1317 zone = e_comp_object_util_zone_get(cw->smart_obj);
1318 if (!zone) zone = e_zone_current_get();
1325 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1326 cw->w, cw->h, zw, zh, x, y}, 8);
1327 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1328 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1331 /////////////////////////////////////////////
1333 /* create necessary objects for clients that e manages */
1335 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1337 if (cw->set_mouse_callbacks) return;
1338 if (!cw->smart_obj) return;
1340 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1341 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1342 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1343 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1344 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1345 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1347 cw->set_mouse_callbacks = EINA_TRUE;
1351 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1353 if (!cw->set_mouse_callbacks) return;
1354 if (!cw->smart_obj) return;
1356 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1357 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1358 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1359 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1360 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1361 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1363 cw->set_mouse_callbacks = EINA_FALSE;
1367 _e_comp_object_setup(E_Comp_Object *cw)
1369 cw->clip = evas_object_rectangle_add(e_comp->evas);
1370 evas_object_move(cw->clip, -9999, -9999);
1371 evas_object_resize(cw->clip, 999999, 999999);
1372 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1373 cw->effect_obj = edje_object_add(e_comp->evas);
1374 evas_object_move(cw->effect_obj, cw->x, cw->y);
1375 evas_object_clip_set(cw->effect_obj, cw->clip);
1376 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1377 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1378 cw->shobj = edje_object_add(e_comp->evas);
1379 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1380 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1381 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1383 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1384 if (cw->ec->override)
1386 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1387 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1388 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1390 else if (!cw->ec->input_only)
1392 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1393 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1394 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1396 cw->real_hid = !cw->ec->input_only;
1397 if (!cw->ec->input_only)
1399 e_util_size_debug_set(cw->effect_obj, 1);
1400 _e_comp_object_mouse_event_callback_set(cw);
1403 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1404 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1405 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1406 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1407 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1408 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1410 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1413 /////////////////////////////////////////////
1415 /* for fast path evas rendering; only called during render */
1417 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1419 E_Comp_Object *cw = data;
1420 E_Client *ec = cw->ec;
1422 int bx, by, bxx, byy;
1424 if (e_object_is_del(E_OBJECT(ec))) return;
1425 if (cw->external_content) return;
1426 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1427 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1430 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1431 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1433 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1435 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1436 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1440 bx = by = bxx = byy = 0;
1441 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1444 Edje_Message_Int_Set *msg;
1445 Edje_Message_Int msg2;
1446 Eina_Bool id = (bx || by || bxx || byy);
1448 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1454 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1456 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1460 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1461 e_comp_client_post_update_add(cw->ec);
1463 else if (e_comp_object_render(ec->frame))
1465 /* apply shape mask if necessary */
1466 if ((!cw->native) && (ec->shaped))
1467 e_comp_object_shape_apply(ec->frame);
1469 /* shaped clients get precise mouse events to handle transparent pixels */
1470 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1472 /* queue another render if client is still dirty; cannot refresh here. */
1473 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1474 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1476 if (cw->render_trace)
1478 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1484 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1486 E_Comp_Object *cw = data;
1487 E_Client *ec = cw->ec;
1489 if (e_object_is_del(E_OBJECT(ec))) return;
1490 if (cw->external_content) return;
1491 if (!e_comp->hwc) return;
1493 e_comp_client_render_list_add(cw->ec);
1495 if (!ec->hwc_window) return;
1497 e_hwc_windows_rendered_window_add(ec->hwc_window);
1500 /////////////////////////////////////////////
1503 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1505 E_Comp_Object *cw = data;
1508 if (cw->render_update_lock.lock)
1510 cw->render_update_lock.pending_move_x = x;
1511 cw->render_update_lock.pending_move_y = y;
1512 cw->render_update_lock.pending_move_set = EINA_TRUE;
1516 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1517 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1518 (cw->external_content))
1520 /* delay to move until the external content is unset */
1521 cw->ec->changes.pos = 1;
1526 if (cw->ec->move_after_resize)
1528 if ((x != cw->ec->x) || (y != cw->ec->y))
1530 if (!cw->ec->is_cursor)
1531 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1532 e_client_pos_set(cw->ec, x, y);
1533 cw->ec->changes.pos = 1;
1539 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1540 (cw->ec->manage_resize.resize_obj))
1542 e_client_pos_set(cw->ec, x, y);
1543 cw->ec->client.x = x + cw->client_inset.l;
1544 cw->ec->client.y = y + cw->client_inset.t;
1545 e_policy_visibility_client_defer_move(cw->ec);
1549 /* if frame_object does not exist, client_inset indicates CSD.
1550 * this means that ec->client matches cw->x/y, the opposite
1553 fx = (!cw->frame_object) * cw->client_inset.l;
1554 fy = (!cw->frame_object) * cw->client_inset.t;
1555 if ((cw->x == x + fx) && (cw->y == y + fy))
1557 if ((cw->ec->x != x) || (cw->ec->y != y))
1559 /* handle case where client tries to move to position and back very quickly */
1560 e_client_pos_set(cw->ec, x, y);
1561 cw->ec->client.x = x + cw->client_inset.l;
1562 cw->ec->client.y = y + cw->client_inset.t;
1566 if (!cw->ec->maximize_override)
1568 /* prevent moving in some directions while directionally maximized */
1569 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1571 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1574 ix = x + cw->client_inset.l;
1575 iy = y + cw->client_inset.t;
1576 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1577 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1578 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1580 /* prevent moving at all if move isn't allowed in current maximize state */
1581 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1582 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1585 zone = e_comp_zone_find_by_ec(cw->ec);
1588 cw->ec->changes.need_unmaximize = 1;
1589 cw->ec->saved.x = ix - zone->x;
1590 cw->ec->saved.y = iy - zone->y;
1591 cw->ec->saved.w = cw->ec->client.w;
1592 cw->ec->saved.h = cw->ec->client.h;
1596 /* only update during resize if triggered by resize */
1597 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1598 /* delay to move while surface waits paired commit serial*/
1599 if (e_client_pending_geometry_has(cw->ec))
1601 /* do nothing while waiting paired commit serial*/
1605 e_client_pos_set(cw->ec, x, y);
1606 if (cw->ec->new_client)
1608 /* don't actually do anything until first client idler loop */
1609 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1610 cw->ec->changes.pos = 1;
1615 /* only update xy position of client to avoid invalid
1616 * first damage region if it is not a new_client. */
1617 cw->ec->client.x = ix;
1618 cw->ec->client.y = iy;
1621 if (!cw->frame_object)
1623 evas_object_move(obj, x, y);
1628 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1630 E_Comp_Object *cw = data;
1631 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1634 if (cw->render_update_lock.lock)
1636 cw->render_update_lock.pending_resize_w = w;
1637 cw->render_update_lock.pending_resize_h = h;
1638 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1642 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1644 e_client_size_set(cw->ec, w, h);
1645 evas_object_resize(obj, w, h);
1649 /* if frame_object does not exist, client_inset indicates CSD.
1650 * this means that ec->client matches cw->w/h, the opposite
1653 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1654 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1655 if ((cw->w == w + fw) && (cw->h == h + fh))
1657 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1658 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1659 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1661 /* handle case where client tries to resize itself and back very quickly */
1662 e_client_size_set(cw->ec, w, h);
1663 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1664 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1665 evas_object_smart_callback_call(obj, "client_resize", NULL);
1669 /* guarantee that fullscreen is fullscreen */
1670 zone = e_comp_zone_find_by_ec(cw->ec);
1672 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1674 if (!e_client_transform_core_enable_get(cw->ec))
1677 /* calculate client size */
1678 iw = w - cw->client_inset.l - cw->client_inset.r;
1679 ih = h - cw->client_inset.t - cw->client_inset.b;
1680 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1682 /* prevent resizing while maximized depending on direction and config */
1683 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1685 Eina_Bool reject = EINA_FALSE;
1686 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1688 if (cw->ec->client.h != ih)
1690 cw->ec->saved.h = ih;
1691 cw->ec->saved.y = cw->ec->client.y - zone->y;
1692 reject = cw->ec->changes.need_unmaximize = 1;
1695 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1697 if (cw->ec->client.w != iw)
1699 cw->ec->saved.w = iw;
1700 cw->ec->saved.x = cw->ec->client.x - zone->x;
1701 reject = cw->ec->changes.need_unmaximize = 1;
1710 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1712 /* do nothing until client idler loops */
1713 if ((cw->ec->w != w) || (cw->ec->h != h))
1715 e_client_size_set(cw->ec, w, h);
1716 cw->ec->changes.size = 1;
1721 if (e_client_pending_geometry_has(cw->ec))
1723 /* do nothing while waiting paired commit serial*/
1727 e_client_size_set(cw->ec, w, h);
1729 cw->ec->client.w = iw;
1730 cw->ec->client.h = ih;
1731 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1733 /* The size of non-compositing window can be changed, so there is a
1734 * need to check that cw is H/W composited if cw is not redirected.
1735 * And of course we have to change size of evas object of H/W composited cw,
1736 * otherwise cw can't receive input events even if it is shown on the screen.
1738 Eina_Bool redirected = cw->redirected;
1740 redirected = e_comp_is_on_overlay(cw->ec);
1742 if ((!cw->ec->input_only) && (redirected) &&
1743 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1744 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1745 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1746 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1749 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1750 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1752 prev_w = cw->w, prev_h = cw->h;
1753 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1754 /* check shading and clamp to pixmap size for regular clients */
1755 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1756 (((w - fw != pw) || (h - fh != ph))))
1758 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1759 evas_object_smart_callback_call(obj, "client_resize", NULL);
1761 if (cw->frame_object || cw->ec->input_only)
1762 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1765 if ((cw->w == w) && (cw->h == h))
1767 /* going to be a noop resize which won't trigger smart resize */
1768 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1769 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1771 evas_object_resize(obj, w, h);
1775 evas_object_smart_callback_call(obj, "client_resize", NULL);
1778 if ((!cw->frame_object) && (!cw->ec->input_only))
1780 /* "just do it" for overrides */
1781 evas_object_resize(obj, w, h);
1783 if (!cw->ec->override)
1785 /* shape probably changed for non-overrides */
1790 /* this fixes positioning jiggles when using a resize mode
1791 * which also changes the client's position
1794 if (cw->frame_object)
1795 x = cw->x, y = cw->y;
1797 x = cw->ec->x, y = cw->ec->y;
1798 switch (cw->ec->resize_mode)
1800 case E_POINTER_RESIZE_BL:
1801 case E_POINTER_RESIZE_L:
1802 evas_object_move(obj, x + prev_w - cw->w, y);
1804 case E_POINTER_RESIZE_TL:
1805 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1807 case E_POINTER_RESIZE_T:
1808 case E_POINTER_RESIZE_TR:
1809 evas_object_move(obj, x, y + prev_h - cw->h);
1818 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1820 #ifdef REFACTOR_DESK_AREA
1821 E_Comp_Object *cw = data;
1822 E_Comp_Object_Data_Set_Layer layer_set_data;
1824 layer_set_data.cw = cw;
1825 layer_set_data.layer = layer;
1827 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1831 e_comp_render_queue();
1832 _e_comp_object_transform_obj_stack_update(obj);
1836 E_Comp_Object *cw = data;
1837 E_Comp_Wl_Client_Data *child_cdata;
1838 unsigned int l = e_comp_canvas_layer_map(layer);
1841 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1843 /* doing a compositor effect, follow directions */
1844 _e_comp_object_layer_set(obj, layer);
1845 if (layer == cw->ec->layer) //trying to put layer back
1849 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1850 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1851 if (cw->layer != l) goto layer_set;
1855 e_comp_render_queue();
1857 ec = e_client_above_get(cw->ec);
1858 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1859 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1860 ec = e_client_above_get(ec);
1861 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1863 ec = e_client_below_get(cw->ec);
1864 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1865 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1866 ec = e_client_below_get(ec);
1867 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1869 evas_object_stack_above(obj, ec->frame);
1874 if (ec && (cw->ec->parent == ec))
1876 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1877 evas_object_stack_above(obj, ec->frame);
1879 evas_object_stack_below(obj, ec->frame);
1882 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1888 if (cw->layer == l) return;
1889 if (e_comp_canvas_client_layer_map(layer) == 9999)
1890 return; //invalid layer for clients not doing comp effects
1891 if (cw->ec->fullscreen)
1893 cw->ec->saved.layer = layer;
1896 oldraise = e_config->transient.raise;
1898 /* clamp to valid client layer */
1899 layer = e_comp_canvas_client_layer_map_nearest(layer);
1900 cw->ec->layer = layer;
1901 if (e_config->transient.layer)
1904 Eina_List *list = eina_list_clone(cw->ec->transients);
1906 /* We need to set raise to one, else the child wont
1907 * follow to the new layer. It should be like this,
1908 * even if the user usually doesn't want to raise
1911 e_config->transient.raise = 1;
1912 EINA_LIST_FREE(list, child)
1914 child_cdata = e_client_cdata_get(child);
1915 if (child_cdata && !child_cdata->mapped)
1917 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1920 e_client_layer_set(child, layer);
1924 e_config->transient.raise = oldraise;
1926 _e_comp_object_layers_remove(cw);
1927 cw->layer = e_comp_canvas_layer_map(layer);
1928 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1929 //if (cw->ec->new_client)
1930 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1931 _e_comp_object_layer_set(obj, layer);
1932 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1933 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1934 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1936 /* can't stack a client above its own layer marker */
1937 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1939 if (!cw->visible) return;
1940 e_comp_render_queue();
1941 _e_comp_object_transform_obj_stack_update(obj);
1945 #ifdef REFACTOR_DESK_AREA
1947 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1950 #ifdef REFACTOR_DESK_AREA
1952 _e_comp_object_raise(Evas_Object *obj)
1955 _e_comp_object_raise(Evas_Object *obj)
1958 evas_object_raise(obj);
1960 if (evas_object_smart_smart_get(obj))
1962 E_Client *ec = e_comp_object_client_get(obj);
1964 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1968 #ifdef REFACTOR_DESK_AREA
1970 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1973 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1976 evas_object_lower(obj);
1978 if (evas_object_smart_smart_get(obj))
1980 E_Client *ec = e_comp_object_client_get(obj);
1983 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1984 #ifdef REFACTOR_DESK_AREA
1985 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1987 wl_signal_emit_mutable(&cw->events.lower, NULL);
1993 #ifdef REFACTOR_DESK_AREA
1995 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1998 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2001 evas_object_stack_above(obj, target);
2003 if (evas_object_smart_smart_get(obj))
2005 E_Client *ec = e_comp_object_client_get(obj);
2007 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2011 #ifdef REFACTOR_DESK_AREA
2013 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2016 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2019 evas_object_stack_below(obj, target);
2021 if (evas_object_smart_smart_get(obj))
2023 E_Client *ec = e_comp_object_client_get(obj);
2025 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2029 #ifdef REFACTOR_DESK_AREA
2031 e_comp_object_layer_set(Evas_Object *obj, short layer)
2034 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2037 evas_object_layer_set(obj, layer);
2039 if (evas_object_smart_smart_get(obj))
2041 E_Client *ec = e_comp_object_client_get(obj);
2043 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2047 #ifdef REFACTOR_DESK_AREA
2050 _e_comp_object_is_pending(E_Client *ec)
2054 if (!ec) return EINA_FALSE;
2056 topmost = e_comp_wl_topmost_parent_get(ec);
2058 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2062 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2064 E_Comp_Object *cw2 = NULL;
2067 Evas_Object *o = stack;
2068 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2070 /* We should consider topmost's layer_pending for subsurface */
2071 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2073 if (_e_comp_object_is_pending(cw->ec))
2074 e_comp_object_layer_update(cw->smart_obj,
2075 raising? stack : NULL,
2076 raising? NULL : stack);
2078 /* obey compositor effects! */
2079 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2080 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2081 stack_cb(cw->smart_obj, stack);
2082 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2083 evas_object_data_del(cw->smart_obj, "client_restack");
2087 cw2 = evas_object_data_get(o, "comp_obj");
2089 /* assume someone knew what they were doing during client init */
2090 if (cw->ec->new_client)
2091 layer = cw->ec->layer;
2092 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2093 layer = cw2->ec->layer;
2095 layer = evas_object_layer_get(stack);
2096 ecstack = e_client_below_get(cw->ec);
2097 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2099 evas_object_layer_set(cw->smart_obj, layer);
2100 /* we got our layer wrangled, return now! */
2101 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2104 /* check if we're stacking below another client */
2107 /* check for non-client layer object */
2108 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2110 /* find an existing client to use for layering
2111 * by walking up the object stack
2113 * this is guaranteed to be pretty quick since we'll either:
2114 * - run out of client layers
2115 * - find a stacking client
2117 o = evas_object_above_get(o);
2118 if ((!o) || (o == cw->smart_obj)) break;
2119 if (evas_object_layer_get(o) != layer)
2121 /* reached the top client layer somehow
2122 * use top client object
2124 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2127 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2128 * return here since the top client layer window
2133 ec = e_client_top_get();
2138 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2141 if (cw2 && cw->layer != cw2->layer)
2144 /* remove existing layers */
2145 _e_comp_object_layers_remove(cw);
2148 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2149 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2150 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2151 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2152 else //if no stacking objects found, either raise or lower
2153 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2156 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2158 /* find new object for stacking if cw2 is on state of layer_pending */
2159 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2161 E_Client *new_stack = NULL, *current_ec = NULL;
2162 current_ec = cw2->ec;
2165 while ((new_stack = e_client_below_get(current_ec)))
2167 current_ec = new_stack;
2168 if (new_stack == cw->ec) continue;
2169 if (new_stack->layer != cw2->ec->layer) break;
2170 if (!_e_comp_object_is_pending(new_stack)) break;
2172 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2173 stack = new_stack->frame;
2176 /* stack it above layer object */
2178 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2179 stack = e_comp->layers[below_layer].obj;
2184 while ((new_stack = e_client_above_get(current_ec)))
2186 current_ec = new_stack;
2187 if (new_stack == cw->ec) continue;
2188 if (new_stack->layer != cw2->ec->layer) break;
2189 if (!_e_comp_object_is_pending(new_stack)) break;
2191 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2192 stack = new_stack->frame;
2194 stack = e_comp->layers[cw2->layer].obj;
2198 /* set restack if stacking has changed */
2199 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2200 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2201 stack_cb(cw->smart_obj, stack);
2202 if (e_comp->layers[cw->layer].obj)
2203 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2205 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2207 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2208 evas_object_data_del(cw->smart_obj, "client_restack");
2209 if (!cw->visible) return;
2210 e_comp_render_queue();
2215 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2217 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2219 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2221 #ifdef REFACTOR_DESK_AREA
2222 E_Comp_Object *cw = data;
2223 E_Comp_Object_Data_Stack_Above stack_above_data;
2225 stack_above_data.cw = cw;
2226 stack_above_data.above_obj = above;
2228 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2230 if (evas_object_below_get(obj) == above)
2232 e_comp_object_layer_update(obj, above, NULL);
2236 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2238 _e_comp_object_transform_obj_stack_update(obj);
2239 _e_comp_object_transform_obj_stack_update(above);
2246 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2248 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2250 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2252 #ifdef REFACTOR_DESK_AREA
2253 E_Comp_Object *cw = data;
2254 E_Comp_Object_Data_Stack_Below stack_below_data;
2256 stack_below_data.cw = cw;
2257 stack_below_data.below_obj = below;
2259 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2262 e_comp_render_queue();
2264 if (evas_object_above_get(obj) == below)
2266 e_comp_object_layer_update(obj, NULL, below);
2270 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2272 if (evas_object_smart_smart_get(obj))
2273 _e_comp_object_transform_obj_stack_update(obj);
2274 if (evas_object_smart_smart_get(below))
2275 _e_comp_object_transform_obj_stack_update(below);
2282 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2284 E_Comp_Object *cw = data;
2286 #ifdef REFACTOR_DESK_AREA
2291 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2293 #ifdef REFACTOR_DESK_AREA
2294 wl_signal_emit_mutable(&cw->events.lower, cw);
2296 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2298 if (cw->ec->layer_pending)
2299 e_comp_object_layer_update(obj, NULL, obj);
2301 _e_comp_object_lower(cw, obj);
2304 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2305 o = evas_object_below_get(obj);
2306 _e_comp_object_layers_remove(cw);
2307 /* prepend to client list since this client should be the first item now */
2308 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2309 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2310 evas_object_data_set(obj, "client_restack", (void*)1);
2311 _e_comp_object_lower(cw, obj);
2312 evas_object_data_del(obj, "client_restack");
2313 if (!cw->visible) goto end;
2314 e_comp_render_queue();
2315 _e_comp_object_transform_obj_stack_update(obj);
2323 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2325 E_Comp_Object *cw = data;
2326 #ifdef REFACTOR_DESK_AREA
2332 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2334 #ifdef REFACTOR_DESK_AREA
2335 wl_signal_emit_mutable(&cw->events.raise, cw);
2337 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2339 if (cw->ec->layer_pending)
2341 int obj_layer = evas_object_layer_get(obj);
2342 if (cw->ec->layer != obj_layer)
2343 e_comp_object_layer_update(obj, NULL, NULL);
2346 _e_comp_object_raise(obj);
2349 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2350 o = evas_object_above_get(obj);
2351 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2353 /* still stack below override below the layer marker */
2354 for (op = o = e_comp->layers[cw->layer].obj;
2355 o && o != e_comp->layers[cw->layer - 1].obj;
2356 op = o, o = evas_object_below_get(o))
2358 if (evas_object_smart_smart_get(o))
2362 ec = e_comp_object_client_get(o);
2363 if (ec && (!ec->override)) break;
2366 _e_comp_object_stack_below(obj, op);
2367 e_client_focus_defer_set(cw->ec);
2369 if (!cw->visible) goto end;
2370 e_comp_render_queue();
2371 _e_comp_object_transform_obj_stack_update(obj);
2379 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2381 E_Comp_Object *cw = data;
2383 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2384 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2386 ELOGF("COMP", "Hide. intercepted", cw->ec);
2391 if (cw->ec->launching == EINA_TRUE)
2393 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2394 cw->ec->launching = EINA_FALSE;
2399 /* hidden flag = just do it */
2400 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2401 evas_object_hide(obj);
2403 wl_signal_emit_mutable(&cw->events.hide, NULL);
2408 if (cw->ec->input_only)
2410 /* input_only = who cares */
2411 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2412 evas_object_hide(obj);
2414 wl_signal_emit_mutable(&cw->events.hide, NULL);
2418 /* already hidden or currently animating */
2419 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2421 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2425 /* don't try hiding during shutdown */
2426 cw->defer_hide |= stopping;
2427 if (!cw->defer_hide)
2429 if ((!cw->ec->iconic) && (!cw->ec->override))
2430 /* unset delete requested so the client doesn't break */
2431 cw->ec->delete_requested = 0;
2432 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2434 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2435 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2438 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2441 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2443 _e_comp_object_animating_begin(cw);
2444 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2446 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2447 cw->defer_hide = !!cw->animating;
2449 e_comp_object_effect_set(obj, NULL);
2452 if (cw->animating) return;
2453 /* if we have no animations running, go ahead and hide */
2455 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2456 evas_object_hide(obj);
2458 wl_signal_emit_mutable(&cw->events.hide, NULL);
2462 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2464 E_Client *ec = cw->ec;
2467 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2469 if (ec->show_pending.count > 0)
2471 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2472 ec->show_pending.running = EINA_TRUE;
2476 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2477 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2479 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2484 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,
2485 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2486 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2489 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2492 if (ec->iconic && cw->animating)
2494 /* triggered during iconify animation */
2495 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2498 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2501 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2502 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2504 evas_object_move(cw->smart_obj, ec->x, ec->y);
2505 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2506 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2508 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2509 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2512 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2513 evas_object_show(cw->smart_obj);
2516 e_client_focus_defer_set(ec);
2520 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2524 pw = ec->client.w, ph = ec->client.h;
2526 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2528 ec->changes.visible = !ec->hidden;
2531 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2535 cw->updates = eina_tiler_new(pw, ph);
2538 ec->changes.visible = !ec->hidden;
2541 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2546 eina_tiler_tile_size_set(cw->updates, 1, 1);
2549 /* ignore until client idler first run */
2550 ec->changes.visible = !ec->hidden;
2553 ELOGF("COMP", "show_helper. return. new_client", ec);
2560 evas_object_move(cw->smart_obj, ec->x, ec->y);
2561 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2562 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2563 evas_object_show(cw->smart_obj);
2566 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2568 /* start_drag not received */
2569 ec->changes.visible = 1;
2572 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2575 /* re-set geometry */
2576 evas_object_move(cw->smart_obj, ec->x, ec->y);
2577 /* force resize in case it hasn't happened yet, or just to update size */
2578 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2579 if ((cw->w < 1) || (cw->h < 1))
2581 /* if resize didn't go through, try again */
2582 ec->visible = ec->changes.visible = 1;
2584 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2587 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2588 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2589 e_pixmap_clear(ec->pixmap);
2591 if (cw->real_hid && w && h)
2594 /* force comp theming in case it didn't happen already */
2595 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2596 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2597 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2600 /* only do the show if show is allowed */
2603 if (ec->internal) //internal clients render when they feel like it
2604 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2606 if (!e_client_is_iconified_by_client(ec)||
2607 e_policy_visibility_client_is_uniconic(ec))
2609 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2610 evas_object_show(cw->smart_obj);
2612 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2613 it is rendered in idle callback without native surface and
2614 compositor shows an empty frame if other objects aren't shown
2615 because job callback of e_comp called at the next loop.
2616 it causes a visual defect when windows are switched.
2620 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2621 e_comp_object_dirty(cw->smart_obj);
2622 e_comp_object_render(cw->smart_obj);
2627 wl_signal_emit_mutable(&cw->events.show, NULL);
2631 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2633 E_Comp_Object *cw = data;
2634 E_Client *ec = cw->ec;
2636 E_Input_Rect_Data *input_rect_data;
2637 E_Input_Rect_Smart_Data *input_rect_sd;
2640 if (ec->ignored) return;
2644 //INF("SHOW2 %p", ec);
2645 _e_comp_intercept_show_helper(cw);
2648 //INF("SHOW %p", ec);
2651 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2652 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2653 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2654 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2658 if ((!cw->obj) && (cw->external_content))
2660 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2664 _e_comp_object_setup(cw);
2667 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2668 cw->obj = evas_object_image_filled_add(e_comp->evas);
2669 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2670 e_util_size_debug_set(cw->obj, 1);
2671 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2672 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2673 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2674 evas_object_name_set(cw->obj, "cw->obj");
2675 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2677 _e_comp_object_alpha_set(cw);
2680 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2683 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2684 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2687 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2690 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2692 if (input_rect_data->obj)
2694 evas_object_geometry_set(input_rect_data->obj,
2695 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2696 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2697 input_rect_data->rect.w, input_rect_data->rect.h);
2704 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2706 _e_comp_intercept_show_helper(cw);
2710 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2712 E_Comp_Object *cw = data;
2716 /* note: this is here as it seems there are enough apps that do not even
2717 * expect us to emulate a look of focus but not actually set x input
2718 * focus as we do - so simply abort any focus set on such windows */
2719 /* be strict about accepting focus hint */
2720 /* be strict about accepting focus hint */
2721 if ((!ec->icccm.accepts_focus) &&
2722 (!ec->icccm.take_focus))
2726 if (e_client_focused_get() == ec)
2727 e_client_focused_set(NULL);
2729 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2730 evas_object_focus_set(obj, focus);
2734 if (focus && ec->lock_focus_out) return;
2735 if (e_object_is_del(E_OBJECT(ec)) && focus)
2736 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2738 /* filter focus setting based on current state */
2743 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2744 evas_object_focus_set(obj, focus);
2747 if ((ec->iconic) && (!ec->deskshow))
2749 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2751 /* don't focus an iconified window. that's silly! */
2752 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2753 e_client_uniconify(ec);
2754 e_client_focus_latest_set(ec);
2768 /* not yet visible, wait till the next time... */
2769 ec->want_focus = !ec->hidden;
2774 e_client_focused_set(ec);
2778 if (e_client_focused_get() == ec)
2779 e_client_focused_set(NULL);
2783 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2785 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2787 evas_object_focus_set(obj, focus);
2791 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2793 E_Comp_Object *cw = data;
2795 if (cw->transparent.set)
2797 cw->transparent.user_r = r;
2798 cw->transparent.user_g = g;
2799 cw->transparent.user_b = b;
2800 cw->transparent.user_a = a;
2802 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2804 cw->transparent.user_r,
2805 cw->transparent.user_g,
2806 cw->transparent.user_b,
2807 cw->transparent.user_a);
2811 evas_object_color_set(obj, r, g, b, a);
2814 ////////////////////////////////////////////////////
2817 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2819 int w, h, ox, oy, ow, oh;
2821 Eina_Bool pass_event_flag = EINA_FALSE;
2822 E_Input_Rect_Data *input_rect_data;
2823 E_Input_Rect_Smart_Data *input_rect_sd;
2825 if (cw->frame_object)
2827 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2828 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2829 /* set a fixed size, force edje calc, check size difference */
2830 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2831 edje_object_message_signal_process(cw->frame_object);
2832 edje_object_calc_force(cw->frame_object);
2833 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2834 cw->client_inset.l = ox;
2835 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2836 cw->client_inset.t = oy;
2837 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2838 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2839 evas_object_resize(cw->frame_object, w, h);
2843 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2846 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2848 if (input_rect_data->obj)
2850 pass_event_flag = EINA_TRUE;
2856 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2857 evas_object_pass_events_set(cw->obj, pass_event_flag);
2861 cw->client_inset.l = 0;
2862 cw->client_inset.r = 0;
2863 cw->client_inset.t = 0;
2864 cw->client_inset.b = 0;
2866 cw->client_inset.calc = !!cw->frame_object;
2870 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2872 E_Comp_Object *cw = data;
2876 /* - get current size
2878 * - readjust for new frame size
2881 w = cw->ec->w, h = cw->ec->h;
2882 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2884 _e_comp_object_frame_recalc(cw);
2886 if (!cw->ec->fullscreen)
2887 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2889 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2890 if (cw->ec->fullscreen)
2892 zone = e_comp_zone_find_by_ec(cw->ec);
2894 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2896 else if (cw->ec->new_client)
2898 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2899 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2900 evas_object_resize(cw->ec->frame, w, h);
2902 else if ((w != cw->ec->w) || (h != cw->ec->h))
2903 evas_object_resize(cw->ec->frame, w, h);
2907 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2909 E_Comp_Object *cw = data;
2911 _e_comp_object_shadow_setup(cw);
2912 if (cw->frame_object)
2914 _e_comp_object_shadow(cw);
2915 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2916 _e_comp_object_frame_recalc(cw);
2917 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2922 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2924 E_Comp_Object *cw = data;
2926 if (_e_comp_object_shadow_setup(cw))
2927 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2928 if (cw->frame_object)
2930 _e_comp_object_shadow(cw);
2931 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2932 _e_comp_object_frame_recalc(cw);
2933 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2938 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2940 E_Comp_Object *cw = data;
2942 if (cw->frame_object)
2944 _e_comp_object_shadow(cw);
2945 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2946 _e_comp_object_frame_recalc(cw);
2947 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2952 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2954 E_Comp_Object *cw = data;
2956 if (_e_comp_object_shadow_setup(cw))
2959 cw->ec->changes.size = 1;
2961 if (cw->frame_object)
2963 _e_comp_object_shadow(cw);
2964 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2965 _e_comp_object_frame_recalc(cw);
2966 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2971 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2973 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2977 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2979 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2983 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2985 E_Comp_Object *cw = data;
2987 if (!cw->ec) return; //NYI
2988 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2992 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2994 E_Comp_Object *cw = data;
2996 if (!cw->ec) return; //NYI
2997 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3001 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3003 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3007 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3009 E_Comp_Object *cw = data;
3011 if (!e_object_is_del(E_OBJECT(cw->ec)))
3012 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3016 _e_comp_input_obj_smart_add(Evas_Object *obj)
3018 E_Input_Rect_Smart_Data *input_rect_sd;
3019 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3021 if (!input_rect_sd) return;
3022 evas_object_smart_data_set(obj, input_rect_sd);
3026 _e_comp_input_obj_smart_del(Evas_Object *obj)
3028 E_Input_Rect_Smart_Data *input_rect_sd;
3029 E_Input_Rect_Data *input_rect_data;
3031 input_rect_sd = evas_object_smart_data_get(obj);
3032 if (!input_rect_sd) return;
3034 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3036 if (input_rect_data->obj)
3038 evas_object_smart_member_del(input_rect_data->obj);
3039 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3041 E_FREE(input_rect_data);
3043 E_FREE(input_rect_sd);
3047 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3049 E_Input_Rect_Smart_Data *input_rect_sd;
3050 E_Input_Rect_Data *input_rect_data;
3054 input_rect_sd = evas_object_smart_data_get(obj);
3055 if (!input_rect_sd) return;
3057 cw = input_rect_sd->cw;
3058 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3060 if (input_rect_data->obj)
3062 evas_object_geometry_set(input_rect_data->obj,
3063 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3064 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3065 input_rect_data->rect.w, input_rect_data->rect.h);
3071 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3073 E_Input_Rect_Smart_Data *input_rect_sd;
3074 E_Input_Rect_Data *input_rect_data;
3078 input_rect_sd = evas_object_smart_data_get(obj);
3079 if (!input_rect_sd) return;
3081 cw = input_rect_sd->cw;
3082 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3084 if (input_rect_data->obj)
3086 evas_object_geometry_set(input_rect_data->obj,
3087 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3088 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3089 input_rect_data->rect.w, input_rect_data->rect.h);
3095 _e_comp_input_obj_smart_show(Evas_Object *obj)
3097 E_Input_Rect_Smart_Data *input_rect_sd;
3098 E_Input_Rect_Data *input_rect_data;
3101 input_rect_sd = evas_object_smart_data_get(obj);
3102 if (!input_rect_sd) return;
3104 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3106 if (input_rect_data->obj)
3108 evas_object_show(input_rect_data->obj);
3114 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3116 E_Input_Rect_Smart_Data *input_rect_sd;
3117 E_Input_Rect_Data *input_rect_data;
3120 input_rect_sd = evas_object_smart_data_get(obj);
3121 if (!input_rect_sd) return;
3123 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3125 if (input_rect_data->obj)
3127 evas_object_hide(input_rect_data->obj);
3133 _e_comp_input_obj_smart_init(void)
3135 if (_e_comp_input_obj_smart) return;
3137 static const Evas_Smart_Class sc =
3139 INPUT_OBJ_SMART_NAME,
3140 EVAS_SMART_CLASS_VERSION,
3141 _e_comp_input_obj_smart_add,
3142 _e_comp_input_obj_smart_del,
3143 _e_comp_input_obj_smart_move,
3144 _e_comp_input_obj_smart_resize,
3145 _e_comp_input_obj_smart_show,
3146 _e_comp_input_obj_smart_hide,
3159 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3165 _e_comp_smart_add(Evas_Object *obj)
3169 cw = E_NEW(E_Comp_Object, 1);
3170 EINA_SAFETY_ON_NULL_RETURN(cw);
3172 wl_signal_init(&cw->events.lower);
3173 #ifdef REFACTOR_DESK_AREA
3174 wl_signal_init(&cw->events.lower_done);
3175 wl_signal_init(&cw->events.raise);
3177 wl_signal_init(&cw->events.show);
3178 wl_signal_init(&cw->events.hide);
3179 #ifdef REFACTOR_DESK_AREA
3180 wl_signal_init(&cw->events.set_layer);
3181 wl_signal_init(&cw->events.stack_above);
3182 wl_signal_init(&cw->events.stack_below);
3185 cw->smart_obj = obj;
3186 cw->x = cw->y = cw->w = cw->h = -1;
3187 evas_object_smart_data_set(obj, cw);
3188 cw->opacity = 255.0;
3189 cw->external_content = 0;
3190 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3191 cw->transform_bg_color.r = 0;
3192 cw->transform_bg_color.g = 0;
3193 cw->transform_bg_color.b = 0;
3194 cw->transform_bg_color.a = 255;
3195 evas_object_data_set(obj, "comp_obj", cw);
3196 evas_object_move(obj, -1, -1);
3197 /* intercept ALL the callbacks! */
3198 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3199 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3200 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3201 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3202 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3203 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3204 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3205 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3206 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3207 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3208 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3210 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3211 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3212 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3213 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3215 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3216 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3218 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3219 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3221 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3223 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3224 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3228 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3231 evas_object_color_set(cw->clip, r, g, b, a);
3232 evas_object_smart_callback_call(obj, "color_set", NULL);
3237 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3240 evas_object_clip_set(cw->clip, clip);
3244 _e_comp_smart_clip_unset(Evas_Object *obj)
3247 evas_object_clip_unset(cw->clip);
3251 _e_comp_smart_hide(Evas_Object *obj)
3253 TRACE_DS_BEGIN(COMP:SMART HIDE);
3258 evas_object_hide(cw->clip);
3259 if (cw->input_obj) evas_object_hide(cw->input_obj);
3260 evas_object_hide(cw->effect_obj);
3261 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3262 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3263 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3270 /* unset native surface if current displaying buffer was destroied */
3271 if (!cw->buffer_destroy_listener.notify)
3273 Evas_Native_Surface *ns;
3274 ns = evas_object_image_native_surface_get(cw->obj);
3275 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3276 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3279 if (!cw->ec->input_only)
3281 edje_object_freeze(cw->effect_obj);
3282 edje_object_freeze(cw->shobj);
3283 edje_object_play_set(cw->shobj, 0);
3284 if (cw->frame_object)
3285 edje_object_play_set(cw->frame_object, 0);
3288 e_comp_render_queue(); //force nocomp recheck
3294 _e_comp_smart_show(Evas_Object *obj)
3302 if ((cw->w < 0) || (cw->h < 0))
3303 CRI("ACK! ec:%p", cw->ec);
3305 TRACE_DS_BEGIN(COMP:SMART SHOW);
3307 e_comp_object_map_update(obj);
3309 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3310 evas_object_show(tmp->frame);
3312 evas_object_show(cw->clip);
3313 if (cw->input_obj) evas_object_show(cw->input_obj);
3314 if (!cw->ec->input_only)
3316 edje_object_thaw(cw->effect_obj);
3317 edje_object_thaw(cw->shobj);
3318 edje_object_play_set(cw->shobj, 1);
3319 if (cw->frame_object)
3320 edje_object_play_set(cw->frame_object, 1);
3322 evas_object_show(cw->effect_obj);
3323 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3324 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3325 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3326 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3327 e_comp_render_queue();
3328 if (cw->ec->input_only)
3333 if (cw->ec->iconic && (!cw->ec->new_client))
3335 if (e_client_is_iconified_by_client(cw->ec))
3337 ELOGF("COMP", "Set launching flag..", cw->ec);
3338 cw->ec->launching = EINA_TRUE;
3341 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3343 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3346 ELOGF("COMP", "Set launching flag..", cw->ec);
3347 cw->ec->launching = EINA_TRUE;
3349 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3350 _e_comp_object_animating_begin(cw);
3351 if (!_e_comp_object_effect_visibility_start(cw, 1))
3357 /* ensure some random effect doesn't lock the client offscreen */
3361 e_comp_object_effect_set(obj, NULL);
3364 _e_comp_object_dim_update(cw);
3370 _e_comp_smart_del(Evas_Object *obj)
3376 if (cw->buffer_destroy_listener.notify)
3378 wl_list_remove(&cw->buffer_destroy_listener.link);
3379 cw->buffer_destroy_listener.notify = NULL;
3382 if (cw->tbm_surface)
3384 tbm_surface_internal_unref(cw->tbm_surface);
3385 cw->tbm_surface = NULL;
3388 if (cw->render_update_lock.buffer_ref.buffer)
3390 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3391 cw->ec, cw->render_update_lock.lock);
3392 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3395 e_comp_object_render_update_del(cw->smart_obj);
3396 E_FREE_FUNC(cw->updates, eina_tiler_free);
3397 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3404 EINA_LIST_FREE(cw->obj_mirror, o)
3406 evas_object_image_data_set(o, NULL);
3407 evas_object_freeze_events_set(o, 1);
3408 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3412 #ifdef REFACTOR_DESK_AREA
3414 _e_comp_object_layers_remove(cw);
3416 l = evas_object_data_get(obj, "comp_object-to_del");
3417 E_FREE_LIST(l, evas_object_del);
3418 _e_comp_object_mouse_event_callback_unset(cw);
3419 evas_object_del(cw->clip);
3420 evas_object_del(cw->obj);
3421 evas_object_del(cw->shobj);
3422 evas_object_del(cw->effect_obj);
3423 evas_object_del(cw->frame_object);
3424 evas_object_del(cw->input_obj);
3425 evas_object_del(cw->mask.obj);
3426 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3427 evas_object_del(cw->transform_bg_obj);
3428 evas_object_del(cw->transform_tranp_obj);
3429 evas_object_del(cw->default_input_obj);
3430 eina_stringshare_del(cw->frame_theme);
3431 eina_stringshare_del(cw->frame_name);
3435 e_comp->animating--;
3437 e_object_unref(E_OBJECT(cw->ec));
3439 cw->ec->frame = NULL;
3444 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3448 cw->x = x, cw->y = y;
3449 evas_object_move(cw->effect_obj, x, y);
3450 evas_object_move(cw->default_input_obj, x, y);
3451 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3453 e_comp_object_map_update(obj);
3457 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3459 Eina_Bool first = EINA_FALSE;
3464 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3466 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3468 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3470 if (cw->w != w || cw->h != h)
3471 e_comp_object_map_update(obj);
3473 first = ((cw->w < 1) || (cw->h < 1));
3474 cw->w = w, cw->h = h;
3478 if (cw->frame_object)
3479 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3482 /* verify pixmap:object size */
3483 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3485 if ((ww != pw) || (hh != ph))
3486 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3488 evas_object_resize(cw->effect_obj, tw, th);
3489 evas_object_resize(cw->default_input_obj, w, h);
3491 evas_object_resize(cw->input_obj, w, h);
3493 evas_object_resize(cw->mask.obj, w, h);
3494 /* resize render update tiler */
3497 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3498 cw->updates_full = 0;
3499 if (cw->updates) eina_tiler_clear(cw->updates);
3503 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3504 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3512 e_comp_render_queue();
3518 _e_comp_smart_init(void)
3520 if (_e_comp_smart) return;
3522 static const Evas_Smart_Class sc =
3525 EVAS_SMART_CLASS_VERSION,
3529 _e_comp_smart_resize,
3532 _e_comp_smart_color_set,
3533 _e_comp_smart_clip_set,
3534 _e_comp_smart_clip_unset,
3544 _e_comp_smart = evas_smart_class_new(&sc);
3549 e_comp_object_init(void)
3551 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3552 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3553 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3554 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3558 e_comp_object_shutdown(void)
3564 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3566 API_ENTRY EINA_FALSE;
3567 return !!cw->force_visible;
3569 /////////////////////////////////////////////////////////
3572 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3575 Eina_Bool comp_object;
3577 comp_object = !!evas_object_data_get(obj, "comp_object");
3582 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3584 e_comp_render_queue();
3586 l = evas_object_data_get(obj, "comp_object-to_del");
3587 E_FREE_LIST(l, evas_object_del);
3591 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3593 if (e_comp_util_object_is_above_nocomp(obj) &&
3594 (!evas_object_data_get(obj, "comp_override")))
3596 evas_object_data_set(obj, "comp_override", (void*)1);
3597 e_comp_override_add();
3602 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3604 Eina_Bool ref = EINA_TRUE;
3605 if (evas_object_visible_get(obj))
3609 d = evas_object_data_del(obj, "comp_hiding");
3611 /* currently trying to hide */
3614 /* already visible */
3618 evas_object_show(obj);
3621 evas_object_ref(obj);
3622 evas_object_data_set(obj, "comp_ref", (void*)1);
3624 edje_object_signal_emit(obj, "e,state,visible", "e");
3625 evas_object_data_set(obj, "comp_showing", (void*)1);
3626 if (e_comp_util_object_is_above_nocomp(obj))
3628 evas_object_data_set(obj, "comp_override", (void*)1);
3629 e_comp_override_add();
3634 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3636 if (!evas_object_visible_get(obj)) return;
3637 /* already hiding */
3638 if (evas_object_data_get(obj, "comp_hiding")) return;
3639 if (!evas_object_data_del(obj, "comp_showing"))
3641 evas_object_ref(obj);
3642 evas_object_data_set(obj, "comp_ref", (void*)1);
3644 edje_object_signal_emit(obj, "e,state,hidden", "e");
3645 evas_object_data_set(obj, "comp_hiding", (void*)1);
3647 if (evas_object_data_del(obj, "comp_override"))
3648 e_comp_override_timed_pop();
3652 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3654 if (!e_util_strcmp(emission, "e,action,hide,done"))
3656 if (!evas_object_data_del(obj, "comp_hiding")) return;
3657 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3658 evas_object_hide(obj);
3659 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3662 evas_object_data_del(obj, "comp_showing");
3663 if (evas_object_data_del(obj, "comp_ref"))
3664 evas_object_unref(obj);
3668 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3674 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3678 E_API E_Comp_Object_Hook *
3679 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3681 E_Comp_Object_Hook *ch;
3683 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3684 ch = E_NEW(E_Comp_Object_Hook, 1);
3685 if (!ch) return NULL;
3686 ch->hookpoint = hookpoint;
3688 ch->data = (void*)data;
3689 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3694 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3697 if (_e_comp_object_hooks_walking == 0)
3699 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3703 _e_comp_object_hooks_delete++;
3706 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3707 E_API E_Comp_Object_Intercept_Hook *
3708 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3710 E_Comp_Object_Intercept_Hook *ch;
3712 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3713 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3714 if (!ch) return NULL;
3715 ch->hookpoint = hookpoint;
3717 ch->data = (void*)data;
3718 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3723 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3726 if (_e_comp_object_intercept_hooks_walking == 0)
3728 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3732 _e_comp_object_intercept_hooks_delete++;
3737 e_comp_object_util_add(Evas_Object *obj)
3741 E_Comp_Config *conf = e_comp_config_get();
3742 Eina_Bool skip = EINA_FALSE;
3748 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3750 name = evas_object_name_get(obj);
3751 vis = evas_object_visible_get(obj);
3752 o = edje_object_add(e_comp->evas);
3753 evas_object_data_set(o, "comp_object", (void*)1);
3755 skip = (!strncmp(name, "noshadow", 8));
3757 evas_object_data_set(o, "comp_object_skip", (void*)1);
3759 if (conf->shadow_style)
3761 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3762 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3765 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3766 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3767 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3769 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3771 evas_object_geometry_get(obj, &x, &y, &w, &h);
3772 evas_object_geometry_set(o, x, y, w, h);
3773 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3775 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3777 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3778 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3779 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3780 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3781 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3782 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3784 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3786 edje_object_part_swallow(o, "e.swallow.content", obj);
3788 _e_comp_object_event_add(o);
3791 evas_object_show(o);
3796 /* utility functions for deleting objects when their "owner" is deleted */
3798 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3803 EINA_SAFETY_ON_NULL_RETURN(to_del);
3804 l = evas_object_data_get(obj, "comp_object-to_del");
3805 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3806 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3807 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3811 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3816 EINA_SAFETY_ON_NULL_RETURN(to_del);
3817 l = evas_object_data_get(obj, "comp_object-to_del");
3819 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3822 /////////////////////////////////////////////////////////
3824 EINTERN Evas_Object *
3825 e_comp_object_client_add(E_Client *ec)
3830 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3831 if (ec->frame) return NULL;
3832 _e_comp_smart_init();
3833 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3834 cw = evas_object_smart_data_get(o);
3835 if (!cw) return NULL;
3836 evas_object_data_set(o, "E_Client", ec);
3839 evas_object_data_set(o, "comp_object", (void*)1);
3841 _e_comp_object_event_add(o);
3846 /* utility functions for getting client inset */
3848 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3851 if (!cw->client_inset.calc)
3857 if (ax) *ax = x - cw->client_inset.l;
3858 if (ay) *ay = y - cw->client_inset.t;
3862 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3865 if (!cw->client_inset.calc)
3871 if (ax) *ax = x + cw->client_inset.l;
3872 if (ay) *ay = y + cw->client_inset.t;
3876 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3879 if (!cw->client_inset.calc)
3885 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3886 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3890 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3893 if (!cw->client_inset.calc)
3899 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3900 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3904 e_comp_object_client_get(Evas_Object *obj)
3909 /* FIXME: remove this when eo is used */
3910 o = evas_object_data_get(obj, "comp_smart_obj");
3912 return e_comp_object_client_get(o);
3913 return cw ? cw->ec : NULL;
3917 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3920 if (cw->frame_extends)
3921 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3926 if (w) *w = cw->ec->w;
3927 if (h) *h = cw->ec->h;
3932 e_comp_object_util_zone_get(Evas_Object *obj)
3934 E_Zone *zone = NULL;
3938 zone = e_comp_zone_find_by_ec(cw->ec);
3943 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3944 zone = e_comp_zone_xy_get(x, y);
3950 e_comp_object_util_center(Evas_Object *obj)
3952 int x, y, w, h, ow, oh;
3957 zone = e_comp_object_util_zone_get(obj);
3958 EINA_SAFETY_ON_NULL_RETURN(zone);
3959 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3960 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3961 ow = cw->ec->w, oh = cw->ec->h;
3963 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3964 x = x + (w - ow) / 2;
3965 y = y + (h - oh) / 2;
3966 evas_object_move(obj, x, y);
3970 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3972 int x, y, w, h, ow, oh;
3975 EINA_SAFETY_ON_NULL_RETURN(on);
3976 evas_object_geometry_get(on, &x, &y, &w, &h);
3977 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3978 ow = cw->ec->w, oh = cw->ec->h;
3980 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3981 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3985 e_comp_object_util_fullscreen(Evas_Object *obj)
3990 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3993 evas_object_move(obj, 0, 0);
3994 evas_object_resize(obj, e_comp->w, e_comp->h);
3999 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4007 ow = cw->w, oh = cw->h;
4009 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4010 zone = e_comp_object_util_zone_get(obj);
4011 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4012 if (x) *x = zx + (zw - ow) / 2;
4013 if (y) *y = zy + (zh - oh) / 2;
4017 e_comp_object_input_objs_del(Evas_Object *obj)
4020 E_Input_Rect_Data *input_rect_data;
4021 E_Input_Rect_Smart_Data *input_rect_sd;
4026 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4027 if (!input_rect_sd) return;
4029 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4031 if (input_rect_data->obj)
4033 evas_object_smart_member_del(input_rect_data->obj);
4034 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4036 E_FREE(input_rect_data);
4041 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4044 E_Input_Rect_Data *input_rect_data = NULL;
4045 E_Input_Rect_Smart_Data *input_rect_sd;
4046 int client_w, client_h;
4048 if (cw->ec->client.w)
4049 client_w = cw->ec->client.w;
4051 client_w = cw->ec->w;
4053 if (cw->ec->client.h)
4054 client_h = cw->ec->client.h;
4056 client_h = cw->ec->h;
4058 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4062 _e_comp_input_obj_smart_init();
4063 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4064 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4065 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4068 input_rect_sd->cw = cw;
4071 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4074 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4075 if (input_rect_data)
4077 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4078 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4082 if ((input_rect_data) &&
4083 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4085 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4086 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4087 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4088 evas_object_clip_set(input_rect_data->obj, cw->clip);
4089 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4090 evas_object_geometry_set(input_rect_data->obj,
4091 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4092 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4093 evas_object_pass_events_set(cw->default_input_obj, 1);
4094 evas_object_pass_events_set(cw->obj, 1);
4097 evas_object_show(input_rect_data->obj);
4098 evas_object_show(cw->input_obj);
4103 evas_object_smart_member_del(cw->input_obj);
4104 E_FREE_FUNC(cw->input_obj, evas_object_del);
4105 evas_object_pass_events_set(cw->default_input_obj, 0);
4106 evas_object_pass_events_set(cw->obj, 0);
4111 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4114 E_Input_Rect_Smart_Data *input_rect_sd;
4115 E_Input_Rect_Data *input_rect_data;
4118 if (!cw->input_obj) return;
4120 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4123 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4125 *list = eina_list_append(*list, &input_rect_data->rect);
4131 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4134 if (l) *l = cw->client_inset.l;
4135 if (r) *r = cw->client_inset.r;
4136 if (t) *t = cw->client_inset.t;
4137 if (b) *b = cw->client_inset.b;
4140 /* set geometry for CSD */
4142 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4148 if (cw->frame_object)
4149 CRI("ACK! ec:%p", cw->ec);
4150 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4151 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4152 calc = cw->client_inset.calc;
4153 cw->client_inset.calc = l || r || t || b;
4154 eina_stringshare_replace(&cw->frame_theme, "borderless");
4155 if (cw->client_inset.calc)
4157 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4158 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4159 e_client_size_set(cw->ec, tw, th);
4161 else if (cw->ec->maximized || cw->ec->fullscreen)
4163 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4164 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4166 if (!cw->ec->new_client)
4168 if (calc && cw->client_inset.calc)
4170 tx = cw->ec->x - (l - cw->client_inset.l);
4171 ty = cw->ec->y - (t - cw->client_inset.t);
4172 e_client_pos_set(cw->ec, tx, ty);
4174 cw->ec->changes.pos = cw->ec->changes.size = 1;
4177 cw->client_inset.l = l;
4178 cw->client_inset.r = r;
4179 cw->client_inset.t = t;
4180 cw->client_inset.b = b;
4184 e_comp_object_frame_allowed(Evas_Object *obj)
4186 API_ENTRY EINA_FALSE;
4187 return (cw->frame_object || (!cw->client_inset.calc));
4191 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4193 API_ENTRY EINA_FALSE;
4194 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4195 eina_stringshare_replace(&cw->frame_name, name);
4196 if (cw->frame_object)
4197 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4202 e_comp_object_frame_exists(Evas_Object *obj)
4204 API_ENTRY EINA_FALSE;
4205 return !!cw->frame_object;
4209 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4211 Evas_Object *o, *pbg;
4214 Eina_Stringshare *theme;
4216 API_ENTRY EINA_FALSE;
4218 if (!e_util_strcmp(cw->frame_theme, name))
4219 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4220 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4221 return _e_comp_object_shadow_setup(cw);
4222 pbg = cw->frame_object;
4223 theme = eina_stringshare_add(name);
4225 if (cw->frame_object)
4229 w = cw->ec->w, h = cw->ec->h;
4230 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4231 if ((cw->ec->w != w) || (cw->ec->h != h))
4233 cw->ec->changes.size = 1;
4236 E_FREE_FUNC(cw->frame_object, evas_object_del);
4237 if (!name) goto reshadow;
4239 o = edje_object_add(e_comp->evas);
4240 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4241 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4242 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4244 cw->frame_object = NULL;
4246 eina_stringshare_del(cw->frame_theme);
4247 cw->frame_theme = theme;
4252 if (theme != e_config->theme_default_border_style)
4254 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4255 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4259 ok = e_theme_edje_object_set(o, "base/theme/border",
4260 "e/widgets/border/default/border");
4261 if (ok && (theme == e_config->theme_default_border_style))
4263 /* Reset default border style to default */
4264 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4265 e_config_save_queue();
4272 cw->frame_object = o;
4273 eina_stringshare_del(cw->frame_theme);
4274 cw->frame_theme = theme;
4275 evas_object_name_set(o, "cw->frame_object");
4278 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4282 cw->ec->changes.icon = 1;
4288 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4293 _e_comp_object_shadow_setup(cw);
4296 int old_x, old_y, new_x = 0, new_y = 0;
4298 old_x = cw->x, old_y = cw->y;
4300 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4302 new_x = cw->ec->x, new_y = cw->ec->y;
4303 else if (cw->ec->placed || (!cw->ec->new_client))
4305 /* if no previous frame:
4306 * - reapply client_inset
4311 if (cw->ec->changes.size)
4319 zone = e_comp_zone_find_by_ec(cw->ec);
4322 x = cw->ec->client.x, y = cw->ec->client.y;
4323 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4324 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4326 new_x = x, new_y = y;
4329 if (old_x != new_x || old_y != new_y)
4331 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4332 cw->y = cw->x = -99999;
4333 evas_object_move(obj, new_x, new_y);
4337 if (cw->ec->maximized)
4339 cw->ec->changes.need_maximize = 1;
4342 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4343 if (cw->frame_object)
4345 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4348 cw->frame_extends = 0;
4349 evas_object_del(pbg);
4354 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4356 E_Comp_Object_Mover *prov;
4359 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4360 edje_object_signal_emit(cw->shobj, sig, src);
4361 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4362 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4363 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4365 /* start with highest priority callback first */
4366 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4368 if (!e_util_glob_match(sig, prov->sig)) continue;
4369 if (prov->func(prov->data, obj, sig)) break;
4374 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4376 /* FIXME: at some point I guess this should use eo to inherit
4377 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4378 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4381 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4385 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4388 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4392 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4395 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4399 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4402 Eina_Rectangle rect;
4405 if (cw->ec->input_only || (!cw->updates)) return;
4406 if (cw->nocomp) return;
4407 rect.x = x, rect.y = y;
4408 rect.w = w, rect.h = h;
4409 evas_object_smart_callback_call(obj, "damage", &rect);
4411 if (e_comp_is_on_overlay(cw->ec))
4413 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4414 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4415 * E module attempts to block screen update due to the particular policy.
4417 if (e_pixmap_resource_get(cw->ec->pixmap))
4418 cw->hwc_need_update = EINA_TRUE;
4421 /* ignore overdraw */
4422 if (cw->updates_full)
4424 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4425 e_comp_object_render_update_add(obj);
4427 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4428 evas_object_show(cw->smart_obj);
4432 /* clip rect to client surface */
4433 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4434 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4435 /* if rect is the total size of the client after clip, clear the updates
4436 * since this is guaranteed to be the whole region anyway
4438 eina_tiler_area_size_get(cw->updates, &tw, &th);
4439 if ((w > tw) || (h > th))
4441 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4442 eina_tiler_clear(cw->updates);
4443 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4445 tw = cw->ec->client.w, th = cw->ec->client.h;
4447 if ((!x) && (!y) && (w == tw) && (h == th))
4449 eina_tiler_clear(cw->updates);
4450 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4451 cw->updates_full = 1;
4452 cw->update_count = 0;
4455 if (cw->update_count > UPDATE_MAX)
4457 /* this is going to get really dumb, so just update the whole thing */
4458 eina_tiler_clear(cw->updates);
4459 cw->update_count = cw->updates_full = 1;
4460 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4461 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4465 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4466 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4468 cw->updates_exist = 1;
4469 e_comp_object_render_update_add(obj);
4471 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4472 evas_object_show(cw->smart_obj);
4476 e_comp_object_damage_exists(Evas_Object *obj)
4478 API_ENTRY EINA_FALSE;
4479 return cw->updates_exist;
4483 e_comp_object_render_update_add(Evas_Object *obj)
4487 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4488 if (cw->render_update_lock.lock) return;
4489 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4493 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4495 e_comp_render_queue();
4499 e_comp_object_render_update_del(Evas_Object *obj)
4503 if (cw->ec->input_only || (!cw->updates)) return;
4504 if (!cw->update) return;
4506 /* this gets called during comp animating to clear the update flag */
4507 if (e_comp->grabbed) return;
4508 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4509 if (!e_comp->updates)
4511 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4512 if (e_comp->render_animator)
4513 ecore_animator_freeze(e_comp->render_animator);
4518 e_comp_object_shape_apply(Evas_Object *obj)
4522 unsigned int i, *pix, *p;
4526 if (!cw->ec) return; //NYI
4527 if (cw->external_content) return;
4530 if ((cw->ec->shape_rects_num >= 1) &&
4531 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4536 ERR("BUGGER: shape with native surface? cw=%p", cw);
4539 evas_object_image_size_get(cw->obj, &w, &h);
4540 if ((w < 1) || (h < 1)) return;
4543 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4544 _e_comp_object_alpha_set(cw);
4545 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4546 evas_object_image_alpha_set(o, 1);
4548 p = pix = evas_object_image_data_get(cw->obj, 1);
4551 evas_object_image_data_set(cw->obj, pix);
4556 unsigned char *spix, *sp;
4558 spix = calloc(w * h, sizeof(unsigned char));
4560 for (i = 0; i < cw->ec->shape_rects_num; i++)
4564 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4565 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4566 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4567 sp = spix + (w * ry) + rx;
4568 for (py = 0; py < rh; py++)
4570 for (px = 0; px < rw; px++)
4578 for (py = 0; py < h; py++)
4580 for (px = 0; px < w; px++)
4582 unsigned int mask, imask;
4584 mask = ((unsigned int)(*sp)) << 24;
4586 imask |= imask >> 8;
4587 imask |= imask >> 8;
4588 *p = mask | (*p & imask);
4589 //if (*sp) *p = 0xff000000 | *p;
4590 //else *p = 0x00000000;
4599 for (py = 0; py < h; py++)
4601 for (px = 0; px < w; px++)
4605 evas_object_image_data_set(cw->obj, pix);
4606 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4607 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4609 evas_object_image_data_set(o, pix);
4610 evas_object_image_data_update_add(o, 0, 0, w, h);
4612 // don't need to fix alpha chanel as blending
4613 // should be totally off here regardless of
4614 // alpha channel content
4618 _e_comp_object_clear(E_Comp_Object *cw)
4623 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4625 if (cw->render_update_lock.lock) return;
4628 e_pixmap_clear(cw->ec->pixmap);
4630 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4631 evas_object_image_size_set(cw->obj, 1, 1);
4632 evas_object_image_data_set(cw->obj, NULL);
4633 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4635 evas_object_image_size_set(o, 1, 1);
4636 evas_object_image_data_set(o, NULL);
4639 e_comp_object_render_update_del(cw->smart_obj);
4643 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4647 API_ENTRY EINA_FALSE;
4649 if (cw->transparent.set == set)
4654 evas_object_color_get(obj, &r, &g, &b, &a);
4655 evas_object_color_set(obj, 0, 0, 0, 0);
4657 cw->transparent.user_r = r;
4658 cw->transparent.user_g = g;
4659 cw->transparent.user_b = b;
4660 cw->transparent.user_a = a;
4662 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4664 cw->transparent.user_r,
4665 cw->transparent.user_g,
4666 cw->transparent.user_b,
4667 cw->transparent.user_a);
4669 cw->transparent.set = EINA_TRUE;
4673 cw->transparent.set = EINA_FALSE;
4675 evas_object_color_set(obj,
4676 cw->transparent.user_r,
4677 cw->transparent.user_g,
4678 cw->transparent.user_b,
4679 cw->transparent.user_a);
4681 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4683 cw->transparent.user_r,
4684 cw->transparent.user_g,
4685 cw->transparent.user_b,
4686 cw->transparent.user_a);
4692 /* helper function to simplify toggling of redirection for display servers which support it */
4694 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4699 if (cw->redirected == set) return;
4700 cw->redirected = set;
4701 if (cw->external_content) return;
4703 e_comp_object_map_update(obj);
4707 if (cw->updates_exist)
4708 e_comp_object_render_update_add(obj);
4710 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4712 _e_comp_object_transparent_set(obj, EINA_FALSE);
4713 evas_object_smart_callback_call(obj, "redirected", NULL);
4717 _e_comp_object_clear(cw);
4718 _e_comp_object_transparent_set(obj, EINA_TRUE);
4719 evas_object_smart_callback_call(obj, "unredirected", NULL);
4724 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4727 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4729 if (cw->buffer_destroy_listener.notify)
4731 cw->buffer_destroy_listener.notify = NULL;
4732 wl_list_remove(&cw->buffer_destroy_listener.link);
4735 if (e_object_is_del(E_OBJECT(cw->ec)))
4737 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4742 /* if it's current displaying buffer, do not remove its content */
4743 if (!evas_object_visible_get(cw->ec->frame))
4744 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4749 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4754 if (cw->buffer_destroy_listener.notify)
4756 wl_list_remove(&cw->buffer_destroy_listener.link);
4757 cw->buffer_destroy_listener.notify = NULL;
4760 if (cw->tbm_surface)
4762 tbm_surface_internal_unref(cw->tbm_surface);
4763 cw->tbm_surface = NULL;
4768 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4770 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4771 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4773 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4775 tbm_surface_internal_ref(ns->data.tbm.buffer);
4776 cw->tbm_surface = ns->data.tbm.buffer;
4780 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4781 evas_object_image_native_surface_set(cw->obj, ns);
4785 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4787 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4788 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4789 evas_object_image_native_surface_set(o, ns);
4796 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4798 Evas_Native_Surface ns;
4801 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4802 if (cw->ec->input_only) return;
4803 if (cw->external_content) return;
4804 if (cw->render_update_lock.lock) return;
4807 memset(&ns, 0, sizeof(Evas_Native_Surface));
4811 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4812 set = (!cw->ec->shaped);
4814 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4818 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4822 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4825 if (cw->ec->input_only) return;
4828 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4829 _e_comp_object_alpha_set(cw);
4831 e_comp_object_native_surface_set(obj, cw->native);
4832 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4836 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4842 if (cw->blanked == set) return;
4844 _e_comp_object_alpha_set(cw);
4847 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4848 evas_object_image_data_set(cw->obj, NULL);
4852 e_comp_object_native_surface_set(obj, 1);
4853 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4857 _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)
4862 if (!_damage_trace) return;
4866 if (!evas_object_visible_get(cw->obj)) return;
4868 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4870 o = evas_object_rectangle_add(e_comp->evas);
4871 evas_object_layer_set(o, E_LAYER_MAX);
4872 evas_object_name_set(o, "damage_trace");
4873 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4874 evas_object_resize(o, dmg_w, dmg_h);
4875 evas_object_color_set(o, 0, 128, 0, 128);
4876 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4877 evas_object_pass_events_set(o, EINA_TRUE);
4878 evas_object_show(o);
4880 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4882 dmg_w, dmg_h, dmg_x, dmg_y,
4883 origin->w, origin->h, origin->x, origin->y);
4885 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4888 /* mark an object as dirty and setup damages */
4890 e_comp_object_dirty(Evas_Object *obj)
4893 Eina_Rectangle *rect;
4897 Eina_Bool dirty, visible;
4901 if (cw->external_content) return;
4902 if (!cw->redirected) return;
4903 if (cw->render_update_lock.lock)
4905 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4908 /* only actually dirty if pixmap is available */
4909 if (!e_pixmap_resource_get(cw->ec->pixmap))
4911 // e_pixmap_size_get returns last attached buffer size
4912 // eventhough it is destroyed
4913 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4916 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4917 visible = cw->visible;
4918 if (!dirty) w = h = 1;
4919 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4921 evas_object_image_data_set(cw->obj, NULL);
4922 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4923 evas_object_image_size_set(cw->obj, tw, th);
4924 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4925 if (cw->pending_updates)
4926 eina_tiler_area_size_set(cw->pending_updates, w, h);
4927 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4929 evas_object_image_pixels_dirty_set(o, dirty);
4931 evas_object_image_data_set(o, NULL);
4932 evas_object_image_size_set(o, tw, th);
4933 visible |= evas_object_visible_get(o);
4937 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4941 e_comp_object_native_surface_set(obj, 1);
4943 m = _e_comp_object_map_damage_transform_get(cw->ec);
4944 it = eina_tiler_iterator_new(cw->updates);
4945 EINA_ITERATOR_FOREACH(it, rect)
4947 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4948 * of evas engine and doesn't convert damage according to evas_map.
4949 * so damage of evas_object_image use surface coordinate.
4953 int damage_x, damage_y, damage_w, damage_h;
4955 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4956 &damage_x, &damage_y, &damage_w, &damage_h);
4957 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4958 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4962 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4963 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4966 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4967 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4968 if (cw->pending_updates)
4969 eina_tiler_rect_add(cw->pending_updates, rect);
4971 eina_iterator_free(it);
4972 if (m) e_map_free(m);
4973 if (cw->pending_updates)
4974 eina_tiler_clear(cw->updates);
4977 cw->pending_updates = cw->updates;
4978 cw->updates = eina_tiler_new(w, h);
4979 eina_tiler_tile_size_set(cw->updates, 1, 1);
4981 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4982 evas_object_smart_callback_call(obj, "dirty", NULL);
4983 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4984 /* force render if main object is hidden but mirrors are visible */
4985 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4986 e_comp_object_render(obj);
4990 e_comp_object_render(Evas_Object *obj)
4997 API_ENTRY EINA_FALSE;
4999 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5000 if (cw->ec->input_only) return EINA_TRUE;
5001 if (cw->external_content) return EINA_TRUE;
5002 if (cw->native) return EINA_FALSE;
5003 /* if comp object is not redirected state, comp object should not be set by newly committed data
5004 because image size of comp object is 1x1 and it should not be shown on canvas */
5005 if (!cw->redirected) return EINA_TRUE;
5006 if (cw->render_update_lock.lock)
5008 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5011 e_comp_object_render_update_del(obj);
5012 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5014 if (!cw->pending_updates)
5016 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5017 evas_object_image_data_set(cw->obj, NULL);
5018 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5019 evas_object_image_data_set(o, NULL);
5023 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5025 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5027 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5030 e_pixmap_image_refresh(cw->ec->pixmap);
5031 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5034 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5035 e_pixmap_image_data_ref(cw->ec->pixmap);
5037 /* set pixel data */
5038 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5039 _e_comp_object_alpha_set(cw);
5040 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5042 evas_object_image_data_set(o, pix);
5043 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5044 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5047 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5049 e_comp_client_post_update_add(cw->ec);
5054 /* create a duplicate of an evas object */
5056 e_comp_object_util_mirror_add(Evas_Object *obj)
5060 unsigned int *pix = NULL;
5061 Eina_Bool argb = EINA_FALSE;
5066 cw = evas_object_data_get(obj, "comp_mirror");
5069 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5070 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5071 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5072 evas_object_image_alpha_set(o, 1);
5073 evas_object_image_source_set(o, obj);
5076 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5077 if (cw->external_content)
5079 ERR("%p of client %p is external content.", obj, cw->ec);
5082 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5083 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5084 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5085 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5086 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5087 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5088 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5089 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5090 evas_object_data_set(o, "comp_mirror", cw);
5092 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5093 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5095 evas_object_image_size_set(o, tw, th);
5098 pix = evas_object_image_data_get(cw->obj, 0);
5104 evas_object_image_native_surface_set(o, cw->ns);
5107 Evas_Native_Surface ns;
5108 memset(&ns, 0, sizeof(Evas_Native_Surface));
5109 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5110 evas_object_image_native_surface_set(o, &ns);
5115 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5116 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5118 (e_pixmap_image_exists(cw->ec->pixmap)))
5119 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5121 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5128 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5129 evas_object_image_pixels_dirty_set(o, dirty);
5130 evas_object_image_data_set(o, pix);
5131 evas_object_image_data_set(cw->obj, pix);
5133 evas_object_image_data_update_add(o, 0, 0, tw, th);
5138 //////////////////////////////////////////////////////
5141 e_comp_object_effect_allowed_get(Evas_Object *obj)
5143 API_ENTRY EINA_FALSE;
5145 if (!cw->shobj) return EINA_FALSE;
5146 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5147 return !e_comp_config_get()->match.disable_borders;
5150 /* setup an api effect for a client */
5152 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5155 Eina_Stringshare *grp;
5156 E_Comp_Config *config;
5157 Eina_Bool loaded = EINA_FALSE;
5159 API_ENTRY EINA_FALSE;
5160 if (!cw->shobj) return EINA_FALSE; //input window
5162 if (!effect) effect = "none";
5163 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5165 config = e_comp_config_get();
5166 if ((config) && (config->effect_file))
5168 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5170 cw->effect_set = EINA_TRUE;
5177 edje_object_file_get(cw->effect_obj, NULL, &grp);
5178 cw->effect_set = !eina_streq(effect, "none");
5179 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5180 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5182 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5183 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5184 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5186 if (cw->effect_running)
5188 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5191 cw->effect_set = EINA_FALSE;
5192 return cw->effect_set;
5196 if (cw->effect_running)
5198 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5201 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5202 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5203 if (cw->effect_clip)
5205 evas_object_clip_unset(cw->clip);
5206 cw->effect_clip = 0;
5208 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5210 _e_comp_object_dim_update(cw);
5212 return cw->effect_set;
5215 /* set params for embryo scripts in effect */
5217 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5219 Edje_Message_Int_Set *msg;
5223 EINA_SAFETY_ON_NULL_RETURN(params);
5224 EINA_SAFETY_ON_FALSE_RETURN(count);
5225 if (!cw->effect_set) return;
5227 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5228 msg->count = (int)count;
5229 for (x = 0; x < count; x++)
5230 msg->val[x] = params[x];
5231 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5232 edje_object_message_signal_process(cw->effect_obj);
5236 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5238 Edje_Signal_Cb end_cb;
5240 E_Comp_Object *cw = data;
5242 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5243 cw->effect_running = 0;
5244 if (!_e_comp_object_animating_end(cw)) return;
5246 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5248 evas_object_data_del(cw->smart_obj, "effect_running");
5249 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5250 e_comp_visibility_calculation_set(EINA_TRUE);
5253 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5254 if (!end_cb) return;
5255 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5256 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5257 end_cb(end_data, cw->smart_obj, emission, source);
5260 /* clip effect to client's zone */
5262 e_comp_object_effect_clip(Evas_Object *obj)
5266 zone = e_comp_zone_find_by_ec(cw->ec);
5268 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5269 if (!cw->effect_clip_able) return;
5270 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5271 cw->effect_clip = 1;
5274 /* unclip effect from client's zone */
5276 e_comp_object_effect_unclip(Evas_Object *obj)
5279 if (!cw->effect_clip) return;
5280 evas_object_clip_unset(cw->smart_obj);
5281 cw->effect_clip = 0;
5284 /* start effect, running end_cb after */
5286 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5288 API_ENTRY EINA_FALSE;
5289 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5290 if (!cw->effect_set) return EINA_FALSE;
5292 if (cw->effect_running)
5294 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5297 e_comp_object_effect_clip(obj);
5298 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5300 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5301 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5302 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5303 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5305 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5306 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5308 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5309 _e_comp_object_animating_begin(cw);
5310 cw->effect_running = 1;
5314 /* stop a currently-running effect immediately */
5316 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5319 Edje_Signal_Cb end_cb_before = NULL;
5320 void *end_data_before = NULL;
5321 API_ENTRY EINA_FALSE;
5323 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5324 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5326 if (end_cb_before != end_cb) return EINA_TRUE;
5327 e_comp_object_effect_unclip(obj);
5328 if (cw->effect_clip)
5330 evas_object_clip_unset(cw->effect_obj);
5331 cw->effect_clip = 0;
5333 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5334 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5336 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5338 evas_object_data_del(cw->smart_obj, "effect_running");
5339 e_comp_visibility_calculation_set(EINA_TRUE);
5342 cw->effect_running = 0;
5343 ret = _e_comp_object_animating_end(cw);
5345 if ((ret) && (end_cb_before))
5347 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5348 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5355 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5357 return a->pri - b->pri;
5360 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5361 E_API E_Comp_Object_Mover *
5362 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5364 E_Comp_Object_Mover *prov;
5366 prov = E_NEW(E_Comp_Object_Mover, 1);
5367 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5368 prov->func = provider;
5369 prov->data = (void*)data;
5372 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5373 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5378 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5380 EINA_SAFETY_ON_NULL_RETURN(prov);
5381 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5386 e_comp_object_effect_object_get(Evas_Object *obj)
5390 return cw->effect_obj;
5394 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5396 API_ENTRY EINA_FALSE;
5397 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5398 if (!cw->effect_set) return EINA_FALSE;
5405 ////////////////////////////////////
5408 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5410 if (e_comp->autoclose.obj)
5412 e_comp_ungrab_input(0, 1);
5413 if (e_comp->autoclose.del_cb)
5414 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5415 else if (!already_del)
5417 evas_object_hide(e_comp->autoclose.obj);
5418 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5420 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5422 e_comp->autoclose.obj = NULL;
5423 e_comp->autoclose.data = NULL;
5424 e_comp->autoclose.del_cb = NULL;
5425 e_comp->autoclose.key_cb = NULL;
5426 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5430 _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)
5432 _e_comp_object_autoclose_cleanup(0);
5436 _e_comp_object_autoclose_setup(Evas_Object *obj)
5438 if (!e_comp->autoclose.rect)
5440 /* create rect just below autoclose object to catch mouse events */
5441 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5442 evas_object_move(e_comp->autoclose.rect, 0, 0);
5443 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5444 evas_object_show(e_comp->autoclose.rect);
5445 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5446 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5447 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5448 e_comp_grab_input(0, 1);
5450 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5451 evas_object_focus_set(obj, 1);
5455 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5457 _e_comp_object_autoclose_setup(obj);
5458 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5462 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5464 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5465 _e_comp_object_autoclose_cleanup(1);
5466 if (e_client_focused_get()) return;
5468 E_Zone *zone = e_zone_current_get();
5471 e_zone_focus_reset(zone);
5475 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5479 if (e_comp->autoclose.obj)
5481 if (e_comp->autoclose.obj == obj) return;
5482 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5483 e_comp->autoclose.obj = obj;
5484 e_comp->autoclose.del_cb = del_cb;
5485 e_comp->autoclose.key_cb = cb;
5486 e_comp->autoclose.data = (void*)data;
5487 if (evas_object_visible_get(obj))
5488 _e_comp_object_autoclose_setup(obj);
5490 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5491 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5494 e_comp->autoclose.obj = obj;
5495 e_comp->autoclose.del_cb = del_cb;
5496 e_comp->autoclose.key_cb = cb;
5497 e_comp->autoclose.data = (void*)data;
5498 if (evas_object_visible_get(obj))
5499 _e_comp_object_autoclose_setup(obj);
5501 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5502 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5506 e_comp_object_is_animating(Evas_Object *obj)
5510 return cw->animating;
5514 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5518 if ((cw->external_content) &&
5519 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5521 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5522 "But current external content is %d object for %p.",
5523 cw->content_type, cw->ec);
5527 cw->user_alpha_set = EINA_TRUE;
5528 cw->user_alpha = alpha;
5530 if (!cw->obj) return;
5532 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5534 evas_object_image_alpha_set(cw->obj, alpha);
5536 if ((!cw->native) && (!cw->external_content))
5537 evas_object_image_data_set(cw->obj, NULL);
5541 e_comp_object_alpha_get(Evas_Object *obj)
5543 API_ENTRY EINA_FALSE;
5545 return evas_object_image_alpha_get(cw->obj);
5549 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5551 Eina_Bool mask_set = EINA_FALSE;
5555 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5556 if (cw->ec->input_only) return;
5563 o = evas_object_rectangle_add(e_comp->evas);
5564 evas_object_color_set(o, 0, 0, 0, 0);
5565 evas_object_clip_set(o, cw->clip);
5566 evas_object_smart_member_add(o, obj);
5567 evas_object_move(o, 0, 0);
5568 evas_object_resize(o, cw->w, cw->h);
5569 /* save render op value to restore when clear a mask.
5571 * NOTE: DO NOT change the render op on ec->frame while mask object
5572 * is set. it will overwrite the changed op value. */
5573 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5574 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5575 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5576 if (cw->visible) evas_object_show(o);
5579 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5580 ELOGF("COMP", " |mask_obj", cw->ec);
5581 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5588 evas_object_smart_member_del(cw->mask.obj);
5589 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5591 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5592 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5598 e_comp_object_mask_has(Evas_Object *obj)
5600 API_ENTRY EINA_FALSE;
5602 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5606 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5611 if ((cw->external_content) &&
5612 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5614 WRN("Can set up size to ONLY evas \"image\" object. "
5615 "But current external content is %d object for %p.",
5616 cw->content_type, cw->ec);
5620 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5622 evas_object_image_size_set(cw->obj, tw, th);
5626 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5628 Eina_Bool transform_set = EINA_FALSE;
5630 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5631 if (cw->ec->input_only) return;
5633 transform_set = !!set;
5637 if (!cw->transform_bg_obj)
5639 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5640 evas_object_move(o, 0, 0);
5641 evas_object_resize(o, 1, 1);
5642 if (cw->transform_bg_color.a >= 255)
5643 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5645 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5646 evas_object_color_set(o,
5647 cw->transform_bg_color.r,
5648 cw->transform_bg_color.g,
5649 cw->transform_bg_color.b,
5650 cw->transform_bg_color.a);
5651 if (cw->visible) evas_object_show(o);
5653 cw->transform_bg_obj = o;
5654 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5656 _e_comp_object_transform_obj_stack_update(obj);
5660 if (cw->transform_bg_obj)
5662 evas_object_smart_member_del(cw->transform_bg_obj);
5663 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5669 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5673 cw->transform_bg_color.r = r;
5674 cw->transform_bg_color.g = g;
5675 cw->transform_bg_color.b = b;
5676 cw->transform_bg_color.a = a;
5678 if (cw->transform_bg_obj)
5680 evas_object_color_set(cw->transform_bg_obj,
5681 cw->transform_bg_color.r,
5682 cw->transform_bg_color.g,
5683 cw->transform_bg_color.b,
5684 cw->transform_bg_color.a);
5689 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5692 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5693 if (cw->ec->input_only) return;
5694 if (!cw->transform_bg_obj) return;
5696 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5700 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5703 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5704 if (cw->ec->input_only) return;
5705 if (!cw->transform_bg_obj) return;
5707 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5711 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5713 Eina_Bool transform_set = EINA_FALSE;
5715 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5716 if (cw->ec->input_only) return;
5718 transform_set = !!set;
5722 if (!cw->transform_tranp_obj)
5724 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5725 evas_object_move(o, 0, 0);
5726 evas_object_resize(o, 1, 1);
5727 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5728 evas_object_color_set(o, 0, 0, 0, 0);
5729 if (cw->visible) evas_object_show(o);
5731 cw->transform_tranp_obj = o;
5732 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5733 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5734 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5736 _e_comp_object_transform_obj_stack_update(obj);
5740 if (cw->transform_tranp_obj)
5742 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5743 evas_object_smart_member_del(cw->transform_tranp_obj);
5744 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5750 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5753 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5754 if (cw->ec->input_only) return;
5755 if (!cw->transform_tranp_obj) return;
5757 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5761 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5764 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5765 if (cw->ec->input_only) return;
5766 if (!cw->transform_tranp_obj) return;
5768 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5771 #ifdef REFACTOR_DESK_AREA
5774 e_comp_object_layer_update(Evas_Object *obj,
5775 Evas_Object *above, Evas_Object *below)
5777 E_Comp_Object *cw2 = NULL;
5778 Evas_Object *o = NULL;
5783 if (cw->ec->layer_block) return;
5784 if ((above) && (below))
5786 ERR("Invalid layer update request! cw=%p", cw);
5794 layer = evas_object_layer_get(o);
5795 cw2 = evas_object_data_get(o, "comp_obj");
5798 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5800 o = evas_object_above_get(o);
5801 if ((!o) || (o == cw->smart_obj)) break;
5802 if (evas_object_layer_get(o) != layer)
5804 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5809 ec = e_client_top_get();
5810 if (ec) o = ec->frame;
5813 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5817 _e_comp_object_layers_remove(cw);
5820 if (cw2->layer > cw->layer)
5821 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5822 else if (cw2->layer == cw->layer)
5825 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5827 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5829 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5832 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5835 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5840 e_comp_object_layer_get(Evas_Object *obj)
5847 e_comp_object_content_set(Evas_Object *obj,
5848 Evas_Object *content,
5849 E_Comp_Object_Content_Type type)
5851 API_ENTRY EINA_FALSE;
5853 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5854 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5855 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5859 ERR("Can't set e.swallow.content to requested content. "
5860 "Previous comp object should not be changed at all.");
5864 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5866 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5867 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5869 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5870 type, content, cw->ec, cw->ec->pixmap);
5874 cw->external_content = EINA_TRUE;
5877 cw->content_type = type;
5878 e_util_size_debug_set(cw->obj, 1);
5879 evas_object_name_set(cw->obj, "cw->obj");
5880 _e_comp_object_alpha_set(cw);
5883 _e_comp_object_shadow_setup(cw);
5889 e_comp_object_content_unset(Evas_Object *obj)
5891 API_ENTRY EINA_FALSE;
5893 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5894 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5896 if (!cw->obj && !cw->ec->visible)
5898 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5902 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5904 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5910 if (cw->frame_object)
5911 edje_object_part_unswallow(cw->frame_object, cw->obj);
5913 edje_object_part_unswallow(cw->shobj, cw->obj);
5915 evas_object_del(cw->obj);
5916 evas_object_hide(cw->obj);
5920 cw->external_content = EINA_FALSE;
5921 if (cw->ec->is_cursor)
5924 DBG("%p is cursor surface..", cw->ec);
5925 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5927 evas_object_resize(cw->ec->frame, pw, ph);
5928 evas_object_hide(cw->ec->frame);
5933 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5934 cw->obj = evas_object_image_filled_add(e_comp->evas);
5935 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5936 e_util_size_debug_set(cw->obj, 1);
5937 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5938 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5939 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5940 evas_object_name_set(cw->obj, "cw->obj");
5941 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5942 _e_comp_object_alpha_set(cw);
5945 _e_comp_object_shadow_setup(cw);
5950 _e_comp_intercept_show_helper(cw);
5954 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5955 e_comp_object_dirty(cw->smart_obj);
5956 e_comp_object_render(cw->smart_obj);
5957 e_comp_object_render_update_add(obj);
5962 EINTERN Evas_Object *
5963 e_comp_object_content_get(Evas_Object *obj)
5967 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5969 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5971 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5978 E_API E_Comp_Object_Content_Type
5979 e_comp_object_content_type_get(Evas_Object *obj)
5981 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5983 return cw->content_type;
5987 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5990 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5991 E_Comp_Config *conf = e_comp_config_get();
5992 if (cw->ec->input_only) return;
5993 if (!conf->dim_rect_enable) return;
5995 cw->dim.mask_set = mask_set;
6001 if (!cw->dim.enable) return;
6002 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6006 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6008 Eina_Bool mask_set = EINA_FALSE;
6012 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6013 E_Comp_Config *conf = e_comp_config_get();
6014 if (cw->ec->input_only) return;
6015 if (!conf->dim_rect_enable) return;
6021 if (cw->dim.mask_obj)
6023 evas_object_smart_member_del(cw->dim.mask_obj);
6024 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6027 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);
6028 o = evas_object_rectangle_add(e_comp->evas);
6029 evas_object_color_set(o, 0, 0, 0, 0);
6030 evas_object_smart_member_add(o, obj);
6031 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6032 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6034 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6035 if (cw->visible) evas_object_show(o);
6037 cw->dim.mask_obj = o;
6038 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6040 evas_object_layer_set(cw->dim.mask_obj, 9998);
6044 if (cw->dim.mask_obj)
6046 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6047 evas_object_smart_member_del(cw->dim.mask_obj);
6048 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6054 e_comp_object_dim_client_set(E_Client *ec)
6056 E_Comp_Config *conf = e_comp_config_get();
6058 if (!conf->dim_rect_enable) return ;
6059 if (dim_client == ec) return;
6061 Eina_Bool prev_dim = EINA_FALSE;
6062 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6064 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6065 prev_dim = EINA_TRUE;
6067 if (prev_dim && dim_client->visible && ec)
6069 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6070 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6074 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6075 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6081 e_comp_object_dim_client_get(void)
6083 E_Comp_Config *conf = e_comp_config_get();
6085 if (!conf->dim_rect_enable ) return NULL;
6091 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6094 char emit[32] = "\0";
6095 E_Comp_Config *conf = e_comp_config_get();
6098 if (!conf->dim_rect_enable) return;
6099 if (!cw->effect_obj) return;
6100 if (enable == cw->dim.enable) return;
6102 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6103 if (noeffect || !conf->dim_rect_effect)
6105 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6109 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6112 cw->dim.enable = enable;
6114 if (cw->dim.mask_set && !enable)
6116 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6117 edje_object_signal_emit(cw->effect_obj, emit, "e");
6119 else if (cw->dim.mask_set && enable)
6121 edje_object_signal_emit(cw->effect_obj, emit, "e");
6122 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6126 edje_object_signal_emit(cw->effect_obj, emit, "e");
6131 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6133 API_ENTRY EINA_FALSE;
6134 E_Comp_Config *conf = e_comp_config_get();
6136 if (!ec) return EINA_FALSE;
6137 if (!conf->dim_rect_enable) return EINA_FALSE;
6139 if (cw->dim.enable) return EINA_TRUE;
6145 _e_comp_object_dim_update(E_Comp_Object *cw)
6147 E_Comp_Config *conf = e_comp_config_get();
6150 if (!conf->dim_rect_enable) return;
6151 if (!cw->effect_obj) return;
6154 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6155 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6157 if (cw->dim.mask_set)
6159 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6165 e_comp_object_clear(Evas_Object *obj)
6169 _e_comp_object_clear(cw);
6173 e_comp_object_hwc_update_exists(Evas_Object *obj)
6175 API_ENTRY EINA_FALSE;
6176 return cw->hwc_need_update;
6181 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6184 cw->hwc_need_update = set;
6188 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6190 API_ENTRY EINA_FALSE;
6191 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6195 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6198 if (cw->indicator.obj != indicator)
6199 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6200 cw->indicator.obj = indicator;
6201 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6205 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6208 if (cw->indicator.obj != indicator) return;
6209 cw->indicator.obj = NULL;
6210 edje_object_part_unswallow(cw->shobj, indicator);
6214 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6217 Edje_Message_Int_Set *msg;
6219 if (!cw->indicator.obj) return;
6221 cw->indicator.w = w;
6222 cw->indicator.h = h;
6224 if (!cw->shobj) return;
6226 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6230 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6231 edje_object_message_signal_process(cw->shobj);
6234 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6236 e_comp_object_map_update(Evas_Object *obj)
6239 E_Client *ec = cw->ec;
6240 E_Comp_Wl_Client_Data *cdata;
6242 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6245 int l, remain = sizeof buffer;
6248 if (e_object_is_del(E_OBJECT(ec))) return;
6249 cdata = e_client_cdata_get(ec);
6252 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6253 * when new buffer is attached.
6255 if (!cdata->buffer_ref.buffer) return;
6257 if ((!cw->redirected) ||
6258 (e_client_video_hw_composition_check(ec)) ||
6259 (!e_comp_wl_output_buffer_transform_get(ec) &&
6260 cdata->scaler.buffer_viewport.buffer.scale == 1))
6262 if (evas_object_map_enable_get(cw->effect_obj))
6264 ELOGF("TRANSFORM", "map: disable", cw->ec);
6265 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6266 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6267 evas_object_resize(cw->effect_obj, tw, th);
6274 EINA_SAFETY_ON_NULL_RETURN(map);
6276 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6282 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6284 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6285 e_map_point_image_uv_set(map, 0, x, y);
6286 l = snprintf(p, remain, "%d,%d", x, y);
6287 p += l, remain -= l;
6289 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6290 e_map_point_image_uv_set(map, 1, x, y);
6291 l = snprintf(p, remain, " %d,%d", x, y);
6292 p += l, remain -= l;
6294 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6295 e_map_point_image_uv_set(map, 2, x, y);
6296 l = snprintf(p, remain, " %d,%d", x, y);
6297 p += l, remain -= l;
6299 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6300 e_map_point_image_uv_set(map, 3, x, y);
6301 l = snprintf(p, remain, " %d,%d", x, y);
6302 p += l, remain -= l;
6304 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6306 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6308 e_comp_object_map_set(cw->effect_obj, map);
6309 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6313 /* if there's screen rotation with comp mode, then ec->effect_obj and
6314 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6316 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6317 evas_object_resize(cw->effect_obj, tw, th);
6321 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6323 API_ENTRY EINA_FALSE;
6325 cw->render_trace = set;
6331 e_comp_object_native_usable_get(Evas_Object *obj)
6333 API_ENTRY EINA_FALSE;
6334 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6336 if (cw->ec->input_only) return EINA_FALSE;
6337 if (cw->external_content) return EINA_FALSE;
6338 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6340 /* just return true value, if it is normal case */
6341 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6344 Evas_Native_Surface *ns;
6345 ns = evas_object_image_native_surface_get(cw->obj);
6347 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6350 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6358 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6360 API_ENTRY EINA_FALSE;
6361 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6362 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6363 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6367 case E_COMP_IMAGE_FILTER_BLUR:
6368 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6370 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6371 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6373 case E_COMP_IMAGE_FILTER_INVERSE:
6374 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6376 case E_COMP_IMAGE_FILTER_NONE:
6378 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6382 cw->image_filter = filter;
6387 EINTERN E_Comp_Image_Filter
6388 e_comp_object_image_filter_get(Evas_Object *obj)
6390 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6391 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6392 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6393 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6395 return cw->image_filter;
6399 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6403 if (!_damage_trace) return;
6405 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6406 evas_object_del(obj);
6408 _damage_trace_post_objs = NULL;
6412 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6414 if (!_damage_trace) return;
6416 _damage_trace_post_objs = _damage_trace_objs;
6417 _damage_trace_objs = NULL;
6421 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6423 if (_damage_trace == onoff) return;
6427 evas_event_callback_add(e_comp->evas,
6428 EVAS_CALLBACK_RENDER_PRE,
6429 _e_comp_object_damage_trace_render_pre_cb,
6432 evas_event_callback_add(e_comp->evas,
6433 EVAS_CALLBACK_RENDER_POST,
6434 _e_comp_object_damage_trace_render_post_cb,
6441 EINA_LIST_FREE(_damage_trace_objs, obj)
6442 evas_object_del(obj);
6444 _damage_trace_objs = NULL;
6446 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6447 evas_object_del(obj);
6449 _damage_trace_post_objs = NULL;
6451 evas_event_callback_del(e_comp->evas,
6452 EVAS_CALLBACK_RENDER_PRE,
6453 _e_comp_object_damage_trace_render_pre_cb);
6455 evas_event_callback_del(e_comp->evas,
6456 EVAS_CALLBACK_RENDER_POST,
6457 _e_comp_object_damage_trace_render_post_cb);
6460 _damage_trace = onoff;
6464 e_comp_object_redirected_get(Evas_Object *obj)
6466 API_ENTRY EINA_FALSE;
6467 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6469 return cw->redirected;
6473 e_comp_object_color_visible_get(Evas_Object *obj)
6475 API_ENTRY EINA_FALSE;
6478 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6480 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6484 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6488 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6492 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6500 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6502 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6504 return e_map_set_to_comp_object(em, obj);
6508 e_comp_object_map_get(const Evas_Object *obj)
6510 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6512 return e_map_get_from_comp_object(obj);
6516 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6518 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6520 evas_object_map_enable_set(obj, enable);
6526 e_comp_object_render_update_lock(Evas_Object *obj)
6528 E_Comp_Wl_Buffer *buffer;
6529 struct wayland_tbm_client_queue *cqueue;
6531 API_ENTRY EINA_FALSE;
6533 if (cw->render_update_lock.lock == 0)
6535 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6537 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6538 if ((buffer) && (buffer->resource))
6540 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6542 wayland_tbm_server_client_queue_flush(cqueue);
6545 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6546 e_comp_object_render_update_del(obj);
6548 ELOGF("COMP", "Render update lock enabled", cw->ec);
6551 cw->render_update_lock.lock++;
6557 e_comp_object_render_update_unlock(Evas_Object *obj)
6561 if (cw->render_update_lock.lock == 0)
6564 cw->render_update_lock.lock--;
6566 if (cw->render_update_lock.lock == 0)
6569 if (cw->render_update_lock.pending_move_set)
6571 evas_object_move(obj,
6572 cw->render_update_lock.pending_move_x,
6573 cw->render_update_lock.pending_move_y);
6574 cw->render_update_lock.pending_move_x = 0;
6575 cw->render_update_lock.pending_move_y = 0;
6576 cw->render_update_lock.pending_move_set = EINA_FALSE;
6579 if (cw->render_update_lock.pending_resize_set)
6581 evas_object_resize(obj,
6582 cw->render_update_lock.pending_resize_w,
6583 cw->render_update_lock.pending_resize_h);
6584 cw->render_update_lock.pending_resize_w = 0;
6585 cw->render_update_lock.pending_resize_h = 0;
6586 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6589 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6591 if ((cw->ec->exp_iconify.buffer_flush) &&
6592 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6593 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6594 e_comp_object_clear(obj);
6596 e_comp_object_render_update_add(obj);
6598 ELOGF("COMP", "Render update lock disabled", cw->ec);
6603 e_comp_object_render_update_lock_get(Evas_Object *obj)
6605 API_ENTRY EINA_FALSE;
6607 if (cw->render_update_lock.lock > 0)
6614 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6618 if (cw->transparent.set)
6620 if (r) *r = cw->transparent.user_r;
6621 if (g) *g = cw->transparent.user_g;
6622 if (b) *b = cw->transparent.user_b;
6623 if (a) *a = cw->transparent.user_a;
6627 evas_object_color_get(obj, r, g, b, a);
6632 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6636 evas_object_render_op_set(cw->obj, op);
6639 EINTERN Evas_Render_Op
6640 e_comp_object_render_op_get(Evas_Object *obj)
6642 API_ENTRY EVAS_RENDER_BLEND;
6644 return evas_object_render_op_get(cw->obj);
6648 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6651 wl_signal_add(&cw->events.lower, listener);
6654 #ifdef REFACTOR_DESK_AREA
6656 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6659 wl_signal_add(&cw->events.lower_done, listener);
6663 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6666 wl_signal_add(&cw->events.raise, listener);
6671 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6674 wl_signal_add(&cw->events.show, listener);
6678 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6681 wl_signal_add(&cw->events.hide, listener);
6684 #ifdef REFACTOR_DESK_AREA
6686 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6689 wl_signal_add(&cw->events.set_layer, listener);
6693 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6696 wl_signal_add(&cw->events.stack_above, listener);
6700 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6703 wl_signal_add(&cw->events.stack_below, listener);