2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
8 = keys that return objects =
9 - E_Client: the client associated with the object (E_Client*)
10 - comp_smart_obj: cw->smart_obj (Evas_Object*)
11 - comp_obj: cw (E_Comp_Object*)
13 = keys that are bool flags =
14 - client_restack: client needs a protocol-level restack
15 - comp_override: object is triggering a nocomp override to force compositing
16 - comp_ref: object has a ref from visibility animations
17 - comp_showing: object is currently running its show animation
18 - comp_hiding: object is currently running its hiding animation
19 - comp_object: object is a compositor-created object
20 - comp_object_skip: object has a name which prohibits theme shadows
21 - comp_object-to_del: list of objects which will be deleted when this object is deleted
22 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
23 - effect_running: object is animating by external module
26 #define UPDATE_MAX 512 // same as evas
27 #define FAILURE_MAX 2 // seems reasonable
28 #define SMART_NAME "e_comp_object"
29 #define INPUT_OBJ_SMART_NAME "input_object"
31 /* for non-util functions */
32 #define API_ENTRY E_Comp_Object *cw; \
33 cw = evas_object_smart_data_get(obj); \
34 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
36 /* for util functions (obj may or may not be E_Comp_Object */
37 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
40 CRI("YOU PASSED NULL! ARGH!"); \
43 cw = evas_object_smart_data_get(obj); \
44 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
46 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
48 /* enable for lots of client size info in console output */
50 # define e_util_size_debug_set(x, y)
53 /* enable along with display-specific damage INF calls to enable render tracing
57 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
59 #define RENDER_DEBUG(...)
62 #ifdef REFACTOR_DESK_AREA
64 typedef struct _E_Comp_Object
68 int x, y, w, h; // geometry
72 E_Comp_Object_Frame client_inset;
74 Eina_Stringshare *frame_theme;
75 Eina_Stringshare *frame_name;
76 Eina_Stringshare *visibility_effect; //effect when toggling visibility
78 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
80 Evas_Object *smart_obj; // smart object
81 Evas_Object *clip; // clipper over effect object
82 Evas_Object *input_obj; // input smart object
83 Evas_Object *obj; // composite object
84 Evas_Object *frame_object; // for client frames
85 Evas_Object *shobj; // shadow object
86 Evas_Object *effect_obj; // effects object
87 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
92 Evas_Object *transform_tranp_obj;// transform transp rect obj
93 Evas_Object *default_input_obj; // default input object
94 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
95 Eina_List *obj_mirror; // extra mirror objects
96 Eina_Tiler *updates; //render update regions
97 Eina_Tiler *pending_updates; //render update regions which are about to render
99 Evas_Native_Surface *ns; //for custom gl rendering
101 struct wl_listener buffer_destroy_listener;
103 unsigned int update_count; // how many updates have happened to this obj
105 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
107 unsigned int animating; // it's busy animating
108 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
109 unsigned int force_visible; //number of visible obj_mirror objects
110 Eina_Bool delete_pending : 1; // delete pending
111 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
112 Eina_Bool showing : 1; // object is currently in "show" animation
113 Eina_Bool hiding : 1; // object is currently in "hide" animation
114 Eina_Bool visible : 1; // is visible
116 Eina_Bool shaped : 1; // is shaped
117 Eina_Bool update : 1; // has updates to fetch
118 Eina_Bool redirected : 1; // has updates to fetch
119 Eina_Bool native : 1; // native
121 Eina_Bool nocomp : 1; // nocomp applied
122 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
123 Eina_Bool real_hid : 1; // last hide was a real window unmap
125 Eina_Bool effect_set : 1; //effect_obj has a valid group
126 Eina_Bool effect_running : 1; //effect_obj is playing an animation
127 Eina_Bool effect_clip : 1; //effect_obj is clipped
128 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
130 Eina_Bool updates_exist : 1;
131 Eina_Bool updates_full : 1; // entire object will be updated
133 Eina_Bool force_move : 1;
134 Eina_Bool frame_extends : 1; //frame may extend beyond object size
135 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
136 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
137 Eina_Bool user_alpha_set : 1;
138 Eina_Bool user_alpha : 1;
142 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
143 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
150 } indicator; //indicator object for internal client
154 Evas_Object *mask_obj;
157 int mask_x, mask_y, mask_w, mask_h;
160 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
162 tbm_surface_h tbm_surface;
163 E_Comp_Image_Filter image_filter;
164 Eina_Bool set_mouse_callbacks;
169 E_Comp_Wl_Buffer_Ref buffer_ref;
170 Eina_Bool pending_move_set;
171 int pending_move_x, pending_move_y;
172 Eina_Bool pending_resize_set;
173 int pending_resize_w, pending_resize_h;
174 } render_update_lock;
187 struct wl_signal lower;
188 //#ifdef REFACTOR_DESK_AREA
189 struct wl_signal raise;
191 struct wl_signal show;
192 struct wl_signal hide;
193 //#ifdef REFACTOR_DESK_AREA
194 struct wl_signal set_layer;
195 struct wl_signal stack_above;
196 struct wl_signal stack_below;
202 typedef struct _E_Input_Rect_Data
208 typedef struct _E_Input_Rect_Smart_Data
210 Eina_List *input_rect_data_list;
212 } E_Input_Rect_Smart_Data;
214 struct E_Comp_Object_Mover
217 E_Comp_Object_Mover_Cb func;
223 static Eina_Inlist *_e_comp_object_movers = NULL;
224 static Evas_Smart *_e_comp_smart = NULL;
225 static Evas_Smart *_e_comp_input_obj_smart = NULL;
227 static int _e_comp_object_hooks_delete = 0;
228 static int _e_comp_object_hooks_walking = 0;
230 static Eina_Inlist *_e_comp_object_hooks[] =
232 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
233 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
234 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
235 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
236 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
237 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
238 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
239 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
242 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
243 static int _e_comp_object_intercept_hooks_delete = 0;
244 static int _e_comp_object_intercept_hooks_walking = 0;
246 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
248 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
249 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
253 static Eina_Bool _damage_trace = EINA_FALSE;
254 static Eina_List *_damage_trace_objs = NULL;
255 static Eina_List *_damage_trace_post_objs = NULL;
257 /* sekrit functionzzz */
258 EINTERN void e_client_focused_set(E_Client *ec);
260 /* emitted every time a new noteworthy comp object is added */
261 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
263 /* ecore event define */
264 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
265 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
266 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
268 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
269 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
270 static void _e_comp_object_dim_update(E_Comp_Object *cw);
271 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
272 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
274 static E_Client *dim_client = NULL;
277 _e_comp_object_hooks_clean(void)
280 E_Comp_Object_Hook *ch;
283 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
284 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
286 if (!ch->delete_me) continue;
287 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
293 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
295 E_Comp_Object_Hook *ch;
296 Eina_Bool ret = EINA_TRUE;
298 if (e_object_is_del(E_OBJECT(ec)))
300 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
301 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
302 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
303 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
304 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
305 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
306 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
307 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
313 e_object_ref(E_OBJECT(ec));
314 _e_comp_object_hooks_walking++;
315 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
317 if (ch->delete_me) continue;
318 if (!(ch->func(ch->data, ec)))
324 _e_comp_object_hooks_walking--;
325 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
326 _e_comp_object_hooks_clean();
328 e_object_unref(E_OBJECT(ec));
333 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
335 _e_comp_object_intercept_hooks_clean(void)
338 E_Comp_Object_Intercept_Hook *ch;
341 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
342 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
344 if (!ch->delete_me) continue;
345 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
351 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
353 E_Comp_Object_Intercept_Hook *ch;
354 Eina_Bool ret = EINA_TRUE;
356 if (e_object_is_del(E_OBJECT(ec))) return ret;
357 e_object_ref(E_OBJECT(ec));
358 _e_comp_object_intercept_hooks_walking++;
359 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
361 if (ch->delete_me) continue;
362 if (!(ch->func(ch->data, ec)))
368 _e_comp_object_intercept_hooks_walking--;
369 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
370 _e_comp_object_intercept_hooks_clean();
372 e_object_unref(E_OBJECT(ec));
379 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
381 E_Event_Comp_Object *ev = event;
384 ec = evas_object_data_get(ev->comp_object, "E_Client");
388 e_object_unref(E_OBJECT(ec));
390 evas_object_unref(ev->comp_object);
395 _e_comp_object_event_add(Evas_Object *obj)
397 E_Event_Comp_Object *ev;
400 if (stopping) return;
401 ev = E_NEW(E_Event_Comp_Object, 1);
402 EINA_SAFETY_ON_NULL_RETURN(ev);
404 evas_object_ref(obj);
405 ev->comp_object = obj;
406 ec = evas_object_data_get(ev->comp_object, "E_Client");
410 e_object_ref(E_OBJECT(ec));
412 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
416 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
418 E_Event_Comp_Object *ev = event;
421 ec = evas_object_data_get(ev->comp_object, "E_Client");
425 e_object_unref(E_OBJECT(ec));
427 evas_object_unref(ev->comp_object);
432 _e_comp_object_event_simple(Evas_Object *obj, int type)
434 E_Event_Comp_Object *ev;
437 ev = E_NEW(E_Event_Comp_Object, 1);
440 evas_object_ref(obj);
441 ev->comp_object = obj;
442 ec = evas_object_data_get(ev->comp_object, "E_Client");
446 e_object_ref(E_OBJECT(ec));
448 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
450 /////////////////////////////////////
453 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
455 E_Comp_Object *cw = data;
457 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
461 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
463 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
469 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
470 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
474 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
476 E_Comp_Object *cw = data;
479 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
480 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
483 /////////////////////////////////////
486 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
490 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
491 if (cw->ec->input_only) return;
493 layer = evas_object_layer_get(obj);
495 if (cw->transform_bg_obj)
497 if (layer != evas_object_layer_get(cw->transform_bg_obj))
499 evas_object_layer_set(cw->transform_bg_obj, layer);
502 evas_object_stack_below(cw->transform_bg_obj, obj);
505 if (cw->transform_tranp_obj)
507 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
509 evas_object_layer_set(cw->transform_tranp_obj, layer);
512 evas_object_stack_below(cw->transform_tranp_obj, obj);
517 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
524 if (!map) return NULL;
526 e_map_util_points_populate_from_object_full(map, obj, 0);
527 e_map_util_points_color_set(map, 255, 255, 255, 255);
529 for (i = 0 ; i < 4 ; ++i)
534 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
535 e_map_point_coord_set(map, i, x, y, 1.0);
542 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
548 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
551 e_comp_object_map_set(obj, map);
552 e_comp_object_map_enable_set(obj, EINA_TRUE);
559 evas_object_map_enable_set(obj, EINA_FALSE);
564 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
570 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
573 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
575 e_comp_object_map_set(obj, map);
576 e_comp_object_map_enable_set(obj, EINA_TRUE);
583 evas_object_map_enable_set(obj, EINA_FALSE);
586 /////////////////////////////////////
588 static inline Eina_Bool
589 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
591 if (num > 1) return EINA_TRUE;
592 if ((rects[0].x == 0) && (rects[0].y == 0) &&
593 ((int)rects[0].w == w) && ((int)rects[0].h == h))
598 /////////////////////////////////////
600 /* add a client to the layer-client list */
602 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
604 g_rec_mutex_lock(&e_comp->ec_list_mutex);
607 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));
609 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));
610 if ((!above) && (!below))
613 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
614 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
615 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
617 e_comp->layers[cw->layer].clients_count++;
619 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
623 _e_comp_object_layers_remove(E_Comp_Object *cw)
625 g_rec_mutex_lock(&e_comp->ec_list_mutex);
627 if (cw->ec && e_comp->layers[cw->layer].clients)
629 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
630 e_comp->layers[cw->layer].clients_count--;
633 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
636 /////////////////////////////////////
638 _e_comp_object_alpha_set(E_Comp_Object *cw)
640 Eina_Bool alpha = cw->ec->argb;
642 if ((cw->external_content) &&
643 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
648 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
649 if (cw->user_alpha_set) alpha = cw->user_alpha;
651 evas_object_image_alpha_set(cw->obj, alpha);
655 _e_comp_object_shadow(E_Comp_Object *cw)
657 if (e_client_util_shadow_state_get(cw->ec))
658 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
660 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
661 if (cw->frame_object)
662 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
663 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
666 /* convert from the surface coordinates to the buffer coordinates */
668 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
670 E_Comp_Wl_Buffer_Viewport *vp;
671 E_Comp_Wl_Client_Data *cdata;
675 cdata = e_client_cdata_get(ec);
677 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
684 vp = &cdata->scaler.buffer_viewport;
685 transform = e_comp_wl_output_buffer_transform_get(ec);
687 e_pixmap_size_get(ec->pixmap, &bw, &bh);
689 /* for subsurface, it should be swap 90 and 270 */
690 if (e_comp_wl_subsurface_check(ec))
693 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
694 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
695 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
696 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
702 case WL_OUTPUT_TRANSFORM_NORMAL:
703 default: tx = sx, ty = sy; break;
704 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
705 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
706 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
707 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
708 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
709 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
710 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
713 tx *= vp->buffer.scale;
714 ty *= vp->buffer.scale;
721 _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)
729 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
730 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
737 if (dw) *dw = MAX(x1, x2) - mx;
738 if (dh) *dh = MAX(y1, y2) - my;
742 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
743 int *dx, int *dy, int *dw, int *dh)
745 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
746 E_Util_Transform_Rect_Vertex sv, dv;
750 e_pixmap_size_get(ec->pixmap, &bw, &bh);
752 sv = e_util_transform_rect_to_vertices(&rect);
754 for (i = 0; i < 4; i++)
756 double x = 0.0, y = 0.0;
758 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
760 /* if evas decide coordinate is outside of map, it returns (0, 0)
761 in this case, full damage is added.
763 if ((i != 0) && (x == 0.0) && (y == 0.0))
766 dv.vertices[i].vertex[0] = x;
767 dv.vertices[i].vertex[1] = y;
768 dv.vertices[i].vertex[2] = 1.0;
769 dv.vertices[i].vertex[3] = 1.0;
772 rect = e_util_transform_vertices_to_rect(&dv);
774 if (dx) *dx = rect.x;
775 if (dy) *dy = rect.y;
776 if (dw) *dw = rect.w;
777 if (dh) *dh = rect.h;
791 _e_comp_object_map_damage_transform_get(E_Client *ec)
798 if (!e_client_transform_core_enable_get(ec))
801 m = e_client_map_get(ec);
805 e_pixmap_size_get(ec->pixmap, &bw, &bh);
806 if ((bw == 0) || (bh == 0))
819 e_map_point_coord_set(m2, 0, 0, 0, 0);
820 e_map_point_coord_set(m2, 1, bw, 0, 0);
821 e_map_point_coord_set(m2, 2, bw, bh, 0);
822 e_map_point_coord_set(m2, 3, 0, bh, 0);
824 for (i = 0; i < 4; i++)
828 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
829 e_map_point_image_uv_set(m2, i, map_x, map_y);
836 /////////////////////////////////////
838 /* handle evas mouse-in events on client object */
840 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
842 Evas_Event_Mouse_In *ev = event_info;
843 E_Comp_Object *cw = data;
845 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
848 /* handle evas mouse-out events on client object */
850 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
852 Evas_Event_Mouse_Out *ev = event_info;
853 E_Comp_Object *cw = data;
855 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
858 /* handle evas mouse wheel events on client object */
860 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
862 Evas_Event_Mouse_Wheel *ev = event_info;
863 E_Comp_Object *cw = data;
864 E_Binding_Event_Wheel ev2;
867 if (e_client_action_get()) return;
868 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
869 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
872 /* handle evas mouse down events on client object */
874 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
876 Evas_Event_Mouse_Down *ev = event_info;
877 E_Comp_Object *cw = data;
878 E_Binding_Event_Mouse_Button ev2;
881 if (e_client_action_get()) return;
882 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
883 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
886 /* handle evas mouse up events on client object */
888 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
890 Evas_Event_Mouse_Up *ev = event_info;
891 E_Comp_Object *cw = data;
892 E_Binding_Event_Mouse_Button ev2;
895 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
896 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
897 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
900 /* handle evas mouse movement events on client object */
902 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
904 Evas_Event_Mouse_Move *ev = event_info;
905 E_Comp_Object *cw = data;
908 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
909 e_client_mouse_move(cw->ec, &ev->cur.output);
911 /////////////////////////////////////
913 /* helper function for checking compositor themes based on user-defined matches */
915 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
917 if (((m->title) && (!ec->netwm.name)) ||
918 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
920 #if defined(__cplusplus) || defined(c_plusplus)
921 if (((m->clas) && (!ec->icccm.cpp_class)) ||
922 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
925 if (((m->clas) && (!ec->icccm.class)) ||
926 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
930 if (((m->role) && (!ec->icccm.window_role)) ||
931 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
937 if ((int)ec->netwm.type != m->primary_type)
940 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
943 if (m->borderless != 0)
947 if (e_client_util_borderless(ec))
949 if (!(((m->borderless == -1) && (!borderless)) ||
950 ((m->borderless == 1) && (borderless))))
957 if (((ec->icccm.transient_for != 0) ||
960 if (!(((m->dialog == -1) && (!dialog)) ||
961 ((m->dialog == 1) && (dialog))))
964 if (m->accepts_focus != 0)
966 int accepts_focus = 0;
968 if (ec->icccm.accepts_focus)
970 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
971 ((m->accepts_focus == 1) && (accepts_focus))))
980 if (!(((m->vkbd == -1) && (!vkbd)) ||
981 ((m->vkbd == 1) && (vkbd))))
986 if (!(((m->argb == -1) && (!ec->argb)) ||
987 ((m->argb == 1) && (ec->argb))))
990 if (m->fullscreen != 0)
992 int fullscreen = ec->fullscreen;
994 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
995 ((m->fullscreen == 1) && (fullscreen))))
1000 if (!(m->modal == -1))
1006 /* function for setting up a client's compositor frame theme (cw->shobj) */
1008 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1012 Eina_List *list = NULL, *l;
1013 E_Input_Rect_Data *input_rect_data;
1014 E_Input_Rect_Smart_Data *input_rect_sd;
1016 Eina_Stringshare *reshadow_group = NULL;
1017 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1018 Eina_Stringshare *name, *title;
1019 E_Comp_Config *conf = e_comp_config_get();
1021 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1022 /* match correct client type */
1023 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1024 name = cw->ec->icccm.name;
1025 title = cw->ec->icccm.title;
1026 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1027 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1029 /* skipping here is mostly a hack for systray because I hate it */
1032 EINA_LIST_FOREACH(list, l, m)
1034 if (((m->name) && (!name)) ||
1035 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1037 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1040 no_shadow = m->no_shadow;
1041 if (m->shadow_style)
1043 /* fast effects are just themes with "/fast" appended and shorter effect times */
1046 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1047 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1049 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1051 /* default to non-fast style if fast not available */
1054 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1055 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1057 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1059 if (ok && m->visibility_effect)
1060 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1067 if (skip || (cw->ec->e.state.video))
1069 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1071 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1074 if (conf->shadow_style)
1078 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1079 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1081 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1085 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1086 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1088 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1095 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1097 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1101 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1103 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1108 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1113 if (cw->ec->override)
1115 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1116 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1118 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1119 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1125 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1126 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1129 _e_comp_object_shadow(cw);
1132 if (focus || cw->ec->focused || cw->ec->override)
1133 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1135 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1137 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1139 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1140 /* visibility must always be enabled for re_manage clients to prevent
1141 * pop-in animations every time the user sees a persistent client again;
1142 * applying visibility for iconic clients prevents the client from getting
1145 if (cw->visible || cw->ec->re_manage)
1146 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1148 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1150 /* breaks animation counter */
1151 if (cw->frame_object)
1153 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1154 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1155 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1156 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1162 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1166 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1169 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1171 if (input_rect_data->obj)
1173 pass_event_flag = EINA_TRUE;
1179 if (cw->indicator.obj)
1181 Evas_Object *indicator;
1182 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1183 if (indicator != cw->indicator.obj)
1185 edje_object_part_unswallow(cw->shobj, indicator);
1186 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1187 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1191 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1192 evas_object_pass_events_set(cw->obj, pass_event_flag);
1197 /////////////////////////////////////////////
1200 _e_comp_object_animating_begin(E_Comp_Object *cw)
1203 if (cw->animating == 1)
1205 e_comp->animating++;
1207 e_object_ref(E_OBJECT(cw->ec));
1212 _e_comp_object_animating_end(E_Comp_Object *cw)
1221 if (cw->ec->launching)
1223 if (!cw->ec->extra_animating)
1225 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1226 cw->ec->launching = EINA_FALSE;
1227 if (cw->ec->first_mapped)
1229 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1230 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1233 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1237 e_comp->animating--;
1238 cw->showing = cw->hiding = 0;
1240 if (e_comp->animating == 0)
1241 e_comp_visibility_calculation_set(EINA_TRUE);
1242 /* remove ref from animation start, account for possibility of deletion from unref */
1243 return !!e_object_unref(E_OBJECT(cw->ec));
1249 /* handle the end of a compositor animation */
1251 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1253 E_Comp_Object *cw = data;
1255 /* visible clients which have never been sized are a bug */
1256 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1257 CRI("ACK! ec:%p", cw->ec);
1258 if (!_e_comp_object_animating_end(cw)) return;
1259 if (cw->animating) return;
1260 /* hide only after animation finishes to guarantee a full run of the animation */
1261 if (!cw->defer_hide) return;
1262 if ((!strcmp(emission, "e,action,hide,done")) ||
1263 (!strcmp(emission, "e,action,done")) ||
1264 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1266 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1267 evas_object_hide(cw->smart_obj);
1271 /* run a visibility compositor effect if available, return false if object is dead */
1273 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1279 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1280 if (!cw->effect_running)
1281 _e_comp_object_animating_begin(cw);
1282 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1283 return _e_comp_object_animating_end(cw);
1284 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1285 return _e_comp_object_animating_end(cw);
1287 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1290 zone = e_comp_zone_find_by_ec(cw->ec);
1292 zw = zone->w, zh = zone->h;
1297 zone = e_comp_object_util_zone_get(cw->smart_obj);
1298 if (!zone) zone = e_zone_current_get();
1305 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1306 cw->w, cw->h, zw, zh, x, y}, 8);
1307 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1308 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1311 /////////////////////////////////////////////
1313 /* create necessary objects for clients that e manages */
1315 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1317 if (cw->set_mouse_callbacks) return;
1318 if (!cw->smart_obj) return;
1320 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1321 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1322 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1323 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1324 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1325 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1327 cw->set_mouse_callbacks = EINA_TRUE;
1331 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1333 if (!cw->set_mouse_callbacks) return;
1334 if (!cw->smart_obj) return;
1336 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1337 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1338 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1339 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1340 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1341 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1343 cw->set_mouse_callbacks = EINA_FALSE;
1347 _e_comp_object_setup(E_Comp_Object *cw)
1349 cw->clip = evas_object_rectangle_add(e_comp->evas);
1350 evas_object_move(cw->clip, -9999, -9999);
1351 evas_object_resize(cw->clip, 999999, 999999);
1352 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1353 cw->effect_obj = edje_object_add(e_comp->evas);
1354 evas_object_move(cw->effect_obj, cw->x, cw->y);
1355 evas_object_clip_set(cw->effect_obj, cw->clip);
1356 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1357 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1358 cw->shobj = edje_object_add(e_comp->evas);
1359 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1360 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1361 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1363 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1364 if (cw->ec->override)
1366 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1367 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1368 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1370 else if (!cw->ec->input_only)
1372 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1373 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1374 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1376 cw->real_hid = !cw->ec->input_only;
1377 if (!cw->ec->input_only)
1379 e_util_size_debug_set(cw->effect_obj, 1);
1380 _e_comp_object_mouse_event_callback_set(cw);
1383 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1384 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1385 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1386 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1387 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1388 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1390 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1393 /////////////////////////////////////////////
1395 /* for fast path evas rendering; only called during render */
1397 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1399 E_Comp_Object *cw = data;
1400 E_Client *ec = cw->ec;
1402 int bx, by, bxx, byy;
1404 if (e_object_is_del(E_OBJECT(ec))) return;
1405 if (cw->external_content) return;
1406 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1407 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1410 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1411 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1413 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1415 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1416 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1420 bx = by = bxx = byy = 0;
1421 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1424 Edje_Message_Int_Set *msg;
1425 Edje_Message_Int msg2;
1426 Eina_Bool id = (bx || by || bxx || byy);
1428 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1434 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1436 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1440 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1441 e_comp_client_post_update_add(cw->ec);
1443 else if (e_comp_object_render(ec->frame))
1445 /* apply shape mask if necessary */
1446 if ((!cw->native) && (ec->shaped))
1447 e_comp_object_shape_apply(ec->frame);
1449 /* shaped clients get precise mouse events to handle transparent pixels */
1450 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1452 /* queue another render if client is still dirty; cannot refresh here. */
1453 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1454 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1456 if (cw->render_trace)
1458 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1464 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1466 E_Comp_Object *cw = data;
1467 E_Client *ec = cw->ec;
1469 if (e_object_is_del(E_OBJECT(ec))) return;
1470 if (cw->external_content) return;
1471 if (!e_comp->hwc) return;
1473 e_comp_client_render_list_add(cw->ec);
1475 if (!ec->hwc_window) return;
1477 e_hwc_windows_rendered_window_add(ec->hwc_window);
1480 /////////////////////////////////////////////
1483 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1485 E_Comp_Object *cw = data;
1488 if (cw->render_update_lock.lock)
1490 cw->render_update_lock.pending_move_x = x;
1491 cw->render_update_lock.pending_move_y = y;
1492 cw->render_update_lock.pending_move_set = EINA_TRUE;
1496 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1497 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1498 (cw->external_content))
1500 /* delay to move until the external content is unset */
1501 cw->ec->changes.pos = 1;
1506 if (cw->ec->move_after_resize)
1508 if ((x != cw->ec->x) || (y != cw->ec->y))
1510 if (!cw->ec->is_cursor)
1511 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1512 e_client_pos_set(cw->ec, x, y);
1513 cw->ec->changes.pos = 1;
1519 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1520 (cw->ec->manage_resize.resize_obj))
1522 e_client_pos_set(cw->ec, x, y);
1523 cw->ec->client.x = x + cw->client_inset.l;
1524 cw->ec->client.y = y + cw->client_inset.t;
1525 e_policy_visibility_client_defer_move(cw->ec);
1529 /* if frame_object does not exist, client_inset indicates CSD.
1530 * this means that ec->client matches cw->x/y, the opposite
1533 fx = (!cw->frame_object) * cw->client_inset.l;
1534 fy = (!cw->frame_object) * cw->client_inset.t;
1535 if ((cw->x == x + fx) && (cw->y == y + fy))
1537 if ((cw->ec->x != x) || (cw->ec->y != y))
1539 /* handle case where client tries to move to position and back very quickly */
1540 e_client_pos_set(cw->ec, x, y);
1541 cw->ec->client.x = x + cw->client_inset.l;
1542 cw->ec->client.y = y + cw->client_inset.t;
1546 if (!cw->ec->maximize_override)
1548 /* prevent moving in some directions while directionally maximized */
1549 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1551 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1554 ix = x + cw->client_inset.l;
1555 iy = y + cw->client_inset.t;
1556 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1557 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1558 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1560 /* prevent moving at all if move isn't allowed in current maximize state */
1561 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1562 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1565 zone = e_comp_zone_find_by_ec(cw->ec);
1568 cw->ec->changes.need_unmaximize = 1;
1569 cw->ec->saved.x = ix - zone->x;
1570 cw->ec->saved.y = iy - zone->y;
1571 cw->ec->saved.w = cw->ec->client.w;
1572 cw->ec->saved.h = cw->ec->client.h;
1576 /* only update during resize if triggered by resize */
1577 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1578 /* delay to move while surface waits paired commit serial*/
1579 if (e_client_pending_geometry_has(cw->ec))
1581 /* do nothing while waiting paired commit serial*/
1585 e_client_pos_set(cw->ec, x, y);
1586 if (cw->ec->new_client)
1588 /* don't actually do anything until first client idler loop */
1589 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1590 cw->ec->changes.pos = 1;
1595 /* only update xy position of client to avoid invalid
1596 * first damage region if it is not a new_client. */
1597 cw->ec->client.x = ix;
1598 cw->ec->client.y = iy;
1601 if (!cw->frame_object)
1603 evas_object_move(obj, x, y);
1608 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1610 E_Comp_Object *cw = data;
1611 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1614 if (cw->render_update_lock.lock)
1616 cw->render_update_lock.pending_resize_w = w;
1617 cw->render_update_lock.pending_resize_h = h;
1618 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1622 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1624 e_client_size_set(cw->ec, w, h);
1625 evas_object_resize(obj, w, h);
1629 /* if frame_object does not exist, client_inset indicates CSD.
1630 * this means that ec->client matches cw->w/h, the opposite
1633 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1634 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1635 if ((cw->w == w + fw) && (cw->h == h + fh))
1637 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1638 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1639 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1641 /* handle case where client tries to resize itself and back very quickly */
1642 e_client_size_set(cw->ec, w, h);
1643 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1644 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1645 evas_object_smart_callback_call(obj, "client_resize", NULL);
1649 /* guarantee that fullscreen is fullscreen */
1650 zone = e_comp_zone_find_by_ec(cw->ec);
1652 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1654 if (!e_client_transform_core_enable_get(cw->ec))
1657 /* calculate client size */
1658 iw = w - cw->client_inset.l - cw->client_inset.r;
1659 ih = h - cw->client_inset.t - cw->client_inset.b;
1660 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1662 /* prevent resizing while maximized depending on direction and config */
1663 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1665 Eina_Bool reject = EINA_FALSE;
1666 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1668 if (cw->ec->client.h != ih)
1670 cw->ec->saved.h = ih;
1671 cw->ec->saved.y = cw->ec->client.y - zone->y;
1672 reject = cw->ec->changes.need_unmaximize = 1;
1675 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1677 if (cw->ec->client.w != iw)
1679 cw->ec->saved.w = iw;
1680 cw->ec->saved.x = cw->ec->client.x - zone->x;
1681 reject = cw->ec->changes.need_unmaximize = 1;
1690 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1692 /* do nothing until client idler loops */
1693 if ((cw->ec->w != w) || (cw->ec->h != h))
1695 e_client_size_set(cw->ec, w, h);
1696 cw->ec->changes.size = 1;
1701 if (e_client_pending_geometry_has(cw->ec))
1703 /* do nothing while waiting paired commit serial*/
1707 e_client_size_set(cw->ec, w, h);
1709 cw->ec->client.w = iw;
1710 cw->ec->client.h = ih;
1711 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1713 /* The size of non-compositing window can be changed, so there is a
1714 * need to check that cw is H/W composited if cw is not redirected.
1715 * And of course we have to change size of evas object of H/W composited cw,
1716 * otherwise cw can't receive input events even if it is shown on the screen.
1718 Eina_Bool redirected = cw->redirected;
1720 redirected = e_comp_is_on_overlay(cw->ec);
1722 if ((!cw->ec->input_only) && (redirected) &&
1723 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1724 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1725 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1726 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1729 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1730 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1732 prev_w = cw->w, prev_h = cw->h;
1733 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1734 /* check shading and clamp to pixmap size for regular clients */
1735 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1736 (((w - fw != pw) || (h - fh != ph))))
1738 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1739 evas_object_smart_callback_call(obj, "client_resize", NULL);
1741 if (cw->frame_object || cw->ec->input_only)
1742 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1745 if ((cw->w == w) && (cw->h == h))
1747 /* going to be a noop resize which won't trigger smart resize */
1748 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1749 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1751 evas_object_resize(obj, w, h);
1755 evas_object_smart_callback_call(obj, "client_resize", NULL);
1758 if ((!cw->frame_object) && (!cw->ec->input_only))
1760 /* "just do it" for overrides */
1761 evas_object_resize(obj, w, h);
1763 if (!cw->ec->override)
1765 /* shape probably changed for non-overrides */
1770 /* this fixes positioning jiggles when using a resize mode
1771 * which also changes the client's position
1774 if (cw->frame_object)
1775 x = cw->x, y = cw->y;
1777 x = cw->ec->x, y = cw->ec->y;
1778 switch (cw->ec->resize_mode)
1780 case E_POINTER_RESIZE_BL:
1781 case E_POINTER_RESIZE_L:
1782 evas_object_move(obj, x + prev_w - cw->w, y);
1784 case E_POINTER_RESIZE_TL:
1785 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1787 case E_POINTER_RESIZE_T:
1788 case E_POINTER_RESIZE_TR:
1789 evas_object_move(obj, x, y + prev_h - cw->h);
1798 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1800 E_Comp_Object *cw = data;
1801 E_Comp_Wl_Client_Data *child_cdata;
1802 unsigned int l = e_comp_canvas_layer_map(layer);
1805 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1807 /* doing a compositor effect, follow directions */
1808 _e_comp_object_layer_set(obj, layer);
1809 if (layer == cw->ec->layer) //trying to put layer back
1813 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1814 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1815 if (cw->layer != l) goto layer_set;
1819 e_comp_render_queue();
1821 ec = e_client_above_get(cw->ec);
1822 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1823 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1824 ec = e_client_above_get(ec);
1825 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1827 ec = e_client_below_get(cw->ec);
1828 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1829 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1830 ec = e_client_below_get(ec);
1831 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1833 evas_object_stack_above(obj, ec->frame);
1838 if (ec && (cw->ec->parent == ec))
1840 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1841 evas_object_stack_above(obj, ec->frame);
1843 evas_object_stack_below(obj, ec->frame);
1846 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1852 if (cw->layer == l) return;
1853 if (e_comp_canvas_client_layer_map(layer) == 9999)
1854 return; //invalid layer for clients not doing comp effects
1855 if (cw->ec->fullscreen)
1857 cw->ec->saved.layer = layer;
1860 oldraise = e_config->transient.raise;
1862 /* clamp to valid client layer */
1863 layer = e_comp_canvas_client_layer_map_nearest(layer);
1864 cw->ec->layer = layer;
1865 if (e_config->transient.layer)
1868 Eina_List *list = eina_list_clone(cw->ec->transients);
1870 /* We need to set raise to one, else the child wont
1871 * follow to the new layer. It should be like this,
1872 * even if the user usually doesn't want to raise
1875 e_config->transient.raise = 1;
1876 EINA_LIST_FREE(list, child)
1878 child_cdata = e_client_cdata_get(child);
1879 if (child_cdata && !child_cdata->mapped)
1881 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1884 e_client_layer_set(child, layer);
1888 e_config->transient.raise = oldraise;
1890 _e_comp_object_layers_remove(cw);
1891 cw->layer = e_comp_canvas_layer_map(layer);
1892 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1893 //if (cw->ec->new_client)
1894 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1895 _e_comp_object_layer_set(obj, layer);
1896 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1897 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1898 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1900 /* can't stack a client above its own layer marker */
1901 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1903 if (!cw->visible) return;
1904 e_comp_render_queue();
1905 _e_comp_object_transform_obj_stack_update(obj);
1908 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1911 _e_comp_object_raise(Evas_Object *obj)
1913 evas_object_raise(obj);
1915 if (evas_object_smart_smart_get(obj))
1917 E_Client *ec = e_comp_object_client_get(obj);
1919 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1924 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1926 evas_object_lower(obj);
1928 if (evas_object_smart_smart_get(obj))
1930 E_Client *ec = e_comp_object_client_get(obj);
1933 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1934 wl_signal_emit_mutable(&cw->events.lower, NULL);
1940 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1942 evas_object_stack_above(obj, target);
1944 if (evas_object_smart_smart_get(obj))
1946 E_Client *ec = e_comp_object_client_get(obj);
1948 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1953 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1955 evas_object_stack_below(obj, target);
1957 if (evas_object_smart_smart_get(obj))
1959 E_Client *ec = e_comp_object_client_get(obj);
1961 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1966 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1968 evas_object_layer_set(obj, layer);
1970 if (evas_object_smart_smart_get(obj))
1972 E_Client *ec = e_comp_object_client_get(obj);
1974 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1979 _e_comp_object_is_pending(E_Client *ec)
1983 if (!ec) return EINA_FALSE;
1985 topmost = e_comp_wl_topmost_parent_get(ec);
1987 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1991 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1993 E_Comp_Object *cw2 = NULL;
1996 Evas_Object *o = stack;
1997 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1999 /* We should consider topmost's layer_pending for subsurface */
2000 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2002 if (_e_comp_object_is_pending(cw->ec))
2003 e_comp_object_layer_update(cw->smart_obj,
2004 raising? stack : NULL,
2005 raising? NULL : stack);
2007 /* obey compositor effects! */
2008 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2009 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2010 stack_cb(cw->smart_obj, stack);
2011 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2012 evas_object_data_del(cw->smart_obj, "client_restack");
2016 cw2 = evas_object_data_get(o, "comp_obj");
2018 /* assume someone knew what they were doing during client init */
2019 if (cw->ec->new_client)
2020 layer = cw->ec->layer;
2021 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2022 layer = cw2->ec->layer;
2024 layer = evas_object_layer_get(stack);
2025 ecstack = e_client_below_get(cw->ec);
2026 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2028 evas_object_layer_set(cw->smart_obj, layer);
2029 /* we got our layer wrangled, return now! */
2030 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2033 /* check if we're stacking below another client */
2036 /* check for non-client layer object */
2037 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2039 /* find an existing client to use for layering
2040 * by walking up the object stack
2042 * this is guaranteed to be pretty quick since we'll either:
2043 * - run out of client layers
2044 * - find a stacking client
2046 o = evas_object_above_get(o);
2047 if ((!o) || (o == cw->smart_obj)) break;
2048 if (evas_object_layer_get(o) != layer)
2050 /* reached the top client layer somehow
2051 * use top client object
2053 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2056 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2057 * return here since the top client layer window
2062 ec = e_client_top_get();
2067 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2070 if (cw2 && cw->layer != cw2->layer)
2073 /* remove existing layers */
2074 _e_comp_object_layers_remove(cw);
2077 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2078 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2079 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2080 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2081 else //if no stacking objects found, either raise or lower
2082 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2085 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2087 /* find new object for stacking if cw2 is on state of layer_pending */
2088 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2090 E_Client *new_stack = NULL, *current_ec = NULL;
2091 current_ec = cw2->ec;
2094 while ((new_stack = e_client_below_get(current_ec)))
2096 current_ec = new_stack;
2097 if (new_stack == cw->ec) continue;
2098 if (new_stack->layer != cw2->ec->layer) break;
2099 if (!_e_comp_object_is_pending(new_stack)) break;
2101 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2102 stack = new_stack->frame;
2105 /* stack it above layer object */
2107 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2108 stack = e_comp->layers[below_layer].obj;
2113 while ((new_stack = e_client_above_get(current_ec)))
2115 current_ec = new_stack;
2116 if (new_stack == cw->ec) continue;
2117 if (new_stack->layer != cw2->ec->layer) break;
2118 if (!_e_comp_object_is_pending(new_stack)) break;
2120 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2121 stack = new_stack->frame;
2123 stack = e_comp->layers[cw2->layer].obj;
2127 /* set restack if stacking has changed */
2128 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2129 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2130 stack_cb(cw->smart_obj, stack);
2131 if (e_comp->layers[cw->layer].obj)
2132 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2134 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2136 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2137 evas_object_data_del(cw->smart_obj, "client_restack");
2138 if (!cw->visible) return;
2139 e_comp_render_queue();
2143 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2145 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2147 if (evas_object_below_get(obj) == above)
2149 e_comp_object_layer_update(obj, above, NULL);
2153 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2154 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2155 _e_comp_object_transform_obj_stack_update(obj);
2156 _e_comp_object_transform_obj_stack_update(above);
2161 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2163 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2164 if (evas_object_above_get(obj) == below)
2166 e_comp_object_layer_update(obj, NULL, below);
2170 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2171 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2172 if (evas_object_smart_smart_get(obj))
2173 _e_comp_object_transform_obj_stack_update(obj);
2174 if (evas_object_smart_smart_get(below))
2175 _e_comp_object_transform_obj_stack_update(below);
2180 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2182 E_Comp_Object *cw = data;
2185 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2187 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2189 if (cw->ec->layer_pending)
2190 e_comp_object_layer_update(obj, NULL, obj);
2192 _e_comp_object_lower(cw, obj);
2195 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2196 o = evas_object_below_get(obj);
2197 _e_comp_object_layers_remove(cw);
2198 /* prepend to client list since this client should be the first item now */
2199 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2200 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2201 evas_object_data_set(obj, "client_restack", (void*)1);
2202 _e_comp_object_lower(cw, obj);
2203 evas_object_data_del(obj, "client_restack");
2204 if (!cw->visible) goto end;
2205 e_comp_render_queue();
2206 _e_comp_object_transform_obj_stack_update(obj);
2213 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2215 E_Comp_Object *cw = data;
2219 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2221 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2223 if (cw->ec->layer_pending)
2225 int obj_layer = evas_object_layer_get(obj);
2226 if (cw->ec->layer != obj_layer)
2227 e_comp_object_layer_update(obj, NULL, NULL);
2230 _e_comp_object_raise(obj);
2233 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2234 o = evas_object_above_get(obj);
2235 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2237 /* still stack below override below the layer marker */
2238 for (op = o = e_comp->layers[cw->layer].obj;
2239 o && o != e_comp->layers[cw->layer - 1].obj;
2240 op = o, o = evas_object_below_get(o))
2242 if (evas_object_smart_smart_get(o))
2246 ec = e_comp_object_client_get(o);
2247 if (ec && (!ec->override)) break;
2250 _e_comp_object_stack_below(obj, op);
2251 e_client_focus_defer_set(cw->ec);
2253 if (!cw->visible) goto end;
2254 e_comp_render_queue();
2255 _e_comp_object_transform_obj_stack_update(obj);
2262 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2264 E_Comp_Object *cw = data;
2266 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2267 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2269 ELOGF("COMP", "Hide. intercepted", cw->ec);
2274 if (cw->ec->launching == EINA_TRUE)
2276 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2277 cw->ec->launching = EINA_FALSE;
2282 /* hidden flag = just do it */
2283 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2284 evas_object_hide(obj);
2286 wl_signal_emit_mutable(&cw->events.hide, NULL);
2291 if (cw->ec->input_only)
2293 /* input_only = who cares */
2294 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2295 evas_object_hide(obj);
2297 wl_signal_emit_mutable(&cw->events.hide, NULL);
2301 /* already hidden or currently animating */
2302 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2304 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2308 /* don't try hiding during shutdown */
2309 cw->defer_hide |= stopping;
2310 if (!cw->defer_hide)
2312 if ((!cw->ec->iconic) && (!cw->ec->override))
2313 /* unset delete requested so the client doesn't break */
2314 cw->ec->delete_requested = 0;
2315 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2317 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2318 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2321 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2324 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2326 _e_comp_object_animating_begin(cw);
2327 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2329 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2330 cw->defer_hide = !!cw->animating;
2332 e_comp_object_effect_set(obj, NULL);
2335 if (cw->animating) return;
2336 /* if we have no animations running, go ahead and hide */
2338 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2339 evas_object_hide(obj);
2341 wl_signal_emit_mutable(&cw->events.hide, NULL);
2345 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2347 E_Client *ec = cw->ec;
2350 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2352 if (ec->show_pending.count > 0)
2354 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2355 ec->show_pending.running = EINA_TRUE;
2359 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2360 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2362 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2367 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,
2368 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2369 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2372 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2375 if (ec->iconic && cw->animating)
2377 /* triggered during iconify animation */
2378 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2381 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2384 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2385 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2387 evas_object_move(cw->smart_obj, ec->x, ec->y);
2388 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2389 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2391 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2392 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2395 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2396 evas_object_show(cw->smart_obj);
2399 e_client_focus_defer_set(ec);
2403 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2407 pw = ec->client.w, ph = ec->client.h;
2409 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2411 ec->changes.visible = !ec->hidden;
2414 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2418 cw->updates = eina_tiler_new(pw, ph);
2421 ec->changes.visible = !ec->hidden;
2424 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2429 eina_tiler_tile_size_set(cw->updates, 1, 1);
2432 /* ignore until client idler first run */
2433 ec->changes.visible = !ec->hidden;
2436 ELOGF("COMP", "show_helper. return. new_client", ec);
2443 evas_object_move(cw->smart_obj, ec->x, ec->y);
2444 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2445 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2446 evas_object_show(cw->smart_obj);
2449 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2451 /* start_drag not received */
2452 ec->changes.visible = 1;
2455 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2458 /* re-set geometry */
2459 evas_object_move(cw->smart_obj, ec->x, ec->y);
2460 /* force resize in case it hasn't happened yet, or just to update size */
2461 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2462 if ((cw->w < 1) || (cw->h < 1))
2464 /* if resize didn't go through, try again */
2465 ec->visible = ec->changes.visible = 1;
2467 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2470 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2471 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2472 e_pixmap_clear(ec->pixmap);
2474 if (cw->real_hid && w && h)
2477 /* force comp theming in case it didn't happen already */
2478 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2479 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2480 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2483 /* only do the show if show is allowed */
2486 if (ec->internal) //internal clients render when they feel like it
2487 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2489 if (!e_client_is_iconified_by_client(ec)||
2490 e_policy_visibility_client_is_uniconic(ec))
2492 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2493 evas_object_show(cw->smart_obj);
2495 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2496 it is rendered in idle callback without native surface and
2497 compositor shows an empty frame if other objects aren't shown
2498 because job callback of e_comp called at the next loop.
2499 it causes a visual defect when windows are switched.
2503 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2504 e_comp_object_dirty(cw->smart_obj);
2505 e_comp_object_render(cw->smart_obj);
2510 wl_signal_emit_mutable(&cw->events.show, NULL);
2514 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2516 E_Comp_Object *cw = data;
2517 E_Client *ec = cw->ec;
2519 E_Input_Rect_Data *input_rect_data;
2520 E_Input_Rect_Smart_Data *input_rect_sd;
2523 if (ec->ignored) return;
2527 //INF("SHOW2 %p", ec);
2528 _e_comp_intercept_show_helper(cw);
2531 //INF("SHOW %p", ec);
2534 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2535 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2536 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2537 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2541 if ((!cw->obj) && (cw->external_content))
2543 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2547 _e_comp_object_setup(cw);
2550 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2551 cw->obj = evas_object_image_filled_add(e_comp->evas);
2552 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2553 e_util_size_debug_set(cw->obj, 1);
2554 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2555 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2556 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2557 evas_object_name_set(cw->obj, "cw->obj");
2558 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2560 _e_comp_object_alpha_set(cw);
2563 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2566 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2567 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2570 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2573 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2575 if (input_rect_data->obj)
2577 evas_object_geometry_set(input_rect_data->obj,
2578 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2579 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2580 input_rect_data->rect.w, input_rect_data->rect.h);
2587 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2589 _e_comp_intercept_show_helper(cw);
2593 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2595 E_Comp_Object *cw = data;
2599 /* note: this is here as it seems there are enough apps that do not even
2600 * expect us to emulate a look of focus but not actually set x input
2601 * focus as we do - so simply abort any focus set on such windows */
2602 /* be strict about accepting focus hint */
2603 /* be strict about accepting focus hint */
2604 if ((!ec->icccm.accepts_focus) &&
2605 (!ec->icccm.take_focus))
2609 if (e_client_focused_get() == ec)
2610 e_client_focused_set(NULL);
2612 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2613 evas_object_focus_set(obj, focus);
2617 if (focus && ec->lock_focus_out) return;
2618 if (e_object_is_del(E_OBJECT(ec)) && focus)
2619 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2621 /* filter focus setting based on current state */
2626 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2627 evas_object_focus_set(obj, focus);
2630 if ((ec->iconic) && (!ec->deskshow))
2632 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2634 /* don't focus an iconified window. that's silly! */
2635 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2636 e_client_uniconify(ec);
2637 e_client_focus_latest_set(ec);
2651 /* not yet visible, wait till the next time... */
2652 ec->want_focus = !ec->hidden;
2657 e_client_focused_set(ec);
2661 if (e_client_focused_get() == ec)
2662 e_client_focused_set(NULL);
2666 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2668 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2670 evas_object_focus_set(obj, focus);
2674 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2676 E_Comp_Object *cw = data;
2678 if (cw->transparent.set)
2680 cw->transparent.user_r = r;
2681 cw->transparent.user_g = g;
2682 cw->transparent.user_b = b;
2683 cw->transparent.user_a = a;
2685 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2687 cw->transparent.user_r,
2688 cw->transparent.user_g,
2689 cw->transparent.user_b,
2690 cw->transparent.user_a);
2694 evas_object_color_set(obj, r, g, b, a);
2697 ////////////////////////////////////////////////////
2700 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2702 int w, h, ox, oy, ow, oh;
2704 Eina_Bool pass_event_flag = EINA_FALSE;
2705 E_Input_Rect_Data *input_rect_data;
2706 E_Input_Rect_Smart_Data *input_rect_sd;
2708 if (cw->frame_object)
2710 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2711 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2712 /* set a fixed size, force edje calc, check size difference */
2713 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2714 edje_object_message_signal_process(cw->frame_object);
2715 edje_object_calc_force(cw->frame_object);
2716 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2717 cw->client_inset.l = ox;
2718 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2719 cw->client_inset.t = oy;
2720 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2721 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2722 evas_object_resize(cw->frame_object, w, h);
2726 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2729 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2731 if (input_rect_data->obj)
2733 pass_event_flag = EINA_TRUE;
2739 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2740 evas_object_pass_events_set(cw->obj, pass_event_flag);
2744 cw->client_inset.l = 0;
2745 cw->client_inset.r = 0;
2746 cw->client_inset.t = 0;
2747 cw->client_inset.b = 0;
2749 cw->client_inset.calc = !!cw->frame_object;
2753 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2755 E_Comp_Object *cw = data;
2759 /* - get current size
2761 * - readjust for new frame size
2764 w = cw->ec->w, h = cw->ec->h;
2765 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2767 _e_comp_object_frame_recalc(cw);
2769 if (!cw->ec->fullscreen)
2770 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2772 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2773 if (cw->ec->fullscreen)
2775 zone = e_comp_zone_find_by_ec(cw->ec);
2777 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2779 else if (cw->ec->new_client)
2781 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2782 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2783 evas_object_resize(cw->ec->frame, w, h);
2785 else if ((w != cw->ec->w) || (h != cw->ec->h))
2786 evas_object_resize(cw->ec->frame, w, h);
2790 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2792 E_Comp_Object *cw = data;
2794 _e_comp_object_shadow_setup(cw);
2795 if (cw->frame_object)
2797 _e_comp_object_shadow(cw);
2798 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2799 _e_comp_object_frame_recalc(cw);
2800 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2805 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2807 E_Comp_Object *cw = data;
2809 if (_e_comp_object_shadow_setup(cw))
2810 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2811 if (cw->frame_object)
2813 _e_comp_object_shadow(cw);
2814 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2815 _e_comp_object_frame_recalc(cw);
2816 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2821 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2823 E_Comp_Object *cw = data;
2825 if (cw->frame_object)
2827 _e_comp_object_shadow(cw);
2828 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2829 _e_comp_object_frame_recalc(cw);
2830 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2835 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2837 E_Comp_Object *cw = data;
2839 if (_e_comp_object_shadow_setup(cw))
2842 cw->ec->changes.size = 1;
2844 if (cw->frame_object)
2846 _e_comp_object_shadow(cw);
2847 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2848 _e_comp_object_frame_recalc(cw);
2849 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2854 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2856 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2860 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2862 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2866 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2868 E_Comp_Object *cw = data;
2870 if (!cw->ec) return; //NYI
2871 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2875 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2877 E_Comp_Object *cw = data;
2879 if (!cw->ec) return; //NYI
2880 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2884 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2886 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2890 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2892 E_Comp_Object *cw = data;
2894 if (!e_object_is_del(E_OBJECT(cw->ec)))
2895 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2899 _e_comp_input_obj_smart_add(Evas_Object *obj)
2901 E_Input_Rect_Smart_Data *input_rect_sd;
2902 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2904 if (!input_rect_sd) return;
2905 evas_object_smart_data_set(obj, input_rect_sd);
2909 _e_comp_input_obj_smart_del(Evas_Object *obj)
2911 E_Input_Rect_Smart_Data *input_rect_sd;
2912 E_Input_Rect_Data *input_rect_data;
2914 input_rect_sd = evas_object_smart_data_get(obj);
2915 if (!input_rect_sd) return;
2917 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2919 if (input_rect_data->obj)
2921 evas_object_smart_member_del(input_rect_data->obj);
2922 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2924 E_FREE(input_rect_data);
2926 E_FREE(input_rect_sd);
2930 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2932 E_Input_Rect_Smart_Data *input_rect_sd;
2933 E_Input_Rect_Data *input_rect_data;
2937 input_rect_sd = evas_object_smart_data_get(obj);
2938 if (!input_rect_sd) return;
2940 cw = input_rect_sd->cw;
2941 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2943 if (input_rect_data->obj)
2945 evas_object_geometry_set(input_rect_data->obj,
2946 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2947 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2948 input_rect_data->rect.w, input_rect_data->rect.h);
2954 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2956 E_Input_Rect_Smart_Data *input_rect_sd;
2957 E_Input_Rect_Data *input_rect_data;
2961 input_rect_sd = evas_object_smart_data_get(obj);
2962 if (!input_rect_sd) return;
2964 cw = input_rect_sd->cw;
2965 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2967 if (input_rect_data->obj)
2969 evas_object_geometry_set(input_rect_data->obj,
2970 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2971 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2972 input_rect_data->rect.w, input_rect_data->rect.h);
2978 _e_comp_input_obj_smart_show(Evas_Object *obj)
2980 E_Input_Rect_Smart_Data *input_rect_sd;
2981 E_Input_Rect_Data *input_rect_data;
2984 input_rect_sd = evas_object_smart_data_get(obj);
2985 if (!input_rect_sd) return;
2987 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2989 if (input_rect_data->obj)
2991 evas_object_show(input_rect_data->obj);
2997 _e_comp_input_obj_smart_hide(Evas_Object *obj)
2999 E_Input_Rect_Smart_Data *input_rect_sd;
3000 E_Input_Rect_Data *input_rect_data;
3003 input_rect_sd = evas_object_smart_data_get(obj);
3004 if (!input_rect_sd) return;
3006 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3008 if (input_rect_data->obj)
3010 evas_object_hide(input_rect_data->obj);
3016 _e_comp_input_obj_smart_init(void)
3018 if (_e_comp_input_obj_smart) return;
3020 static const Evas_Smart_Class sc =
3022 INPUT_OBJ_SMART_NAME,
3023 EVAS_SMART_CLASS_VERSION,
3024 _e_comp_input_obj_smart_add,
3025 _e_comp_input_obj_smart_del,
3026 _e_comp_input_obj_smart_move,
3027 _e_comp_input_obj_smart_resize,
3028 _e_comp_input_obj_smart_show,
3029 _e_comp_input_obj_smart_hide,
3042 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3048 _e_comp_smart_add(Evas_Object *obj)
3052 cw = E_NEW(E_Comp_Object, 1);
3053 EINA_SAFETY_ON_NULL_RETURN(cw);
3055 wl_signal_init(&cw->events.lower);
3056 #ifdef REFACTOR_DESK_AREA
3057 wl_signal_init(&cw->events.raise);
3059 wl_signal_init(&cw->events.show);
3060 wl_signal_init(&cw->events.hide);
3061 #ifdef REFACTOR_DESK_AREA
3062 wl_signal_init(&cw->events.set_layer);
3063 wl_signal_init(&cw->events.stack_above);
3064 wl_signal_init(&cw->events.stack_below);
3067 cw->smart_obj = obj;
3068 cw->x = cw->y = cw->w = cw->h = -1;
3069 evas_object_smart_data_set(obj, cw);
3070 cw->opacity = 255.0;
3071 cw->external_content = 0;
3072 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3073 cw->transform_bg_color.r = 0;
3074 cw->transform_bg_color.g = 0;
3075 cw->transform_bg_color.b = 0;
3076 cw->transform_bg_color.a = 255;
3077 evas_object_data_set(obj, "comp_obj", cw);
3078 evas_object_move(obj, -1, -1);
3079 /* intercept ALL the callbacks! */
3080 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3081 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3082 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3083 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3084 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3085 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3086 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3087 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3088 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3089 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3090 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3092 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3093 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3094 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3095 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3097 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3098 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3100 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3101 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3103 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3105 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3106 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3110 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3113 evas_object_color_set(cw->clip, r, g, b, a);
3114 evas_object_smart_callback_call(obj, "color_set", NULL);
3119 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3122 evas_object_clip_set(cw->clip, clip);
3126 _e_comp_smart_clip_unset(Evas_Object *obj)
3129 evas_object_clip_unset(cw->clip);
3133 _e_comp_smart_hide(Evas_Object *obj)
3135 TRACE_DS_BEGIN(COMP:SMART HIDE);
3140 evas_object_hide(cw->clip);
3141 if (cw->input_obj) evas_object_hide(cw->input_obj);
3142 evas_object_hide(cw->effect_obj);
3143 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3144 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3145 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3152 /* unset native surface if current displaying buffer was destroied */
3153 if (!cw->buffer_destroy_listener.notify)
3155 Evas_Native_Surface *ns;
3156 ns = evas_object_image_native_surface_get(cw->obj);
3157 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3158 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3161 if (!cw->ec->input_only)
3163 edje_object_freeze(cw->effect_obj);
3164 edje_object_freeze(cw->shobj);
3165 edje_object_play_set(cw->shobj, 0);
3166 if (cw->frame_object)
3167 edje_object_play_set(cw->frame_object, 0);
3170 e_comp_render_queue(); //force nocomp recheck
3176 _e_comp_smart_show(Evas_Object *obj)
3184 if ((cw->w < 0) || (cw->h < 0))
3185 CRI("ACK! ec:%p", cw->ec);
3187 TRACE_DS_BEGIN(COMP:SMART SHOW);
3189 e_comp_object_map_update(obj);
3191 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3192 evas_object_show(tmp->frame);
3194 evas_object_show(cw->clip);
3195 if (cw->input_obj) evas_object_show(cw->input_obj);
3196 if (!cw->ec->input_only)
3198 edje_object_thaw(cw->effect_obj);
3199 edje_object_thaw(cw->shobj);
3200 edje_object_play_set(cw->shobj, 1);
3201 if (cw->frame_object)
3202 edje_object_play_set(cw->frame_object, 1);
3204 evas_object_show(cw->effect_obj);
3205 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3206 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3207 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3208 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3209 e_comp_render_queue();
3210 if (cw->ec->input_only)
3215 if (cw->ec->iconic && (!cw->ec->new_client))
3217 if (e_client_is_iconified_by_client(cw->ec))
3219 ELOGF("COMP", "Set launching flag..", cw->ec);
3220 cw->ec->launching = EINA_TRUE;
3223 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3225 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3228 ELOGF("COMP", "Set launching flag..", cw->ec);
3229 cw->ec->launching = EINA_TRUE;
3231 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3232 _e_comp_object_animating_begin(cw);
3233 if (!_e_comp_object_effect_visibility_start(cw, 1))
3239 /* ensure some random effect doesn't lock the client offscreen */
3243 e_comp_object_effect_set(obj, NULL);
3246 _e_comp_object_dim_update(cw);
3252 _e_comp_smart_del(Evas_Object *obj)
3258 if (cw->buffer_destroy_listener.notify)
3260 wl_list_remove(&cw->buffer_destroy_listener.link);
3261 cw->buffer_destroy_listener.notify = NULL;
3264 if (cw->tbm_surface)
3266 tbm_surface_internal_unref(cw->tbm_surface);
3267 cw->tbm_surface = NULL;
3270 if (cw->render_update_lock.buffer_ref.buffer)
3272 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3273 cw->ec, cw->render_update_lock.lock);
3274 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3277 e_comp_object_render_update_del(cw->smart_obj);
3278 E_FREE_FUNC(cw->updates, eina_tiler_free);
3279 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3286 EINA_LIST_FREE(cw->obj_mirror, o)
3288 evas_object_image_data_set(o, NULL);
3289 evas_object_freeze_events_set(o, 1);
3290 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3294 _e_comp_object_layers_remove(cw);
3295 l = evas_object_data_get(obj, "comp_object-to_del");
3296 E_FREE_LIST(l, evas_object_del);
3297 _e_comp_object_mouse_event_callback_unset(cw);
3298 evas_object_del(cw->clip);
3299 evas_object_del(cw->obj);
3300 evas_object_del(cw->shobj);
3301 evas_object_del(cw->effect_obj);
3302 evas_object_del(cw->frame_object);
3303 evas_object_del(cw->input_obj);
3304 evas_object_del(cw->mask.obj);
3305 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3306 evas_object_del(cw->transform_bg_obj);
3307 evas_object_del(cw->transform_tranp_obj);
3308 evas_object_del(cw->default_input_obj);
3309 eina_stringshare_del(cw->frame_theme);
3310 eina_stringshare_del(cw->frame_name);
3314 e_comp->animating--;
3316 e_object_unref(E_OBJECT(cw->ec));
3318 cw->ec->frame = NULL;
3323 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3327 cw->x = x, cw->y = y;
3328 evas_object_move(cw->effect_obj, x, y);
3329 evas_object_move(cw->default_input_obj, x, y);
3330 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3332 e_comp_object_map_update(obj);
3336 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3338 Eina_Bool first = EINA_FALSE;
3343 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3345 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3347 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3349 if (cw->w != w || cw->h != h)
3350 e_comp_object_map_update(obj);
3352 first = ((cw->w < 1) || (cw->h < 1));
3353 cw->w = w, cw->h = h;
3357 if (cw->frame_object)
3358 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3361 /* verify pixmap:object size */
3362 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3364 if ((ww != pw) || (hh != ph))
3365 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3367 evas_object_resize(cw->effect_obj, tw, th);
3368 evas_object_resize(cw->default_input_obj, w, h);
3370 evas_object_resize(cw->input_obj, w, h);
3372 evas_object_resize(cw->mask.obj, w, h);
3373 /* resize render update tiler */
3376 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3377 cw->updates_full = 0;
3378 if (cw->updates) eina_tiler_clear(cw->updates);
3382 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3383 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3391 e_comp_render_queue();
3397 _e_comp_smart_init(void)
3399 if (_e_comp_smart) return;
3401 static const Evas_Smart_Class sc =
3404 EVAS_SMART_CLASS_VERSION,
3408 _e_comp_smart_resize,
3411 _e_comp_smart_color_set,
3412 _e_comp_smart_clip_set,
3413 _e_comp_smart_clip_unset,
3423 _e_comp_smart = evas_smart_class_new(&sc);
3428 e_comp_object_init(void)
3430 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3431 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3432 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3433 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3437 e_comp_object_shutdown(void)
3443 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3445 API_ENTRY EINA_FALSE;
3446 return !!cw->force_visible;
3448 /////////////////////////////////////////////////////////
3451 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3454 Eina_Bool comp_object;
3456 comp_object = !!evas_object_data_get(obj, "comp_object");
3461 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3463 e_comp_render_queue();
3465 l = evas_object_data_get(obj, "comp_object-to_del");
3466 E_FREE_LIST(l, evas_object_del);
3470 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3472 if (e_comp_util_object_is_above_nocomp(obj) &&
3473 (!evas_object_data_get(obj, "comp_override")))
3475 evas_object_data_set(obj, "comp_override", (void*)1);
3476 e_comp_override_add();
3481 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3483 Eina_Bool ref = EINA_TRUE;
3484 if (evas_object_visible_get(obj))
3488 d = evas_object_data_del(obj, "comp_hiding");
3490 /* currently trying to hide */
3493 /* already visible */
3497 evas_object_show(obj);
3500 evas_object_ref(obj);
3501 evas_object_data_set(obj, "comp_ref", (void*)1);
3503 edje_object_signal_emit(obj, "e,state,visible", "e");
3504 evas_object_data_set(obj, "comp_showing", (void*)1);
3505 if (e_comp_util_object_is_above_nocomp(obj))
3507 evas_object_data_set(obj, "comp_override", (void*)1);
3508 e_comp_override_add();
3513 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3515 if (!evas_object_visible_get(obj)) return;
3516 /* already hiding */
3517 if (evas_object_data_get(obj, "comp_hiding")) return;
3518 if (!evas_object_data_del(obj, "comp_showing"))
3520 evas_object_ref(obj);
3521 evas_object_data_set(obj, "comp_ref", (void*)1);
3523 edje_object_signal_emit(obj, "e,state,hidden", "e");
3524 evas_object_data_set(obj, "comp_hiding", (void*)1);
3526 if (evas_object_data_del(obj, "comp_override"))
3527 e_comp_override_timed_pop();
3531 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3533 if (!e_util_strcmp(emission, "e,action,hide,done"))
3535 if (!evas_object_data_del(obj, "comp_hiding")) return;
3536 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3537 evas_object_hide(obj);
3538 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3541 evas_object_data_del(obj, "comp_showing");
3542 if (evas_object_data_del(obj, "comp_ref"))
3543 evas_object_unref(obj);
3547 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3553 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3557 E_API E_Comp_Object_Hook *
3558 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3560 E_Comp_Object_Hook *ch;
3562 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3563 ch = E_NEW(E_Comp_Object_Hook, 1);
3564 if (!ch) return NULL;
3565 ch->hookpoint = hookpoint;
3567 ch->data = (void*)data;
3568 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3573 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3576 if (_e_comp_object_hooks_walking == 0)
3578 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3582 _e_comp_object_hooks_delete++;
3585 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3586 E_API E_Comp_Object_Intercept_Hook *
3587 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3589 E_Comp_Object_Intercept_Hook *ch;
3591 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3592 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3593 if (!ch) return NULL;
3594 ch->hookpoint = hookpoint;
3596 ch->data = (void*)data;
3597 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3602 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3605 if (_e_comp_object_intercept_hooks_walking == 0)
3607 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3611 _e_comp_object_intercept_hooks_delete++;
3616 e_comp_object_util_add(Evas_Object *obj)
3620 E_Comp_Config *conf = e_comp_config_get();
3621 Eina_Bool skip = EINA_FALSE;
3627 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3629 name = evas_object_name_get(obj);
3630 vis = evas_object_visible_get(obj);
3631 o = edje_object_add(e_comp->evas);
3632 evas_object_data_set(o, "comp_object", (void*)1);
3634 skip = (!strncmp(name, "noshadow", 8));
3636 evas_object_data_set(o, "comp_object_skip", (void*)1);
3638 if (conf->shadow_style)
3640 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3641 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3644 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3645 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3646 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3648 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3650 evas_object_geometry_get(obj, &x, &y, &w, &h);
3651 evas_object_geometry_set(o, x, y, w, h);
3652 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3654 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3656 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3657 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3658 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3659 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3660 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3661 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3663 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3665 edje_object_part_swallow(o, "e.swallow.content", obj);
3667 _e_comp_object_event_add(o);
3670 evas_object_show(o);
3675 /* utility functions for deleting objects when their "owner" is deleted */
3677 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3682 EINA_SAFETY_ON_NULL_RETURN(to_del);
3683 l = evas_object_data_get(obj, "comp_object-to_del");
3684 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3685 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3686 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3690 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3695 EINA_SAFETY_ON_NULL_RETURN(to_del);
3696 l = evas_object_data_get(obj, "comp_object-to_del");
3698 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3701 /////////////////////////////////////////////////////////
3703 EINTERN Evas_Object *
3704 e_comp_object_client_add(E_Client *ec)
3709 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3710 if (ec->frame) return NULL;
3711 _e_comp_smart_init();
3712 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3713 cw = evas_object_smart_data_get(o);
3714 if (!cw) return NULL;
3715 evas_object_data_set(o, "E_Client", ec);
3718 evas_object_data_set(o, "comp_object", (void*)1);
3720 _e_comp_object_event_add(o);
3725 /* utility functions for getting client inset */
3727 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3730 if (!cw->client_inset.calc)
3736 if (ax) *ax = x - cw->client_inset.l;
3737 if (ay) *ay = y - cw->client_inset.t;
3741 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3744 if (!cw->client_inset.calc)
3750 if (ax) *ax = x + cw->client_inset.l;
3751 if (ay) *ay = y + cw->client_inset.t;
3755 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3758 if (!cw->client_inset.calc)
3764 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3765 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3769 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3772 if (!cw->client_inset.calc)
3778 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3779 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3783 e_comp_object_client_get(Evas_Object *obj)
3788 /* FIXME: remove this when eo is used */
3789 o = evas_object_data_get(obj, "comp_smart_obj");
3791 return e_comp_object_client_get(o);
3792 return cw ? cw->ec : NULL;
3796 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3799 if (cw->frame_extends)
3800 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3805 if (w) *w = cw->ec->w;
3806 if (h) *h = cw->ec->h;
3811 e_comp_object_util_zone_get(Evas_Object *obj)
3813 E_Zone *zone = NULL;
3817 zone = e_comp_zone_find_by_ec(cw->ec);
3822 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3823 zone = e_comp_zone_xy_get(x, y);
3829 e_comp_object_util_center(Evas_Object *obj)
3831 int x, y, w, h, ow, oh;
3836 zone = e_comp_object_util_zone_get(obj);
3837 EINA_SAFETY_ON_NULL_RETURN(zone);
3838 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3839 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3840 ow = cw->ec->w, oh = cw->ec->h;
3842 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3843 x = x + (w - ow) / 2;
3844 y = y + (h - oh) / 2;
3845 evas_object_move(obj, x, y);
3849 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3851 int x, y, w, h, ow, oh;
3854 EINA_SAFETY_ON_NULL_RETURN(on);
3855 evas_object_geometry_get(on, &x, &y, &w, &h);
3856 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3857 ow = cw->ec->w, oh = cw->ec->h;
3859 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3860 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3864 e_comp_object_util_fullscreen(Evas_Object *obj)
3869 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3872 evas_object_move(obj, 0, 0);
3873 evas_object_resize(obj, e_comp->w, e_comp->h);
3878 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3886 ow = cw->w, oh = cw->h;
3888 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3889 zone = e_comp_object_util_zone_get(obj);
3890 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3891 if (x) *x = zx + (zw - ow) / 2;
3892 if (y) *y = zy + (zh - oh) / 2;
3896 e_comp_object_input_objs_del(Evas_Object *obj)
3899 E_Input_Rect_Data *input_rect_data;
3900 E_Input_Rect_Smart_Data *input_rect_sd;
3905 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3906 if (!input_rect_sd) return;
3908 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3910 if (input_rect_data->obj)
3912 evas_object_smart_member_del(input_rect_data->obj);
3913 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3915 E_FREE(input_rect_data);
3920 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3923 E_Input_Rect_Data *input_rect_data = NULL;
3924 E_Input_Rect_Smart_Data *input_rect_sd;
3925 int client_w, client_h;
3927 if (cw->ec->client.w)
3928 client_w = cw->ec->client.w;
3930 client_w = cw->ec->w;
3932 if (cw->ec->client.h)
3933 client_h = cw->ec->client.h;
3935 client_h = cw->ec->h;
3937 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3941 _e_comp_input_obj_smart_init();
3942 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3943 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3944 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3947 input_rect_sd->cw = cw;
3950 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3953 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3954 if (input_rect_data)
3956 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3957 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3961 if ((input_rect_data) &&
3962 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3964 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3965 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3966 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3967 evas_object_clip_set(input_rect_data->obj, cw->clip);
3968 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3969 evas_object_geometry_set(input_rect_data->obj,
3970 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3971 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3972 evas_object_pass_events_set(cw->default_input_obj, 1);
3973 evas_object_pass_events_set(cw->obj, 1);
3976 evas_object_show(input_rect_data->obj);
3977 evas_object_show(cw->input_obj);
3982 evas_object_smart_member_del(cw->input_obj);
3983 E_FREE_FUNC(cw->input_obj, evas_object_del);
3984 evas_object_pass_events_set(cw->default_input_obj, 0);
3985 evas_object_pass_events_set(cw->obj, 0);
3990 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
3993 E_Input_Rect_Smart_Data *input_rect_sd;
3994 E_Input_Rect_Data *input_rect_data;
3997 if (!cw->input_obj) return;
3999 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4002 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4004 *list = eina_list_append(*list, &input_rect_data->rect);
4010 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4013 if (l) *l = cw->client_inset.l;
4014 if (r) *r = cw->client_inset.r;
4015 if (t) *t = cw->client_inset.t;
4016 if (b) *b = cw->client_inset.b;
4019 /* set geometry for CSD */
4021 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4027 if (cw->frame_object)
4028 CRI("ACK! ec:%p", cw->ec);
4029 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4030 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4031 calc = cw->client_inset.calc;
4032 cw->client_inset.calc = l || r || t || b;
4033 eina_stringshare_replace(&cw->frame_theme, "borderless");
4034 if (cw->client_inset.calc)
4036 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4037 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4038 e_client_size_set(cw->ec, tw, th);
4040 else if (cw->ec->maximized || cw->ec->fullscreen)
4042 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4043 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4045 if (!cw->ec->new_client)
4047 if (calc && cw->client_inset.calc)
4049 tx = cw->ec->x - (l - cw->client_inset.l);
4050 ty = cw->ec->y - (t - cw->client_inset.t);
4051 e_client_pos_set(cw->ec, tx, ty);
4053 cw->ec->changes.pos = cw->ec->changes.size = 1;
4056 cw->client_inset.l = l;
4057 cw->client_inset.r = r;
4058 cw->client_inset.t = t;
4059 cw->client_inset.b = b;
4063 e_comp_object_frame_allowed(Evas_Object *obj)
4065 API_ENTRY EINA_FALSE;
4066 return (cw->frame_object || (!cw->client_inset.calc));
4070 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4072 API_ENTRY EINA_FALSE;
4073 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4074 eina_stringshare_replace(&cw->frame_name, name);
4075 if (cw->frame_object)
4076 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4081 e_comp_object_frame_exists(Evas_Object *obj)
4083 API_ENTRY EINA_FALSE;
4084 return !!cw->frame_object;
4088 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4090 Evas_Object *o, *pbg;
4093 Eina_Stringshare *theme;
4095 API_ENTRY EINA_FALSE;
4097 if (!e_util_strcmp(cw->frame_theme, name))
4098 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4099 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4100 return _e_comp_object_shadow_setup(cw);
4101 pbg = cw->frame_object;
4102 theme = eina_stringshare_add(name);
4104 if (cw->frame_object)
4108 w = cw->ec->w, h = cw->ec->h;
4109 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4110 if ((cw->ec->w != w) || (cw->ec->h != h))
4112 cw->ec->changes.size = 1;
4115 E_FREE_FUNC(cw->frame_object, evas_object_del);
4116 if (!name) goto reshadow;
4118 o = edje_object_add(e_comp->evas);
4119 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4120 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4121 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4123 cw->frame_object = NULL;
4125 eina_stringshare_del(cw->frame_theme);
4126 cw->frame_theme = theme;
4131 if (theme != e_config->theme_default_border_style)
4133 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4134 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4138 ok = e_theme_edje_object_set(o, "base/theme/border",
4139 "e/widgets/border/default/border");
4140 if (ok && (theme == e_config->theme_default_border_style))
4142 /* Reset default border style to default */
4143 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4144 e_config_save_queue();
4151 cw->frame_object = o;
4152 eina_stringshare_del(cw->frame_theme);
4153 cw->frame_theme = theme;
4154 evas_object_name_set(o, "cw->frame_object");
4157 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4161 cw->ec->changes.icon = 1;
4167 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4172 _e_comp_object_shadow_setup(cw);
4175 int old_x, old_y, new_x = 0, new_y = 0;
4177 old_x = cw->x, old_y = cw->y;
4179 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4181 new_x = cw->ec->x, new_y = cw->ec->y;
4182 else if (cw->ec->placed || (!cw->ec->new_client))
4184 /* if no previous frame:
4185 * - reapply client_inset
4190 if (cw->ec->changes.size)
4198 zone = e_comp_zone_find_by_ec(cw->ec);
4201 x = cw->ec->client.x, y = cw->ec->client.y;
4202 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4203 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4205 new_x = x, new_y = y;
4208 if (old_x != new_x || old_y != new_y)
4210 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4211 cw->y = cw->x = -99999;
4212 evas_object_move(obj, new_x, new_y);
4216 if (cw->ec->maximized)
4218 cw->ec->changes.need_maximize = 1;
4221 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4222 if (cw->frame_object)
4224 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4227 cw->frame_extends = 0;
4228 evas_object_del(pbg);
4233 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4235 E_Comp_Object_Mover *prov;
4238 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4239 edje_object_signal_emit(cw->shobj, sig, src);
4240 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4241 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4242 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4244 /* start with highest priority callback first */
4245 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4247 if (!e_util_glob_match(sig, prov->sig)) continue;
4248 if (prov->func(prov->data, obj, sig)) break;
4253 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4255 /* FIXME: at some point I guess this should use eo to inherit
4256 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4257 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4260 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4264 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4267 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4271 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4274 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4278 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4281 Eina_Rectangle rect;
4284 if (cw->ec->input_only || (!cw->updates)) return;
4285 if (cw->nocomp) return;
4286 rect.x = x, rect.y = y;
4287 rect.w = w, rect.h = h;
4288 evas_object_smart_callback_call(obj, "damage", &rect);
4290 if (e_comp_is_on_overlay(cw->ec))
4292 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4293 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4294 * E module attempts to block screen update due to the particular policy.
4296 if (e_pixmap_resource_get(cw->ec->pixmap))
4297 cw->hwc_need_update = EINA_TRUE;
4300 /* ignore overdraw */
4301 if (cw->updates_full)
4303 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4304 e_comp_object_render_update_add(obj);
4306 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4307 evas_object_show(cw->smart_obj);
4311 /* clip rect to client surface */
4312 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4313 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4314 /* if rect is the total size of the client after clip, clear the updates
4315 * since this is guaranteed to be the whole region anyway
4317 eina_tiler_area_size_get(cw->updates, &tw, &th);
4318 if ((w > tw) || (h > th))
4320 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4321 eina_tiler_clear(cw->updates);
4322 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4324 tw = cw->ec->client.w, th = cw->ec->client.h;
4326 if ((!x) && (!y) && (w == tw) && (h == th))
4328 eina_tiler_clear(cw->updates);
4329 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4330 cw->updates_full = 1;
4331 cw->update_count = 0;
4334 if (cw->update_count > UPDATE_MAX)
4336 /* this is going to get really dumb, so just update the whole thing */
4337 eina_tiler_clear(cw->updates);
4338 cw->update_count = cw->updates_full = 1;
4339 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4340 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4344 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4345 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4347 cw->updates_exist = 1;
4348 e_comp_object_render_update_add(obj);
4350 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4351 evas_object_show(cw->smart_obj);
4355 e_comp_object_damage_exists(Evas_Object *obj)
4357 API_ENTRY EINA_FALSE;
4358 return cw->updates_exist;
4362 e_comp_object_render_update_add(Evas_Object *obj)
4366 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4367 if (cw->render_update_lock.lock) return;
4368 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4372 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4374 e_comp_render_queue();
4378 e_comp_object_render_update_del(Evas_Object *obj)
4382 if (cw->ec->input_only || (!cw->updates)) return;
4383 if (!cw->update) return;
4385 /* this gets called during comp animating to clear the update flag */
4386 if (e_comp->grabbed) return;
4387 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4388 if (!e_comp->updates)
4390 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4391 if (e_comp->render_animator)
4392 ecore_animator_freeze(e_comp->render_animator);
4397 e_comp_object_shape_apply(Evas_Object *obj)
4401 unsigned int i, *pix, *p;
4405 if (!cw->ec) return; //NYI
4406 if (cw->external_content) return;
4409 if ((cw->ec->shape_rects_num >= 1) &&
4410 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4415 ERR("BUGGER: shape with native surface? cw=%p", cw);
4418 evas_object_image_size_get(cw->obj, &w, &h);
4419 if ((w < 1) || (h < 1)) return;
4422 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4423 _e_comp_object_alpha_set(cw);
4424 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4425 evas_object_image_alpha_set(o, 1);
4427 p = pix = evas_object_image_data_get(cw->obj, 1);
4430 evas_object_image_data_set(cw->obj, pix);
4435 unsigned char *spix, *sp;
4437 spix = calloc(w * h, sizeof(unsigned char));
4439 for (i = 0; i < cw->ec->shape_rects_num; i++)
4443 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4444 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4445 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4446 sp = spix + (w * ry) + rx;
4447 for (py = 0; py < rh; py++)
4449 for (px = 0; px < rw; px++)
4457 for (py = 0; py < h; py++)
4459 for (px = 0; px < w; px++)
4461 unsigned int mask, imask;
4463 mask = ((unsigned int)(*sp)) << 24;
4465 imask |= imask >> 8;
4466 imask |= imask >> 8;
4467 *p = mask | (*p & imask);
4468 //if (*sp) *p = 0xff000000 | *p;
4469 //else *p = 0x00000000;
4478 for (py = 0; py < h; py++)
4480 for (px = 0; px < w; px++)
4484 evas_object_image_data_set(cw->obj, pix);
4485 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4486 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4488 evas_object_image_data_set(o, pix);
4489 evas_object_image_data_update_add(o, 0, 0, w, h);
4491 // don't need to fix alpha chanel as blending
4492 // should be totally off here regardless of
4493 // alpha channel content
4497 _e_comp_object_clear(E_Comp_Object *cw)
4502 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4504 if (cw->render_update_lock.lock) return;
4507 e_pixmap_clear(cw->ec->pixmap);
4509 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4510 evas_object_image_size_set(cw->obj, 1, 1);
4511 evas_object_image_data_set(cw->obj, NULL);
4512 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4514 evas_object_image_size_set(o, 1, 1);
4515 evas_object_image_data_set(o, NULL);
4518 e_comp_object_render_update_del(cw->smart_obj);
4522 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4526 API_ENTRY EINA_FALSE;
4528 if (cw->transparent.set == set)
4533 evas_object_color_get(obj, &r, &g, &b, &a);
4534 evas_object_color_set(obj, 0, 0, 0, 0);
4536 cw->transparent.user_r = r;
4537 cw->transparent.user_g = g;
4538 cw->transparent.user_b = b;
4539 cw->transparent.user_a = a;
4541 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4543 cw->transparent.user_r,
4544 cw->transparent.user_g,
4545 cw->transparent.user_b,
4546 cw->transparent.user_a);
4548 cw->transparent.set = EINA_TRUE;
4552 cw->transparent.set = EINA_FALSE;
4554 evas_object_color_set(obj,
4555 cw->transparent.user_r,
4556 cw->transparent.user_g,
4557 cw->transparent.user_b,
4558 cw->transparent.user_a);
4560 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4562 cw->transparent.user_r,
4563 cw->transparent.user_g,
4564 cw->transparent.user_b,
4565 cw->transparent.user_a);
4571 /* helper function to simplify toggling of redirection for display servers which support it */
4573 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4578 if (cw->redirected == set) return;
4579 cw->redirected = set;
4580 if (cw->external_content) return;
4582 e_comp_object_map_update(obj);
4586 if (cw->updates_exist)
4587 e_comp_object_render_update_add(obj);
4589 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4591 _e_comp_object_transparent_set(obj, EINA_FALSE);
4592 evas_object_smart_callback_call(obj, "redirected", NULL);
4596 _e_comp_object_clear(cw);
4597 _e_comp_object_transparent_set(obj, EINA_TRUE);
4598 evas_object_smart_callback_call(obj, "unredirected", NULL);
4603 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4606 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4608 if (cw->buffer_destroy_listener.notify)
4610 cw->buffer_destroy_listener.notify = NULL;
4611 wl_list_remove(&cw->buffer_destroy_listener.link);
4614 if (e_object_is_del(E_OBJECT(cw->ec)))
4616 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4621 /* if it's current displaying buffer, do not remove its content */
4622 if (!evas_object_visible_get(cw->ec->frame))
4623 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4628 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4633 if (cw->buffer_destroy_listener.notify)
4635 wl_list_remove(&cw->buffer_destroy_listener.link);
4636 cw->buffer_destroy_listener.notify = NULL;
4639 if (cw->tbm_surface)
4641 tbm_surface_internal_unref(cw->tbm_surface);
4642 cw->tbm_surface = NULL;
4647 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4649 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4650 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4652 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4654 tbm_surface_internal_ref(ns->data.tbm.buffer);
4655 cw->tbm_surface = ns->data.tbm.buffer;
4659 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4660 evas_object_image_native_surface_set(cw->obj, ns);
4664 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4666 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4667 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4668 evas_object_image_native_surface_set(o, ns);
4675 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4677 Evas_Native_Surface ns;
4680 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4681 if (cw->ec->input_only) return;
4682 if (cw->external_content) return;
4683 if (cw->render_update_lock.lock) return;
4686 memset(&ns, 0, sizeof(Evas_Native_Surface));
4690 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4691 set = (!cw->ec->shaped);
4693 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4697 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4701 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4704 if (cw->ec->input_only) return;
4707 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4708 _e_comp_object_alpha_set(cw);
4710 e_comp_object_native_surface_set(obj, cw->native);
4711 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4715 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4721 if (cw->blanked == set) return;
4723 _e_comp_object_alpha_set(cw);
4726 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4727 evas_object_image_data_set(cw->obj, NULL);
4731 e_comp_object_native_surface_set(obj, 1);
4732 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4736 _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)
4741 if (!_damage_trace) return;
4745 if (!evas_object_visible_get(cw->obj)) return;
4747 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4749 o = evas_object_rectangle_add(e_comp->evas);
4750 evas_object_layer_set(o, E_LAYER_MAX);
4751 evas_object_name_set(o, "damage_trace");
4752 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4753 evas_object_resize(o, dmg_w, dmg_h);
4754 evas_object_color_set(o, 0, 128, 0, 128);
4755 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4756 evas_object_pass_events_set(o, EINA_TRUE);
4757 evas_object_show(o);
4759 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4761 dmg_w, dmg_h, dmg_x, dmg_y,
4762 origin->w, origin->h, origin->x, origin->y);
4764 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4767 /* mark an object as dirty and setup damages */
4769 e_comp_object_dirty(Evas_Object *obj)
4772 Eina_Rectangle *rect;
4776 Eina_Bool dirty, visible;
4780 if (cw->external_content) return;
4781 if (!cw->redirected) return;
4782 if (cw->render_update_lock.lock)
4784 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4787 /* only actually dirty if pixmap is available */
4788 if (!e_pixmap_resource_get(cw->ec->pixmap))
4790 // e_pixmap_size_get returns last attached buffer size
4791 // eventhough it is destroyed
4792 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4795 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4796 visible = cw->visible;
4797 if (!dirty) w = h = 1;
4798 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4800 evas_object_image_data_set(cw->obj, NULL);
4801 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4802 evas_object_image_size_set(cw->obj, tw, th);
4803 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4804 if (cw->pending_updates)
4805 eina_tiler_area_size_set(cw->pending_updates, w, h);
4806 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4808 evas_object_image_pixels_dirty_set(o, dirty);
4810 evas_object_image_data_set(o, NULL);
4811 evas_object_image_size_set(o, tw, th);
4812 visible |= evas_object_visible_get(o);
4816 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4820 e_comp_object_native_surface_set(obj, 1);
4822 m = _e_comp_object_map_damage_transform_get(cw->ec);
4823 it = eina_tiler_iterator_new(cw->updates);
4824 EINA_ITERATOR_FOREACH(it, rect)
4826 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4827 * of evas engine and doesn't convert damage according to evas_map.
4828 * so damage of evas_object_image use surface coordinate.
4832 int damage_x, damage_y, damage_w, damage_h;
4834 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4835 &damage_x, &damage_y, &damage_w, &damage_h);
4836 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4837 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4841 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4842 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4845 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4846 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4847 if (cw->pending_updates)
4848 eina_tiler_rect_add(cw->pending_updates, rect);
4850 eina_iterator_free(it);
4851 if (m) e_map_free(m);
4852 if (cw->pending_updates)
4853 eina_tiler_clear(cw->updates);
4856 cw->pending_updates = cw->updates;
4857 cw->updates = eina_tiler_new(w, h);
4858 eina_tiler_tile_size_set(cw->updates, 1, 1);
4860 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4861 evas_object_smart_callback_call(obj, "dirty", NULL);
4862 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4863 /* force render if main object is hidden but mirrors are visible */
4864 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4865 e_comp_object_render(obj);
4869 e_comp_object_render(Evas_Object *obj)
4876 API_ENTRY EINA_FALSE;
4878 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4879 if (cw->ec->input_only) return EINA_TRUE;
4880 if (cw->external_content) return EINA_TRUE;
4881 if (cw->native) return EINA_FALSE;
4882 /* if comp object is not redirected state, comp object should not be set by newly committed data
4883 because image size of comp object is 1x1 and it should not be shown on canvas */
4884 if (!cw->redirected) return EINA_TRUE;
4885 if (cw->render_update_lock.lock)
4887 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4890 e_comp_object_render_update_del(obj);
4891 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4893 if (!cw->pending_updates)
4895 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4896 evas_object_image_data_set(cw->obj, NULL);
4897 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4898 evas_object_image_data_set(o, NULL);
4902 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4904 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4906 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4909 e_pixmap_image_refresh(cw->ec->pixmap);
4910 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4913 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4914 e_pixmap_image_data_ref(cw->ec->pixmap);
4916 /* set pixel data */
4917 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4918 _e_comp_object_alpha_set(cw);
4919 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4921 evas_object_image_data_set(o, pix);
4922 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4923 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4926 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4928 e_comp_client_post_update_add(cw->ec);
4933 /* create a duplicate of an evas object */
4935 e_comp_object_util_mirror_add(Evas_Object *obj)
4939 unsigned int *pix = NULL;
4940 Eina_Bool argb = EINA_FALSE;
4945 cw = evas_object_data_get(obj, "comp_mirror");
4948 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4949 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4950 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4951 evas_object_image_alpha_set(o, 1);
4952 evas_object_image_source_set(o, obj);
4955 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4956 if (cw->external_content)
4958 ERR("%p of client %p is external content.", obj, cw->ec);
4961 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4962 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4963 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4964 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4965 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4966 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4967 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4968 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4969 evas_object_data_set(o, "comp_mirror", cw);
4971 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4972 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4974 evas_object_image_size_set(o, tw, th);
4977 pix = evas_object_image_data_get(cw->obj, 0);
4983 evas_object_image_native_surface_set(o, cw->ns);
4986 Evas_Native_Surface ns;
4987 memset(&ns, 0, sizeof(Evas_Native_Surface));
4988 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
4989 evas_object_image_native_surface_set(o, &ns);
4994 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
4995 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
4997 (e_pixmap_image_exists(cw->ec->pixmap)))
4998 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5000 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5007 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5008 evas_object_image_pixels_dirty_set(o, dirty);
5009 evas_object_image_data_set(o, pix);
5010 evas_object_image_data_set(cw->obj, pix);
5012 evas_object_image_data_update_add(o, 0, 0, tw, th);
5017 //////////////////////////////////////////////////////
5020 e_comp_object_effect_allowed_get(Evas_Object *obj)
5022 API_ENTRY EINA_FALSE;
5024 if (!cw->shobj) return EINA_FALSE;
5025 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5026 return !e_comp_config_get()->match.disable_borders;
5029 /* setup an api effect for a client */
5031 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5034 Eina_Stringshare *grp;
5035 E_Comp_Config *config;
5036 Eina_Bool loaded = EINA_FALSE;
5038 API_ENTRY EINA_FALSE;
5039 if (!cw->shobj) return EINA_FALSE; //input window
5041 if (!effect) effect = "none";
5042 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5044 config = e_comp_config_get();
5045 if ((config) && (config->effect_file))
5047 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5049 cw->effect_set = EINA_TRUE;
5056 edje_object_file_get(cw->effect_obj, NULL, &grp);
5057 cw->effect_set = !eina_streq(effect, "none");
5058 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5059 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5061 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5062 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5063 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5065 if (cw->effect_running)
5067 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5070 cw->effect_set = EINA_FALSE;
5071 return cw->effect_set;
5075 if (cw->effect_running)
5077 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5080 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5081 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5082 if (cw->effect_clip)
5084 evas_object_clip_unset(cw->clip);
5085 cw->effect_clip = 0;
5087 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5089 _e_comp_object_dim_update(cw);
5091 return cw->effect_set;
5094 /* set params for embryo scripts in effect */
5096 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5098 Edje_Message_Int_Set *msg;
5102 EINA_SAFETY_ON_NULL_RETURN(params);
5103 EINA_SAFETY_ON_FALSE_RETURN(count);
5104 if (!cw->effect_set) return;
5106 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5107 msg->count = (int)count;
5108 for (x = 0; x < count; x++)
5109 msg->val[x] = params[x];
5110 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5111 edje_object_message_signal_process(cw->effect_obj);
5115 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5117 Edje_Signal_Cb end_cb;
5119 E_Comp_Object *cw = data;
5121 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5122 cw->effect_running = 0;
5123 if (!_e_comp_object_animating_end(cw)) return;
5125 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5127 evas_object_data_del(cw->smart_obj, "effect_running");
5128 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5129 e_comp_visibility_calculation_set(EINA_TRUE);
5132 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5133 if (!end_cb) return;
5134 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5135 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5136 end_cb(end_data, cw->smart_obj, emission, source);
5139 /* clip effect to client's zone */
5141 e_comp_object_effect_clip(Evas_Object *obj)
5145 zone = e_comp_zone_find_by_ec(cw->ec);
5147 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5148 if (!cw->effect_clip_able) return;
5149 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5150 cw->effect_clip = 1;
5153 /* unclip effect from client's zone */
5155 e_comp_object_effect_unclip(Evas_Object *obj)
5158 if (!cw->effect_clip) return;
5159 evas_object_clip_unset(cw->smart_obj);
5160 cw->effect_clip = 0;
5163 /* start effect, running end_cb after */
5165 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5167 API_ENTRY EINA_FALSE;
5168 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5169 if (!cw->effect_set) return EINA_FALSE;
5171 if (cw->effect_running)
5173 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5176 e_comp_object_effect_clip(obj);
5177 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5179 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5180 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5181 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5182 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5184 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5185 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5187 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5188 _e_comp_object_animating_begin(cw);
5189 cw->effect_running = 1;
5193 /* stop a currently-running effect immediately */
5195 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5198 Edje_Signal_Cb end_cb_before = NULL;
5199 void *end_data_before = NULL;
5200 API_ENTRY EINA_FALSE;
5202 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5203 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5205 if (end_cb_before != end_cb) return EINA_TRUE;
5206 e_comp_object_effect_unclip(obj);
5207 if (cw->effect_clip)
5209 evas_object_clip_unset(cw->effect_obj);
5210 cw->effect_clip = 0;
5212 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5213 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5215 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5217 evas_object_data_del(cw->smart_obj, "effect_running");
5218 e_comp_visibility_calculation_set(EINA_TRUE);
5221 cw->effect_running = 0;
5222 ret = _e_comp_object_animating_end(cw);
5224 if ((ret) && (end_cb_before))
5226 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5227 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5234 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5236 return a->pri - b->pri;
5239 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5240 E_API E_Comp_Object_Mover *
5241 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5243 E_Comp_Object_Mover *prov;
5245 prov = E_NEW(E_Comp_Object_Mover, 1);
5246 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5247 prov->func = provider;
5248 prov->data = (void*)data;
5251 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5252 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5257 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5259 EINA_SAFETY_ON_NULL_RETURN(prov);
5260 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5265 e_comp_object_effect_object_get(Evas_Object *obj)
5269 return cw->effect_obj;
5273 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5275 API_ENTRY EINA_FALSE;
5276 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5277 if (!cw->effect_set) return EINA_FALSE;
5284 ////////////////////////////////////
5287 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5289 if (e_comp->autoclose.obj)
5291 e_comp_ungrab_input(0, 1);
5292 if (e_comp->autoclose.del_cb)
5293 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5294 else if (!already_del)
5296 evas_object_hide(e_comp->autoclose.obj);
5297 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5299 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5301 e_comp->autoclose.obj = NULL;
5302 e_comp->autoclose.data = NULL;
5303 e_comp->autoclose.del_cb = NULL;
5304 e_comp->autoclose.key_cb = NULL;
5305 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5309 _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)
5311 _e_comp_object_autoclose_cleanup(0);
5315 _e_comp_object_autoclose_setup(Evas_Object *obj)
5317 if (!e_comp->autoclose.rect)
5319 /* create rect just below autoclose object to catch mouse events */
5320 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5321 evas_object_move(e_comp->autoclose.rect, 0, 0);
5322 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5323 evas_object_show(e_comp->autoclose.rect);
5324 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5325 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5326 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5327 e_comp_grab_input(0, 1);
5329 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5330 evas_object_focus_set(obj, 1);
5334 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5336 _e_comp_object_autoclose_setup(obj);
5337 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5341 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5343 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5344 _e_comp_object_autoclose_cleanup(1);
5345 if (e_client_focused_get()) return;
5347 E_Zone *zone = e_zone_current_get();
5350 e_zone_focus_reset(zone);
5354 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5358 if (e_comp->autoclose.obj)
5360 if (e_comp->autoclose.obj == obj) return;
5361 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5362 e_comp->autoclose.obj = obj;
5363 e_comp->autoclose.del_cb = del_cb;
5364 e_comp->autoclose.key_cb = cb;
5365 e_comp->autoclose.data = (void*)data;
5366 if (evas_object_visible_get(obj))
5367 _e_comp_object_autoclose_setup(obj);
5369 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5370 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5373 e_comp->autoclose.obj = obj;
5374 e_comp->autoclose.del_cb = del_cb;
5375 e_comp->autoclose.key_cb = cb;
5376 e_comp->autoclose.data = (void*)data;
5377 if (evas_object_visible_get(obj))
5378 _e_comp_object_autoclose_setup(obj);
5380 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5381 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5385 e_comp_object_is_animating(Evas_Object *obj)
5389 return cw->animating;
5393 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5397 if ((cw->external_content) &&
5398 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5400 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5401 "But current external content is %d object for %p.",
5402 cw->content_type, cw->ec);
5406 cw->user_alpha_set = EINA_TRUE;
5407 cw->user_alpha = alpha;
5409 if (!cw->obj) return;
5411 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5413 evas_object_image_alpha_set(cw->obj, alpha);
5415 if ((!cw->native) && (!cw->external_content))
5416 evas_object_image_data_set(cw->obj, NULL);
5420 e_comp_object_alpha_get(Evas_Object *obj)
5422 API_ENTRY EINA_FALSE;
5424 return evas_object_image_alpha_get(cw->obj);
5428 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5430 Eina_Bool mask_set = EINA_FALSE;
5434 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5435 if (cw->ec->input_only) return;
5442 o = evas_object_rectangle_add(e_comp->evas);
5443 evas_object_color_set(o, 0, 0, 0, 0);
5444 evas_object_clip_set(o, cw->clip);
5445 evas_object_smart_member_add(o, obj);
5446 evas_object_move(o, 0, 0);
5447 evas_object_resize(o, cw->w, cw->h);
5448 /* save render op value to restore when clear a mask.
5450 * NOTE: DO NOT change the render op on ec->frame while mask object
5451 * is set. it will overwrite the changed op value. */
5452 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5453 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5454 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5455 if (cw->visible) evas_object_show(o);
5458 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5459 ELOGF("COMP", " |mask_obj", cw->ec);
5460 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5467 evas_object_smart_member_del(cw->mask.obj);
5468 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5470 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5471 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5477 e_comp_object_mask_has(Evas_Object *obj)
5479 API_ENTRY EINA_FALSE;
5481 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5485 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5490 if ((cw->external_content) &&
5491 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5493 WRN("Can set up size to ONLY evas \"image\" object. "
5494 "But current external content is %d object for %p.",
5495 cw->content_type, cw->ec);
5499 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5501 evas_object_image_size_set(cw->obj, tw, th);
5505 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5507 Eina_Bool transform_set = EINA_FALSE;
5509 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5510 if (cw->ec->input_only) return;
5512 transform_set = !!set;
5516 if (!cw->transform_bg_obj)
5518 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5519 evas_object_move(o, 0, 0);
5520 evas_object_resize(o, 1, 1);
5521 if (cw->transform_bg_color.a >= 255)
5522 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5524 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5525 evas_object_color_set(o,
5526 cw->transform_bg_color.r,
5527 cw->transform_bg_color.g,
5528 cw->transform_bg_color.b,
5529 cw->transform_bg_color.a);
5530 if (cw->visible) evas_object_show(o);
5532 cw->transform_bg_obj = o;
5533 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5535 _e_comp_object_transform_obj_stack_update(obj);
5539 if (cw->transform_bg_obj)
5541 evas_object_smart_member_del(cw->transform_bg_obj);
5542 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5548 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5552 cw->transform_bg_color.r = r;
5553 cw->transform_bg_color.g = g;
5554 cw->transform_bg_color.b = b;
5555 cw->transform_bg_color.a = a;
5557 if (cw->transform_bg_obj)
5559 evas_object_color_set(cw->transform_bg_obj,
5560 cw->transform_bg_color.r,
5561 cw->transform_bg_color.g,
5562 cw->transform_bg_color.b,
5563 cw->transform_bg_color.a);
5568 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5571 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5572 if (cw->ec->input_only) return;
5573 if (!cw->transform_bg_obj) return;
5575 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5579 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5582 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5583 if (cw->ec->input_only) return;
5584 if (!cw->transform_bg_obj) return;
5586 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5590 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5592 Eina_Bool transform_set = EINA_FALSE;
5594 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5595 if (cw->ec->input_only) return;
5597 transform_set = !!set;
5601 if (!cw->transform_tranp_obj)
5603 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5604 evas_object_move(o, 0, 0);
5605 evas_object_resize(o, 1, 1);
5606 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5607 evas_object_color_set(o, 0, 0, 0, 0);
5608 if (cw->visible) evas_object_show(o);
5610 cw->transform_tranp_obj = o;
5611 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5612 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5613 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5615 _e_comp_object_transform_obj_stack_update(obj);
5619 if (cw->transform_tranp_obj)
5621 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5622 evas_object_smart_member_del(cw->transform_tranp_obj);
5623 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5629 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5632 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5633 if (cw->ec->input_only) return;
5634 if (!cw->transform_tranp_obj) return;
5636 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5640 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5643 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5644 if (cw->ec->input_only) return;
5645 if (!cw->transform_tranp_obj) return;
5647 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5651 e_comp_object_layer_update(Evas_Object *obj,
5652 Evas_Object *above, Evas_Object *below)
5654 E_Comp_Object *cw2 = NULL;
5655 Evas_Object *o = NULL;
5660 if (cw->ec->layer_block) return;
5661 if ((above) && (below))
5663 ERR("Invalid layer update request! cw=%p", cw);
5671 layer = evas_object_layer_get(o);
5672 cw2 = evas_object_data_get(o, "comp_obj");
5675 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5677 o = evas_object_above_get(o);
5678 if ((!o) || (o == cw->smart_obj)) break;
5679 if (evas_object_layer_get(o) != layer)
5681 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5686 ec = e_client_top_get();
5687 if (ec) o = ec->frame;
5690 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5694 _e_comp_object_layers_remove(cw);
5697 if (cw2->layer > cw->layer)
5698 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5699 else if (cw2->layer == cw->layer)
5702 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5704 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5706 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5709 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5712 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5716 e_comp_object_layer_get(Evas_Object *obj)
5723 e_comp_object_content_set(Evas_Object *obj,
5724 Evas_Object *content,
5725 E_Comp_Object_Content_Type type)
5727 API_ENTRY EINA_FALSE;
5729 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5730 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5731 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5735 ERR("Can't set e.swallow.content to requested content. "
5736 "Previous comp object should not be changed at all.");
5740 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5742 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5743 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5745 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5746 type, content, cw->ec, cw->ec->pixmap);
5750 cw->external_content = EINA_TRUE;
5753 cw->content_type = type;
5754 e_util_size_debug_set(cw->obj, 1);
5755 evas_object_name_set(cw->obj, "cw->obj");
5756 _e_comp_object_alpha_set(cw);
5759 _e_comp_object_shadow_setup(cw);
5765 e_comp_object_content_unset(Evas_Object *obj)
5767 API_ENTRY EINA_FALSE;
5769 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5770 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5772 if (!cw->obj && !cw->ec->visible)
5774 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5778 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5780 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5786 if (cw->frame_object)
5787 edje_object_part_unswallow(cw->frame_object, cw->obj);
5789 edje_object_part_unswallow(cw->shobj, cw->obj);
5791 evas_object_del(cw->obj);
5792 evas_object_hide(cw->obj);
5796 cw->external_content = EINA_FALSE;
5797 if (cw->ec->is_cursor)
5800 DBG("%p is cursor surface..", cw->ec);
5801 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5803 evas_object_resize(cw->ec->frame, pw, ph);
5804 evas_object_hide(cw->ec->frame);
5809 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5810 cw->obj = evas_object_image_filled_add(e_comp->evas);
5811 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5812 e_util_size_debug_set(cw->obj, 1);
5813 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5814 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5815 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5816 evas_object_name_set(cw->obj, "cw->obj");
5817 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5818 _e_comp_object_alpha_set(cw);
5821 _e_comp_object_shadow_setup(cw);
5826 _e_comp_intercept_show_helper(cw);
5830 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5831 e_comp_object_dirty(cw->smart_obj);
5832 e_comp_object_render(cw->smart_obj);
5833 e_comp_object_render_update_add(obj);
5838 EINTERN Evas_Object *
5839 e_comp_object_content_get(Evas_Object *obj)
5843 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5845 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5847 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5854 E_API E_Comp_Object_Content_Type
5855 e_comp_object_content_type_get(Evas_Object *obj)
5857 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5859 return cw->content_type;
5863 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5866 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5867 E_Comp_Config *conf = e_comp_config_get();
5868 if (cw->ec->input_only) return;
5869 if (!conf->dim_rect_enable) return;
5871 cw->dim.mask_set = mask_set;
5877 if (!cw->dim.enable) return;
5878 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5882 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5884 Eina_Bool mask_set = EINA_FALSE;
5888 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5889 E_Comp_Config *conf = e_comp_config_get();
5890 if (cw->ec->input_only) return;
5891 if (!conf->dim_rect_enable) return;
5897 if (cw->dim.mask_obj)
5899 evas_object_smart_member_del(cw->dim.mask_obj);
5900 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5903 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);
5904 o = evas_object_rectangle_add(e_comp->evas);
5905 evas_object_color_set(o, 0, 0, 0, 0);
5906 evas_object_smart_member_add(o, obj);
5907 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5908 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5910 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5911 if (cw->visible) evas_object_show(o);
5913 cw->dim.mask_obj = o;
5914 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5916 evas_object_layer_set(cw->dim.mask_obj, 9998);
5920 if (cw->dim.mask_obj)
5922 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5923 evas_object_smart_member_del(cw->dim.mask_obj);
5924 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5930 e_comp_object_dim_client_set(E_Client *ec)
5932 E_Comp_Config *conf = e_comp_config_get();
5934 if (!conf->dim_rect_enable) return ;
5935 if (dim_client == ec) return;
5937 Eina_Bool prev_dim = EINA_FALSE;
5938 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5940 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5941 prev_dim = EINA_TRUE;
5943 if (prev_dim && dim_client->visible && ec)
5945 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5946 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5950 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5951 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5957 e_comp_object_dim_client_get(void)
5959 E_Comp_Config *conf = e_comp_config_get();
5961 if (!conf->dim_rect_enable ) return NULL;
5967 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
5970 char emit[32] = "\0";
5971 E_Comp_Config *conf = e_comp_config_get();
5974 if (!conf->dim_rect_enable) return;
5975 if (!cw->effect_obj) return;
5976 if (enable == cw->dim.enable) return;
5978 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
5979 if (noeffect || !conf->dim_rect_effect)
5981 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
5985 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
5988 cw->dim.enable = enable;
5990 if (cw->dim.mask_set && !enable)
5992 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5993 edje_object_signal_emit(cw->effect_obj, emit, "e");
5995 else if (cw->dim.mask_set && enable)
5997 edje_object_signal_emit(cw->effect_obj, emit, "e");
5998 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6002 edje_object_signal_emit(cw->effect_obj, emit, "e");
6007 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6009 API_ENTRY EINA_FALSE;
6010 E_Comp_Config *conf = e_comp_config_get();
6012 if (!ec) return EINA_FALSE;
6013 if (!conf->dim_rect_enable) return EINA_FALSE;
6015 if (cw->dim.enable) return EINA_TRUE;
6021 _e_comp_object_dim_update(E_Comp_Object *cw)
6023 E_Comp_Config *conf = e_comp_config_get();
6026 if (!conf->dim_rect_enable) return;
6027 if (!cw->effect_obj) return;
6030 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6031 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6033 if (cw->dim.mask_set)
6035 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6041 e_comp_object_clear(Evas_Object *obj)
6045 _e_comp_object_clear(cw);
6049 e_comp_object_hwc_update_exists(Evas_Object *obj)
6051 API_ENTRY EINA_FALSE;
6052 return cw->hwc_need_update;
6057 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6060 cw->hwc_need_update = set;
6064 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6066 API_ENTRY EINA_FALSE;
6067 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6071 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6074 if (cw->indicator.obj != indicator)
6075 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6076 cw->indicator.obj = indicator;
6077 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6081 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6084 if (cw->indicator.obj != indicator) return;
6085 cw->indicator.obj = NULL;
6086 edje_object_part_unswallow(cw->shobj, indicator);
6090 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6093 Edje_Message_Int_Set *msg;
6095 if (!cw->indicator.obj) return;
6097 cw->indicator.w = w;
6098 cw->indicator.h = h;
6100 if (!cw->shobj) return;
6102 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6106 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6107 edje_object_message_signal_process(cw->shobj);
6110 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6112 e_comp_object_map_update(Evas_Object *obj)
6115 E_Client *ec = cw->ec;
6116 E_Comp_Wl_Client_Data *cdata;
6118 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6121 int l, remain = sizeof buffer;
6124 if (e_object_is_del(E_OBJECT(ec))) return;
6125 cdata = e_client_cdata_get(ec);
6128 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6129 * when new buffer is attached.
6131 if (!cdata->buffer_ref.buffer) return;
6133 if ((!cw->redirected) ||
6134 (e_client_video_hw_composition_check(ec)) ||
6135 (!e_comp_wl_output_buffer_transform_get(ec) &&
6136 cdata->scaler.buffer_viewport.buffer.scale == 1))
6138 if (evas_object_map_enable_get(cw->effect_obj))
6140 ELOGF("TRANSFORM", "map: disable", cw->ec);
6141 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6142 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6143 evas_object_resize(cw->effect_obj, tw, th);
6150 EINA_SAFETY_ON_NULL_RETURN(map);
6152 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6158 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6160 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6161 e_map_point_image_uv_set(map, 0, x, y);
6162 l = snprintf(p, remain, "%d,%d", x, y);
6163 p += l, remain -= l;
6165 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6166 e_map_point_image_uv_set(map, 1, x, y);
6167 l = snprintf(p, remain, " %d,%d", x, y);
6168 p += l, remain -= l;
6170 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6171 e_map_point_image_uv_set(map, 2, x, y);
6172 l = snprintf(p, remain, " %d,%d", x, y);
6173 p += l, remain -= l;
6175 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6176 e_map_point_image_uv_set(map, 3, x, y);
6177 l = snprintf(p, remain, " %d,%d", x, y);
6178 p += l, remain -= l;
6180 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6182 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6184 e_comp_object_map_set(cw->effect_obj, map);
6185 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6189 /* if there's screen rotation with comp mode, then ec->effect_obj and
6190 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6192 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6193 evas_object_resize(cw->effect_obj, tw, th);
6197 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6199 API_ENTRY EINA_FALSE;
6201 cw->render_trace = set;
6207 e_comp_object_native_usable_get(Evas_Object *obj)
6209 API_ENTRY EINA_FALSE;
6210 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6212 if (cw->ec->input_only) return EINA_FALSE;
6213 if (cw->external_content) return EINA_FALSE;
6214 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6216 /* just return true value, if it is normal case */
6217 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6220 Evas_Native_Surface *ns;
6221 ns = evas_object_image_native_surface_get(cw->obj);
6223 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6226 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6234 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6236 API_ENTRY EINA_FALSE;
6237 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6238 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6239 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6243 case E_COMP_IMAGE_FILTER_BLUR:
6244 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6246 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6247 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6249 case E_COMP_IMAGE_FILTER_INVERSE:
6250 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6252 case E_COMP_IMAGE_FILTER_NONE:
6254 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6258 cw->image_filter = filter;
6263 EINTERN E_Comp_Image_Filter
6264 e_comp_object_image_filter_get(Evas_Object *obj)
6266 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6267 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6268 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6269 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6271 return cw->image_filter;
6275 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6279 if (!_damage_trace) return;
6281 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6282 evas_object_del(obj);
6284 _damage_trace_post_objs = NULL;
6288 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6290 if (!_damage_trace) return;
6292 _damage_trace_post_objs = _damage_trace_objs;
6293 _damage_trace_objs = NULL;
6297 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6299 if (_damage_trace == onoff) return;
6303 evas_event_callback_add(e_comp->evas,
6304 EVAS_CALLBACK_RENDER_PRE,
6305 _e_comp_object_damage_trace_render_pre_cb,
6308 evas_event_callback_add(e_comp->evas,
6309 EVAS_CALLBACK_RENDER_POST,
6310 _e_comp_object_damage_trace_render_post_cb,
6317 EINA_LIST_FREE(_damage_trace_objs, obj)
6318 evas_object_del(obj);
6320 _damage_trace_objs = NULL;
6322 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6323 evas_object_del(obj);
6325 _damage_trace_post_objs = NULL;
6327 evas_event_callback_del(e_comp->evas,
6328 EVAS_CALLBACK_RENDER_PRE,
6329 _e_comp_object_damage_trace_render_pre_cb);
6331 evas_event_callback_del(e_comp->evas,
6332 EVAS_CALLBACK_RENDER_POST,
6333 _e_comp_object_damage_trace_render_post_cb);
6336 _damage_trace = onoff;
6340 e_comp_object_redirected_get(Evas_Object *obj)
6342 API_ENTRY EINA_FALSE;
6343 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6345 return cw->redirected;
6349 e_comp_object_color_visible_get(Evas_Object *obj)
6351 API_ENTRY EINA_FALSE;
6354 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6356 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6360 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6364 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6368 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6376 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6378 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6380 return e_map_set_to_comp_object(em, obj);
6384 e_comp_object_map_get(const Evas_Object *obj)
6386 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6388 return e_map_get_from_comp_object(obj);
6392 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6394 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6396 evas_object_map_enable_set(obj, enable);
6402 e_comp_object_render_update_lock(Evas_Object *obj)
6404 E_Comp_Wl_Buffer *buffer;
6405 struct wayland_tbm_client_queue *cqueue;
6407 API_ENTRY EINA_FALSE;
6409 if (cw->render_update_lock.lock == 0)
6411 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6413 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6414 if ((buffer) && (buffer->resource))
6416 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6418 wayland_tbm_server_client_queue_flush(cqueue);
6421 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6422 e_comp_object_render_update_del(obj);
6424 ELOGF("COMP", "Render update lock enabled", cw->ec);
6427 cw->render_update_lock.lock++;
6433 e_comp_object_render_update_unlock(Evas_Object *obj)
6437 if (cw->render_update_lock.lock == 0)
6440 cw->render_update_lock.lock--;
6442 if (cw->render_update_lock.lock == 0)
6445 if (cw->render_update_lock.pending_move_set)
6447 evas_object_move(obj,
6448 cw->render_update_lock.pending_move_x,
6449 cw->render_update_lock.pending_move_y);
6450 cw->render_update_lock.pending_move_x = 0;
6451 cw->render_update_lock.pending_move_y = 0;
6452 cw->render_update_lock.pending_move_set = EINA_FALSE;
6455 if (cw->render_update_lock.pending_resize_set)
6457 evas_object_resize(obj,
6458 cw->render_update_lock.pending_resize_w,
6459 cw->render_update_lock.pending_resize_h);
6460 cw->render_update_lock.pending_resize_w = 0;
6461 cw->render_update_lock.pending_resize_h = 0;
6462 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6465 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6467 if ((cw->ec->exp_iconify.buffer_flush) &&
6468 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6469 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6470 e_comp_object_clear(obj);
6472 e_comp_object_render_update_add(obj);
6474 ELOGF("COMP", "Render update lock disabled", cw->ec);
6479 e_comp_object_render_update_lock_get(Evas_Object *obj)
6481 API_ENTRY EINA_FALSE;
6483 if (cw->render_update_lock.lock > 0)
6490 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6494 if (cw->transparent.set)
6496 if (r) *r = cw->transparent.user_r;
6497 if (g) *g = cw->transparent.user_g;
6498 if (b) *b = cw->transparent.user_b;
6499 if (a) *a = cw->transparent.user_a;
6503 evas_object_color_get(obj, r, g, b, a);
6508 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6512 evas_object_render_op_set(cw->obj, op);
6515 EINTERN Evas_Render_Op
6516 e_comp_object_render_op_get(Evas_Object *obj)
6518 API_ENTRY EVAS_RENDER_BLEND;
6520 return evas_object_render_op_get(cw->obj);
6524 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6527 wl_signal_add(&cw->events.lower, listener);
6530 #ifdef REFACTOR_DESK_AREA
6532 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6535 wl_signal_add(&cw->events.raise, listener);
6540 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6543 wl_signal_add(&cw->events.show, listener);
6547 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6550 wl_signal_add(&cw->events.hide, listener);
6553 #ifdef REFACTOR_DESK_AREA
6555 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6558 wl_signal_add(&cw->events.set_layer, listener);
6562 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6565 wl_signal_add(&cw->events.stack_above, listener);
6569 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6572 wl_signal_add(&cw->events.stack_below, listener);