2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
5 #include "e_bindings_intern.h"
6 #include "e_utils_intern.h"
7 #ifdef REFACTOR_DESK_AREA
9 #include "e_comp_canvas_intern.h"
12 #include "e_comp_cfdata_intern.h"
13 #include "e_comp_wl_subsurface_intern.h"
14 #include "e_comp_wl_tbm_intern.h"
15 #include "e_comp_intern.h"
16 #include "e_pixmap_intern.h"
17 #include "e_map_intern.h"
21 = keys that return objects =
22 - E_Client: the client associated with the object (E_Client*)
23 - comp_smart_obj: cw->smart_obj (Evas_Object*)
24 - comp_obj: cw (E_Comp_Object*)
26 = keys that are bool flags =
27 - client_restack: client needs a protocol-level restack
28 - comp_override: object is triggering a nocomp override to force compositing
29 - comp_ref: object has a ref from visibility animations
30 - comp_showing: object is currently running its show animation
31 - comp_hiding: object is currently running its hiding animation
32 - comp_object: object is a compositor-created object
33 - comp_object_skip: object has a name which prohibits theme shadows
34 - comp_object-to_del: list of objects which will be deleted when this object is deleted
35 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
36 - effect_running: object is animating by external module
39 #define UPDATE_MAX 512 // same as evas
40 #define FAILURE_MAX 2 // seems reasonable
41 #define SMART_NAME "e_comp_object"
42 #define INPUT_OBJ_SMART_NAME "input_object"
44 /* for non-util functions */
45 #define API_ENTRY E_Comp_Object *cw; \
46 cw = evas_object_smart_data_get(obj); \
47 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
49 /* for util functions (obj may or may not be E_Comp_Object */
50 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
53 CRI("YOU PASSED NULL! ARGH!"); \
56 cw = evas_object_smart_data_get(obj); \
57 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
59 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
61 /* enable for lots of client size info in console output */
63 # define e_util_size_debug_set(x, y)
66 /* enable along with display-specific damage INF calls to enable render tracing
70 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
72 #define RENDER_DEBUG(...)
75 #ifdef REFACTOR_DESK_AREA
77 typedef struct _E_Comp_Object
81 int x, y, w, h; // geometry
85 E_Comp_Object_Frame client_inset;
87 Eina_Stringshare *frame_theme;
88 Eina_Stringshare *frame_name;
89 Eina_Stringshare *visibility_effect; //effect when toggling visibility
91 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
93 Evas_Object *smart_obj; // smart object
94 Evas_Object *clip; // clipper over effect object
95 Evas_Object *input_obj; // input smart object
96 Evas_Object *obj; // composite object
97 Evas_Object *frame_object; // for client frames
98 Evas_Object *shobj; // shadow object
99 Evas_Object *effect_obj; // effects object
100 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
104 } transform_bg_color;
105 Evas_Object *transform_tranp_obj;// transform transp rect obj
106 Evas_Object *default_input_obj; // default input object
107 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
108 Eina_List *obj_mirror; // extra mirror objects
109 Eina_Tiler *updates; //render update regions
110 Eina_Tiler *pending_updates; //render update regions which are about to render
112 Evas_Native_Surface *ns; //for custom gl rendering
114 struct wl_listener buffer_destroy_listener;
116 unsigned int update_count; // how many updates have happened to this obj
118 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
120 unsigned int animating; // it's busy animating
121 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
122 unsigned int force_visible; //number of visible obj_mirror objects
123 Eina_Bool delete_pending : 1; // delete pending
124 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
125 Eina_Bool showing : 1; // object is currently in "show" animation
126 Eina_Bool hiding : 1; // object is currently in "hide" animation
127 Eina_Bool visible : 1; // is visible
129 Eina_Bool shaped : 1; // is shaped
130 Eina_Bool update : 1; // has updates to fetch
131 Eina_Bool redirected : 1; // has updates to fetch
132 Eina_Bool native : 1; // native
134 Eina_Bool nocomp : 1; // nocomp applied
135 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
136 Eina_Bool real_hid : 1; // last hide was a real window unmap
138 Eina_Bool effect_set : 1; //effect_obj has a valid group
139 Eina_Bool effect_running : 1; //effect_obj is playing an animation
140 Eina_Bool effect_clip : 1; //effect_obj is clipped
141 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
143 Eina_Bool updates_exist : 1;
144 Eina_Bool updates_full : 1; // entire object will be updated
146 Eina_Bool force_move : 1;
147 Eina_Bool frame_extends : 1; //frame may extend beyond object size
148 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
149 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
150 Eina_Bool user_alpha_set : 1;
151 Eina_Bool user_alpha : 1;
155 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
156 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
163 } indicator; //indicator object for internal client
167 Evas_Object *mask_obj;
170 int mask_x, mask_y, mask_w, mask_h;
173 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
175 tbm_surface_h tbm_surface;
176 E_Comp_Image_Filter image_filter;
177 Eina_Bool set_mouse_callbacks;
182 E_Comp_Wl_Buffer_Ref buffer_ref;
183 Eina_Bool pending_move_set;
184 int pending_move_x, pending_move_y;
185 Eina_Bool pending_resize_set;
186 int pending_resize_w, pending_resize_h;
187 } render_update_lock;
200 struct wl_signal lower;
201 //#ifdef REFACTOR_DESK_AREA
202 struct wl_signal raise;
204 struct wl_signal show;
205 struct wl_signal hide;
206 //#ifdef REFACTOR_DESK_AREA
207 struct wl_signal set_layer;
208 struct wl_signal stack_above;
209 struct wl_signal stack_below;
215 typedef struct _E_Input_Rect_Data
221 typedef struct _E_Input_Rect_Smart_Data
223 Eina_List *input_rect_data_list;
225 } E_Input_Rect_Smart_Data;
227 struct E_Comp_Object_Mover
230 E_Comp_Object_Mover_Cb func;
236 static Eina_Inlist *_e_comp_object_movers = NULL;
237 static Evas_Smart *_e_comp_smart = NULL;
238 static Evas_Smart *_e_comp_input_obj_smart = NULL;
240 static int _e_comp_object_hooks_delete = 0;
241 static int _e_comp_object_hooks_walking = 0;
243 static Eina_Inlist *_e_comp_object_hooks[] =
245 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
246 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
247 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
248 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
249 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
250 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
251 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
252 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
255 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
256 static int _e_comp_object_intercept_hooks_delete = 0;
257 static int _e_comp_object_intercept_hooks_walking = 0;
259 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
261 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
262 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
266 static Eina_Bool _damage_trace = EINA_FALSE;
267 static Eina_List *_damage_trace_objs = NULL;
268 static Eina_List *_damage_trace_post_objs = NULL;
270 /* sekrit functionzzz */
271 EINTERN void e_client_focused_set(E_Client *ec);
273 /* emitted every time a new noteworthy comp object is added */
274 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
276 /* ecore event define */
277 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
278 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
279 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
281 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
282 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
283 static void _e_comp_object_dim_update(E_Comp_Object *cw);
284 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
285 #ifdef REFACTOR_DESK_AREA
287 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
290 static E_Client *dim_client = NULL;
293 _e_comp_object_hooks_clean(void)
296 E_Comp_Object_Hook *ch;
299 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
300 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
302 if (!ch->delete_me) continue;
303 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
309 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
311 E_Comp_Object_Hook *ch;
312 Eina_Bool ret = EINA_TRUE;
314 if (e_object_is_del(E_OBJECT(ec)))
316 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
317 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
318 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
319 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
320 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
321 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
322 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
323 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
329 e_object_ref(E_OBJECT(ec));
330 _e_comp_object_hooks_walking++;
331 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
333 if (ch->delete_me) continue;
334 if (!(ch->func(ch->data, ec)))
340 _e_comp_object_hooks_walking--;
341 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
342 _e_comp_object_hooks_clean();
344 e_object_unref(E_OBJECT(ec));
349 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
351 _e_comp_object_intercept_hooks_clean(void)
354 E_Comp_Object_Intercept_Hook *ch;
357 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
358 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
360 if (!ch->delete_me) continue;
361 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
367 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
369 E_Comp_Object_Intercept_Hook *ch;
370 Eina_Bool ret = EINA_TRUE;
372 if (e_object_is_del(E_OBJECT(ec))) return ret;
373 e_object_ref(E_OBJECT(ec));
374 _e_comp_object_intercept_hooks_walking++;
375 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
377 if (ch->delete_me) continue;
378 if (!(ch->func(ch->data, ec)))
384 _e_comp_object_intercept_hooks_walking--;
385 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
386 _e_comp_object_intercept_hooks_clean();
388 e_object_unref(E_OBJECT(ec));
395 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
397 E_Event_Comp_Object *ev = event;
400 ec = evas_object_data_get(ev->comp_object, "E_Client");
404 e_object_unref(E_OBJECT(ec));
406 evas_object_unref(ev->comp_object);
411 _e_comp_object_event_add(Evas_Object *obj)
413 E_Event_Comp_Object *ev;
416 if (stopping) return;
417 ev = E_NEW(E_Event_Comp_Object, 1);
418 EINA_SAFETY_ON_NULL_RETURN(ev);
420 evas_object_ref(obj);
421 ev->comp_object = obj;
422 ec = evas_object_data_get(ev->comp_object, "E_Client");
426 e_object_ref(E_OBJECT(ec));
428 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
432 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
434 E_Event_Comp_Object *ev = event;
437 ec = evas_object_data_get(ev->comp_object, "E_Client");
441 e_object_unref(E_OBJECT(ec));
443 evas_object_unref(ev->comp_object);
448 _e_comp_object_event_simple(Evas_Object *obj, int type)
450 E_Event_Comp_Object *ev;
453 ev = E_NEW(E_Event_Comp_Object, 1);
456 evas_object_ref(obj);
457 ev->comp_object = obj;
458 ec = evas_object_data_get(ev->comp_object, "E_Client");
462 e_object_ref(E_OBJECT(ec));
464 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
466 /////////////////////////////////////
469 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
471 E_Comp_Object *cw = data;
473 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
477 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
479 E_Comp_Object *cw = data;
481 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
482 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
485 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
486 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
490 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
492 E_Comp_Object *cw = data;
495 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
496 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
499 /////////////////////////////////////
501 #ifdef REFACTOR_DESK_AREA
503 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
506 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
511 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
512 if (cw->ec->input_only) return;
514 layer = evas_object_layer_get(obj);
516 if (cw->transform_bg_obj)
518 if (layer != evas_object_layer_get(cw->transform_bg_obj))
520 evas_object_layer_set(cw->transform_bg_obj, layer);
523 evas_object_stack_below(cw->transform_bg_obj, obj);
526 if (cw->transform_tranp_obj)
528 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
530 evas_object_layer_set(cw->transform_tranp_obj, layer);
533 evas_object_stack_below(cw->transform_tranp_obj, obj);
538 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
545 if (!map) return NULL;
547 e_map_util_points_populate_from_object_full(map, obj, 0);
548 e_map_util_points_color_set(map, 255, 255, 255, 255);
550 for (i = 0 ; i < 4 ; ++i)
555 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
556 e_map_point_coord_set(map, i, x, y, 1.0);
563 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
569 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
572 e_comp_object_map_set(obj, map);
573 e_comp_object_map_enable_set(obj, EINA_TRUE);
580 evas_object_map_enable_set(obj, EINA_FALSE);
585 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
591 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
594 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
596 e_comp_object_map_set(obj, map);
597 e_comp_object_map_enable_set(obj, EINA_TRUE);
604 evas_object_map_enable_set(obj, EINA_FALSE);
607 /////////////////////////////////////
609 static inline Eina_Bool
610 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
612 if (num > 1) return EINA_TRUE;
613 if ((rects[0].x == 0) && (rects[0].y == 0) &&
614 ((int)rects[0].w == w) && ((int)rects[0].h == h))
619 /////////////////////////////////////
621 /* add a client to the layer-client list */
622 #ifdef REFACTOR_DESK_AREA
625 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
627 g_rec_mutex_lock(&e_comp->ec_list_mutex);
630 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));
632 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));
633 if ((!above) && (!below))
636 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
637 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
638 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
640 e_comp->layers[cw->layer].clients_count++;
642 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
646 _e_comp_object_layers_remove(E_Comp_Object *cw)
648 g_rec_mutex_lock(&e_comp->ec_list_mutex);
650 if (cw->ec && e_comp->layers[cw->layer].clients)
652 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
653 e_comp->layers[cw->layer].clients_count--;
656 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
660 /////////////////////////////////////
662 _e_comp_object_alpha_set(E_Comp_Object *cw)
664 Eina_Bool alpha = cw->ec->argb;
666 if ((cw->external_content) &&
667 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
672 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
673 if (cw->user_alpha_set) alpha = cw->user_alpha;
675 evas_object_image_alpha_set(cw->obj, alpha);
679 _e_comp_object_shadow(E_Comp_Object *cw)
681 if (e_client_util_shadow_state_get(cw->ec))
682 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
684 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
685 if (cw->frame_object)
686 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
687 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
690 /* convert from the surface coordinates to the buffer coordinates */
692 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
694 E_Comp_Wl_Buffer_Viewport *vp;
695 E_Comp_Wl_Client_Data *cdata;
699 cdata = e_client_cdata_get(ec);
701 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
708 vp = &cdata->scaler.buffer_viewport;
709 transform = e_comp_wl_output_buffer_transform_get(ec);
711 e_pixmap_size_get(ec->pixmap, &bw, &bh);
713 /* for subsurface, it should be swap 90 and 270 */
714 if (e_comp_wl_subsurface_check(ec))
717 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
718 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
719 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
726 case WL_OUTPUT_TRANSFORM_NORMAL:
727 default: tx = sx, ty = sy; break;
728 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
729 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
730 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
731 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
732 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
733 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
734 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
737 tx *= vp->buffer.scale;
738 ty *= vp->buffer.scale;
745 _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)
753 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
754 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
761 if (dw) *dw = MAX(x1, x2) - mx;
762 if (dh) *dh = MAX(y1, y2) - my;
766 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
767 int *dx, int *dy, int *dw, int *dh)
769 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
770 E_Util_Transform_Rect_Vertex sv, dv;
774 e_pixmap_size_get(ec->pixmap, &bw, &bh);
776 sv = e_util_transform_rect_to_vertices(&rect);
778 for (i = 0; i < 4; i++)
780 double x = 0.0, y = 0.0;
782 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
784 /* if evas decide coordinate is outside of map, it returns (0, 0)
785 in this case, full damage is added.
787 if ((i != 0) && (x == 0.0) && (y == 0.0))
790 dv.vertices[i].vertex[0] = x;
791 dv.vertices[i].vertex[1] = y;
792 dv.vertices[i].vertex[2] = 1.0;
793 dv.vertices[i].vertex[3] = 1.0;
796 rect = e_util_transform_vertices_to_rect(&dv);
798 if (dx) *dx = rect.x;
799 if (dy) *dy = rect.y;
800 if (dw) *dw = rect.w;
801 if (dh) *dh = rect.h;
815 _e_comp_object_map_damage_transform_get(E_Client *ec)
822 if (!e_client_transform_core_enable_get(ec))
825 m = e_client_map_get(ec);
829 e_pixmap_size_get(ec->pixmap, &bw, &bh);
830 if ((bw == 0) || (bh == 0))
843 e_map_point_coord_set(m2, 0, 0, 0, 0);
844 e_map_point_coord_set(m2, 1, bw, 0, 0);
845 e_map_point_coord_set(m2, 2, bw, bh, 0);
846 e_map_point_coord_set(m2, 3, 0, bh, 0);
848 for (i = 0; i < 4; i++)
852 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
853 e_map_point_image_uv_set(m2, i, map_x, map_y);
860 /////////////////////////////////////
862 /* handle evas mouse-in events on client object */
864 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
866 Evas_Event_Mouse_In *ev = event_info;
867 E_Comp_Object *cw = data;
869 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
872 /* handle evas mouse-out events on client object */
874 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
876 Evas_Event_Mouse_Out *ev = event_info;
877 E_Comp_Object *cw = data;
879 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
882 /* handle evas mouse wheel events on client object */
884 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
886 Evas_Event_Mouse_Wheel *ev = event_info;
887 E_Comp_Object *cw = data;
888 E_Binding_Event_Wheel ev2;
891 if (e_client_action_get()) return;
892 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
893 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
896 /* handle evas mouse down events on client object */
898 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
900 Evas_Event_Mouse_Down *ev = event_info;
901 E_Comp_Object *cw = data;
902 E_Binding_Event_Mouse_Button ev2;
905 if (e_client_action_get()) return;
906 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
907 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
910 /* handle evas mouse up events on client object */
912 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
914 Evas_Event_Mouse_Up *ev = event_info;
915 E_Comp_Object *cw = data;
916 E_Binding_Event_Mouse_Button ev2;
919 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
920 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
921 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
924 /* handle evas mouse movement events on client object */
926 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
928 Evas_Event_Mouse_Move *ev = event_info;
929 E_Comp_Object *cw = data;
932 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
933 e_client_mouse_move(cw->ec, &ev->cur.output);
935 /////////////////////////////////////
937 /* helper function for checking compositor themes based on user-defined matches */
939 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
941 if (((m->title) && (!ec->netwm.name)) ||
942 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
944 #if defined(__cplusplus) || defined(c_plusplus)
945 if (((m->clas) && (!ec->icccm.cpp_class)) ||
946 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
949 if (((m->clas) && (!ec->icccm.class)) ||
950 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
954 if (((m->role) && (!ec->icccm.window_role)) ||
955 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
961 if ((int)ec->netwm.type != m->primary_type)
964 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
967 if (m->borderless != 0)
971 if (e_client_util_borderless(ec))
973 if (!(((m->borderless == -1) && (!borderless)) ||
974 ((m->borderless == 1) && (borderless))))
981 if (((ec->icccm.transient_for != 0) ||
984 if (!(((m->dialog == -1) && (!dialog)) ||
985 ((m->dialog == 1) && (dialog))))
988 if (m->accepts_focus != 0)
990 int accepts_focus = 0;
992 if (ec->icccm.accepts_focus)
994 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
995 ((m->accepts_focus == 1) && (accepts_focus))))
1004 if (!(((m->vkbd == -1) && (!vkbd)) ||
1005 ((m->vkbd == 1) && (vkbd))))
1010 if (!(((m->argb == -1) && (!ec->argb)) ||
1011 ((m->argb == 1) && (ec->argb))))
1014 if (m->fullscreen != 0)
1016 int fullscreen = ec->fullscreen;
1018 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1019 ((m->fullscreen == 1) && (fullscreen))))
1024 if (!(m->modal == -1))
1030 /* function for setting up a client's compositor frame theme (cw->shobj) */
1032 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1036 Eina_List *list = NULL, *l;
1037 E_Input_Rect_Data *input_rect_data;
1038 E_Input_Rect_Smart_Data *input_rect_sd;
1040 Eina_Stringshare *reshadow_group = NULL;
1041 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1042 Eina_Stringshare *name, *title;
1043 E_Comp_Config *conf = e_comp_config_get();
1045 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1046 /* match correct client type */
1047 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1048 name = cw->ec->icccm.name;
1049 title = cw->ec->icccm.title;
1050 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1051 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1053 /* skipping here is mostly a hack for systray because I hate it */
1056 EINA_LIST_FOREACH(list, l, m)
1058 if (((m->name) && (!name)) ||
1059 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1061 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1064 no_shadow = m->no_shadow;
1065 if (m->shadow_style)
1067 /* fast effects are just themes with "/fast" appended and shorter effect times */
1070 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1071 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1073 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1075 /* default to non-fast style if fast not available */
1078 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1079 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1081 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1083 if (ok && m->visibility_effect)
1084 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1091 if (skip || (cw->ec->e.state.video))
1093 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1095 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1098 if (conf->shadow_style)
1102 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1103 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1105 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1109 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1110 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1112 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1119 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1121 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1125 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1127 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1132 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1137 if (cw->ec->override)
1139 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1140 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1142 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1143 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1149 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1150 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1153 _e_comp_object_shadow(cw);
1156 if (focus || cw->ec->focused || cw->ec->override)
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1161 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1163 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1164 /* visibility must always be enabled for re_manage clients to prevent
1165 * pop-in animations every time the user sees a persistent client again;
1166 * applying visibility for iconic clients prevents the client from getting
1169 if (cw->visible || cw->ec->re_manage)
1170 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1172 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1174 /* breaks animation counter */
1175 if (cw->frame_object)
1177 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1178 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1179 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1186 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1190 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1193 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1195 if (input_rect_data->obj)
1197 pass_event_flag = EINA_TRUE;
1203 if (cw->indicator.obj)
1205 Evas_Object *indicator;
1206 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1207 if (indicator != cw->indicator.obj)
1209 edje_object_part_unswallow(cw->shobj, indicator);
1210 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1211 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1215 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1216 evas_object_pass_events_set(cw->obj, pass_event_flag);
1221 /////////////////////////////////////////////
1224 _e_comp_object_animating_begin(E_Comp_Object *cw)
1227 if (cw->animating == 1)
1229 e_comp->animating++;
1231 e_object_ref(E_OBJECT(cw->ec));
1236 _e_comp_object_animating_end(E_Comp_Object *cw)
1245 if (cw->ec->launching)
1247 if (!cw->ec->extra_animating)
1249 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1250 cw->ec->launching = EINA_FALSE;
1251 if (cw->ec->first_mapped)
1253 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1254 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1257 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1261 e_comp->animating--;
1262 cw->showing = cw->hiding = 0;
1264 if (e_comp->animating == 0)
1265 e_comp_visibility_calculation_set(EINA_TRUE);
1266 /* remove ref from animation start, account for possibility of deletion from unref */
1267 return !!e_object_unref(E_OBJECT(cw->ec));
1273 /* handle the end of a compositor animation */
1275 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1277 E_Comp_Object *cw = data;
1279 /* visible clients which have never been sized are a bug */
1280 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1281 CRI("ACK! ec:%p", cw->ec);
1282 if (!_e_comp_object_animating_end(cw)) return;
1283 if (cw->animating) return;
1284 /* hide only after animation finishes to guarantee a full run of the animation */
1285 if (!cw->defer_hide) return;
1286 if ((!strcmp(emission, "e,action,hide,done")) ||
1287 (!strcmp(emission, "e,action,done")) ||
1288 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1290 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1291 evas_object_hide(cw->smart_obj);
1295 /* run a visibility compositor effect if available, return false if object is dead */
1297 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1303 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1304 if (!cw->effect_running)
1305 _e_comp_object_animating_begin(cw);
1306 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1307 return _e_comp_object_animating_end(cw);
1308 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1309 return _e_comp_object_animating_end(cw);
1311 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1314 zone = e_comp_zone_find_by_ec(cw->ec);
1316 zw = zone->w, zh = zone->h;
1321 zone = e_comp_object_util_zone_get(cw->smart_obj);
1322 if (!zone) zone = e_zone_current_get();
1329 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1330 cw->w, cw->h, zw, zh, x, y}, 8);
1331 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1332 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1335 /////////////////////////////////////////////
1337 /* create necessary objects for clients that e manages */
1339 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1341 if (cw->set_mouse_callbacks) return;
1342 if (!cw->smart_obj) return;
1344 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1345 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1346 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1348 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1351 cw->set_mouse_callbacks = EINA_TRUE;
1355 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1357 if (!cw->set_mouse_callbacks) return;
1358 if (!cw->smart_obj) return;
1360 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1361 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1362 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1364 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1367 cw->set_mouse_callbacks = EINA_FALSE;
1371 _e_comp_object_setup(E_Comp_Object *cw)
1373 cw->clip = evas_object_rectangle_add(e_comp->evas);
1374 evas_object_move(cw->clip, -9999, -9999);
1375 evas_object_resize(cw->clip, 999999, 999999);
1376 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1377 cw->effect_obj = edje_object_add(e_comp->evas);
1378 evas_object_move(cw->effect_obj, cw->x, cw->y);
1379 evas_object_clip_set(cw->effect_obj, cw->clip);
1380 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1381 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1382 cw->shobj = edje_object_add(e_comp->evas);
1383 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1384 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1385 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1387 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1388 if (cw->ec->override)
1390 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1391 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1392 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1394 else if (!cw->ec->input_only)
1396 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1397 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1398 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1400 cw->real_hid = !cw->ec->input_only;
1401 if (!cw->ec->input_only)
1403 e_util_size_debug_set(cw->effect_obj, 1);
1404 _e_comp_object_mouse_event_callback_set(cw);
1407 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1408 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1409 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1410 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1411 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1412 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1414 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1417 /////////////////////////////////////////////
1419 /* for fast path evas rendering; only called during render */
1421 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1423 E_Comp_Object *cw = data;
1424 E_Client *ec = cw->ec;
1426 int bx, by, bxx, byy;
1428 if (e_object_is_del(E_OBJECT(ec))) return;
1429 if (cw->external_content) return;
1430 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1431 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1434 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1435 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1437 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1439 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1440 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1444 bx = by = bxx = byy = 0;
1445 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1448 Edje_Message_Int_Set *msg;
1449 Edje_Message_Int msg2;
1450 Eina_Bool id = (bx || by || bxx || byy);
1452 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1458 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1460 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1464 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1465 e_comp_client_post_update_add(cw->ec);
1467 else if (e_comp_object_render(ec->frame))
1469 /* apply shape mask if necessary */
1470 if ((!cw->native) && (ec->shaped))
1471 e_comp_object_shape_apply(ec->frame);
1473 /* shaped clients get precise mouse events to handle transparent pixels */
1474 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1476 /* queue another render if client is still dirty; cannot refresh here. */
1477 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1478 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1480 if (cw->render_trace)
1482 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1488 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1490 E_Comp_Object *cw = data;
1491 E_Client *ec = cw->ec;
1493 if (e_object_is_del(E_OBJECT(ec))) return;
1494 if (cw->external_content) return;
1495 if (!e_comp->hwc) return;
1497 e_comp_client_render_list_add(cw->ec);
1499 if (!ec->hwc_window) return;
1501 e_hwc_windows_rendered_window_add(ec->hwc_window);
1504 /////////////////////////////////////////////
1507 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1509 E_Comp_Object *cw = data;
1512 if (cw->render_update_lock.lock)
1514 cw->render_update_lock.pending_move_x = x;
1515 cw->render_update_lock.pending_move_y = y;
1516 cw->render_update_lock.pending_move_set = EINA_TRUE;
1520 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1521 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1522 (cw->external_content))
1524 /* delay to move until the external content is unset */
1525 cw->ec->changes.pos = 1;
1530 if (cw->ec->move_after_resize)
1532 if ((x != cw->ec->x) || (y != cw->ec->y))
1534 if (!cw->ec->is_cursor)
1535 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1536 e_client_pos_set(cw->ec, x, y);
1537 cw->ec->changes.pos = 1;
1543 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1544 (cw->ec->manage_resize.resize_obj))
1546 e_client_pos_set(cw->ec, x, y);
1547 cw->ec->client.x = x + cw->client_inset.l;
1548 cw->ec->client.y = y + cw->client_inset.t;
1549 e_policy_visibility_client_defer_move(cw->ec);
1553 /* if frame_object does not exist, client_inset indicates CSD.
1554 * this means that ec->client matches cw->x/y, the opposite
1557 fx = (!cw->frame_object) * cw->client_inset.l;
1558 fy = (!cw->frame_object) * cw->client_inset.t;
1559 if ((cw->x == x + fx) && (cw->y == y + fy))
1561 if ((cw->ec->x != x) || (cw->ec->y != y))
1563 /* handle case where client tries to move to position and back very quickly */
1564 e_client_pos_set(cw->ec, x, y);
1565 cw->ec->client.x = x + cw->client_inset.l;
1566 cw->ec->client.y = y + cw->client_inset.t;
1570 if (!cw->ec->maximize_override)
1572 /* prevent moving in some directions while directionally maximized */
1573 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1575 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1578 ix = x + cw->client_inset.l;
1579 iy = y + cw->client_inset.t;
1580 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1581 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1582 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1584 /* prevent moving at all if move isn't allowed in current maximize state */
1585 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1586 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1589 zone = e_comp_zone_find_by_ec(cw->ec);
1592 cw->ec->changes.need_unmaximize = 1;
1593 cw->ec->saved.x = ix - zone->x;
1594 cw->ec->saved.y = iy - zone->y;
1595 cw->ec->saved.w = cw->ec->client.w;
1596 cw->ec->saved.h = cw->ec->client.h;
1600 /* only update during resize if triggered by resize */
1601 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1602 /* delay to move while surface waits paired commit serial*/
1603 if (e_client_pending_geometry_has(cw->ec))
1605 /* do nothing while waiting paired commit serial*/
1609 e_client_pos_set(cw->ec, x, y);
1610 if (cw->ec->new_client)
1612 /* don't actually do anything until first client idler loop */
1613 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1614 cw->ec->changes.pos = 1;
1619 /* only update xy position of client to avoid invalid
1620 * first damage region if it is not a new_client. */
1621 cw->ec->client.x = ix;
1622 cw->ec->client.y = iy;
1625 if (!cw->frame_object)
1627 evas_object_move(obj, x, y);
1632 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1634 E_Comp_Object *cw = data;
1635 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1638 if (cw->render_update_lock.lock)
1640 cw->render_update_lock.pending_resize_w = w;
1641 cw->render_update_lock.pending_resize_h = h;
1642 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1646 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1648 e_client_size_set(cw->ec, w, h);
1649 evas_object_resize(obj, w, h);
1653 /* if frame_object does not exist, client_inset indicates CSD.
1654 * this means that ec->client matches cw->w/h, the opposite
1657 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1658 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1659 if ((cw->w == w + fw) && (cw->h == h + fh))
1661 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1662 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1663 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1665 /* handle case where client tries to resize itself and back very quickly */
1666 e_client_size_set(cw->ec, w, h);
1667 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1668 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1669 evas_object_smart_callback_call(obj, "client_resize", NULL);
1673 /* guarantee that fullscreen is fullscreen */
1674 zone = e_comp_zone_find_by_ec(cw->ec);
1676 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1678 if (!e_client_transform_core_enable_get(cw->ec))
1681 /* calculate client size */
1682 iw = w - cw->client_inset.l - cw->client_inset.r;
1683 ih = h - cw->client_inset.t - cw->client_inset.b;
1684 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1686 /* prevent resizing while maximized depending on direction and config */
1687 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1689 Eina_Bool reject = EINA_FALSE;
1690 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1692 if (cw->ec->client.h != ih)
1694 cw->ec->saved.h = ih;
1695 cw->ec->saved.y = cw->ec->client.y - zone->y;
1696 reject = cw->ec->changes.need_unmaximize = 1;
1699 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1701 if (cw->ec->client.w != iw)
1703 cw->ec->saved.w = iw;
1704 cw->ec->saved.x = cw->ec->client.x - zone->x;
1705 reject = cw->ec->changes.need_unmaximize = 1;
1714 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1716 /* do nothing until client idler loops */
1717 if ((cw->ec->w != w) || (cw->ec->h != h))
1719 e_client_size_set(cw->ec, w, h);
1720 cw->ec->changes.size = 1;
1725 if (e_client_pending_geometry_has(cw->ec))
1727 /* do nothing while waiting paired commit serial*/
1731 e_client_size_set(cw->ec, w, h);
1733 cw->ec->client.w = iw;
1734 cw->ec->client.h = ih;
1735 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1737 /* The size of non-compositing window can be changed, so there is a
1738 * need to check that cw is H/W composited if cw is not redirected.
1739 * And of course we have to change size of evas object of H/W composited cw,
1740 * otherwise cw can't receive input events even if it is shown on the screen.
1742 Eina_Bool redirected = cw->redirected;
1744 redirected = e_comp_is_on_overlay(cw->ec);
1746 if ((!cw->ec->input_only) && (redirected) &&
1747 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1748 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1749 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1750 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1753 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1754 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1756 prev_w = cw->w, prev_h = cw->h;
1757 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1758 /* check shading and clamp to pixmap size for regular clients */
1759 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1760 (((w - fw != pw) || (h - fh != ph))))
1762 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1763 evas_object_smart_callback_call(obj, "client_resize", NULL);
1765 if (cw->frame_object || cw->ec->input_only)
1766 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1769 if ((cw->w == w) && (cw->h == h))
1771 /* going to be a noop resize which won't trigger smart resize */
1772 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1773 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1775 evas_object_resize(obj, w, h);
1779 evas_object_smart_callback_call(obj, "client_resize", NULL);
1782 if ((!cw->frame_object) && (!cw->ec->input_only))
1784 /* "just do it" for overrides */
1785 evas_object_resize(obj, w, h);
1787 if (!cw->ec->override)
1789 /* shape probably changed for non-overrides */
1794 /* this fixes positioning jiggles when using a resize mode
1795 * which also changes the client's position
1798 if (cw->frame_object)
1799 x = cw->x, y = cw->y;
1801 x = cw->ec->x, y = cw->ec->y;
1802 switch (cw->ec->resize_mode)
1804 case E_POINTER_RESIZE_BL:
1805 case E_POINTER_RESIZE_L:
1806 evas_object_move(obj, x + prev_w - cw->w, y);
1808 case E_POINTER_RESIZE_TL:
1809 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1811 case E_POINTER_RESIZE_T:
1812 case E_POINTER_RESIZE_TR:
1813 evas_object_move(obj, x, y + prev_h - cw->h);
1822 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1824 #ifdef REFACTOR_DESK_AREA
1825 E_Comp_Object *cw = data;
1826 E_Comp_Object_Data_Set_Layer layer_set_data;
1828 layer_set_data.cw = cw;
1829 layer_set_data.layer = layer;
1831 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1835 e_comp_render_queue();
1836 _e_comp_object_transform_obj_stack_update(obj);
1840 E_Comp_Object *cw = data;
1841 E_Comp_Wl_Client_Data *child_cdata;
1842 unsigned int l = e_comp_canvas_layer_map(layer);
1845 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1847 /* doing a compositor effect, follow directions */
1848 _e_comp_object_layer_set(obj, layer);
1849 if (layer == cw->ec->layer) //trying to put layer back
1853 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1854 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1855 if (cw->layer != l) goto layer_set;
1859 e_comp_render_queue();
1861 ec = e_client_above_get(cw->ec);
1862 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1863 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1864 ec = e_client_above_get(ec);
1865 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1867 ec = e_client_below_get(cw->ec);
1868 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1869 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1870 ec = e_client_below_get(ec);
1871 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1873 evas_object_stack_above(obj, ec->frame);
1878 if (ec && (cw->ec->parent == ec))
1880 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1881 evas_object_stack_above(obj, ec->frame);
1883 evas_object_stack_below(obj, ec->frame);
1886 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1892 if (cw->layer == l) return;
1893 if (e_comp_canvas_client_layer_map(layer) == 9999)
1894 return; //invalid layer for clients not doing comp effects
1895 if (cw->ec->fullscreen)
1897 cw->ec->saved.layer = layer;
1900 oldraise = e_config->transient.raise;
1902 /* clamp to valid client layer */
1903 layer = e_comp_canvas_client_layer_map_nearest(layer);
1904 cw->ec->layer = layer;
1905 if (e_config->transient.layer)
1908 Eina_List *list = eina_list_clone(cw->ec->transients);
1910 /* We need to set raise to one, else the child wont
1911 * follow to the new layer. It should be like this,
1912 * even if the user usually doesn't want to raise
1915 e_config->transient.raise = 1;
1916 EINA_LIST_FREE(list, child)
1918 child_cdata = e_client_cdata_get(child);
1919 if (child_cdata && !child_cdata->mapped)
1921 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1924 e_client_layer_set(child, layer);
1928 e_config->transient.raise = oldraise;
1930 _e_comp_object_layers_remove(cw);
1931 cw->layer = e_comp_canvas_layer_map(layer);
1932 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1933 //if (cw->ec->new_client)
1934 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1935 _e_comp_object_layer_set(obj, layer);
1936 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1937 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1938 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1940 /* can't stack a client above its own layer marker */
1941 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1943 if (!cw->visible) return;
1944 e_comp_render_queue();
1945 _e_comp_object_transform_obj_stack_update(obj);
1949 #ifdef REFACTOR_DESK_AREA
1951 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1954 #ifdef REFACTOR_DESK_AREA
1956 _e_comp_object_raise(Evas_Object *obj)
1959 _e_comp_object_raise(Evas_Object *obj)
1962 evas_object_raise(obj);
1964 if (evas_object_smart_smart_get(obj))
1966 E_Client *ec = e_comp_object_client_get(obj);
1968 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1972 #ifdef REFACTOR_DESK_AREA
1974 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1977 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1980 evas_object_lower(obj);
1982 if (evas_object_smart_smart_get(obj))
1984 E_Client *ec = e_comp_object_client_get(obj);
1987 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1988 #ifdef REFACTOR_DESK_AREA
1989 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1991 wl_signal_emit_mutable(&cw->events.lower, NULL);
1997 #ifdef REFACTOR_DESK_AREA
1999 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2002 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2005 evas_object_stack_above(obj, target);
2007 if (evas_object_smart_smart_get(obj))
2009 E_Client *ec = e_comp_object_client_get(obj);
2011 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2015 #ifdef REFACTOR_DESK_AREA
2017 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2020 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2023 evas_object_stack_below(obj, target);
2025 if (evas_object_smart_smart_get(obj))
2027 E_Client *ec = e_comp_object_client_get(obj);
2029 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2033 #ifdef REFACTOR_DESK_AREA
2035 e_comp_object_layer_set(Evas_Object *obj, short layer)
2038 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2041 evas_object_layer_set(obj, layer);
2043 if (evas_object_smart_smart_get(obj))
2045 E_Client *ec = e_comp_object_client_get(obj);
2047 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2051 #ifdef REFACTOR_DESK_AREA
2054 _e_comp_object_is_pending(E_Client *ec)
2058 if (!ec) return EINA_FALSE;
2060 topmost = e_comp_wl_topmost_parent_get(ec);
2062 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2066 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2068 E_Comp_Object *cw2 = NULL;
2071 Evas_Object *o = stack;
2072 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2074 /* We should consider topmost's layer_pending for subsurface */
2075 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2077 if (_e_comp_object_is_pending(cw->ec))
2078 e_comp_object_layer_update(cw->smart_obj,
2079 raising? stack : NULL,
2080 raising? NULL : stack);
2082 /* obey compositor effects! */
2083 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2084 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2085 stack_cb(cw->smart_obj, stack);
2086 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2087 evas_object_data_del(cw->smart_obj, "client_restack");
2091 cw2 = evas_object_data_get(o, "comp_obj");
2093 /* assume someone knew what they were doing during client init */
2094 if (cw->ec->new_client)
2095 layer = cw->ec->layer;
2096 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2097 layer = cw2->ec->layer;
2099 layer = evas_object_layer_get(stack);
2100 ecstack = e_client_below_get(cw->ec);
2101 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2103 evas_object_layer_set(cw->smart_obj, layer);
2104 /* we got our layer wrangled, return now! */
2105 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2108 /* check if we're stacking below another client */
2111 /* check for non-client layer object */
2112 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2114 /* find an existing client to use for layering
2115 * by walking up the object stack
2117 * this is guaranteed to be pretty quick since we'll either:
2118 * - run out of client layers
2119 * - find a stacking client
2121 o = evas_object_above_get(o);
2122 if ((!o) || (o == cw->smart_obj)) break;
2123 if (evas_object_layer_get(o) != layer)
2125 /* reached the top client layer somehow
2126 * use top client object
2128 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2131 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2132 * return here since the top client layer window
2137 ec = e_client_top_get();
2142 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2145 if (cw2 && cw->layer != cw2->layer)
2148 /* remove existing layers */
2149 _e_comp_object_layers_remove(cw);
2152 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2153 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2154 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2155 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2156 else //if no stacking objects found, either raise or lower
2157 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2160 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2162 /* find new object for stacking if cw2 is on state of layer_pending */
2163 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2165 E_Client *new_stack = NULL, *current_ec = NULL;
2166 current_ec = cw2->ec;
2169 while ((new_stack = e_client_below_get(current_ec)))
2171 current_ec = new_stack;
2172 if (new_stack == cw->ec) continue;
2173 if (new_stack->layer != cw2->ec->layer) break;
2174 if (!_e_comp_object_is_pending(new_stack)) break;
2176 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2177 stack = new_stack->frame;
2180 /* stack it above layer object */
2182 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2183 stack = e_comp->layers[below_layer].obj;
2188 while ((new_stack = e_client_above_get(current_ec)))
2190 current_ec = new_stack;
2191 if (new_stack == cw->ec) continue;
2192 if (new_stack->layer != cw2->ec->layer) break;
2193 if (!_e_comp_object_is_pending(new_stack)) break;
2195 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2196 stack = new_stack->frame;
2198 stack = e_comp->layers[cw2->layer].obj;
2202 /* set restack if stacking has changed */
2203 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2204 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2205 stack_cb(cw->smart_obj, stack);
2206 if (e_comp->layers[cw->layer].obj)
2207 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2209 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2211 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2212 evas_object_data_del(cw->smart_obj, "client_restack");
2213 if (!cw->visible) return;
2214 e_comp_render_queue();
2219 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2221 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2223 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2225 #ifdef REFACTOR_DESK_AREA
2226 E_Comp_Object *cw = data;
2227 E_Comp_Object_Data_Stack_Above stack_above_data;
2229 stack_above_data.cw = cw;
2230 stack_above_data.above_obj = above;
2232 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2234 if (evas_object_below_get(obj) == above)
2236 e_comp_object_layer_update(obj, above, NULL);
2240 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2242 _e_comp_object_transform_obj_stack_update(obj);
2243 _e_comp_object_transform_obj_stack_update(above);
2250 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2252 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2254 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2256 #ifdef REFACTOR_DESK_AREA
2257 E_Comp_Object *cw = data;
2258 E_Comp_Object_Data_Stack_Below stack_below_data;
2260 stack_below_data.cw = cw;
2261 stack_below_data.below_obj = below;
2263 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2266 e_comp_render_queue();
2268 if (evas_object_above_get(obj) == below)
2270 e_comp_object_layer_update(obj, NULL, below);
2274 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2276 if (evas_object_smart_smart_get(obj))
2277 _e_comp_object_transform_obj_stack_update(obj);
2278 if (evas_object_smart_smart_get(below))
2279 _e_comp_object_transform_obj_stack_update(below);
2286 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2288 E_Comp_Object *cw = data;
2290 #ifdef REFACTOR_DESK_AREA
2295 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2297 #ifdef REFACTOR_DESK_AREA
2298 wl_signal_emit_mutable(&cw->events.lower, cw);
2300 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2302 if (cw->ec->layer_pending)
2303 e_comp_object_layer_update(obj, NULL, obj);
2305 _e_comp_object_lower(cw, obj);
2308 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2309 o = evas_object_below_get(obj);
2310 _e_comp_object_layers_remove(cw);
2311 /* prepend to client list since this client should be the first item now */
2312 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2313 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2314 evas_object_data_set(obj, "client_restack", (void*)1);
2315 _e_comp_object_lower(cw, obj);
2316 evas_object_data_del(obj, "client_restack");
2317 if (!cw->visible) goto end;
2318 e_comp_render_queue();
2319 _e_comp_object_transform_obj_stack_update(obj);
2327 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2329 E_Comp_Object *cw = data;
2330 #ifdef REFACTOR_DESK_AREA
2336 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2338 #ifdef REFACTOR_DESK_AREA
2339 wl_signal_emit_mutable(&cw->events.raise, cw);
2341 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2343 if (cw->ec->layer_pending)
2345 int obj_layer = evas_object_layer_get(obj);
2346 if (cw->ec->layer != obj_layer)
2347 e_comp_object_layer_update(obj, NULL, NULL);
2350 _e_comp_object_raise(obj);
2353 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2354 o = evas_object_above_get(obj);
2355 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2357 /* still stack below override below the layer marker */
2358 for (op = o = e_comp->layers[cw->layer].obj;
2359 o && o != e_comp->layers[cw->layer - 1].obj;
2360 op = o, o = evas_object_below_get(o))
2362 if (evas_object_smart_smart_get(o))
2366 ec = e_comp_object_client_get(o);
2367 if (ec && (!ec->override)) break;
2370 _e_comp_object_stack_below(obj, op);
2371 e_client_focus_defer_set(cw->ec);
2373 if (!cw->visible) goto end;
2374 e_comp_render_queue();
2375 _e_comp_object_transform_obj_stack_update(obj);
2383 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2385 E_Comp_Object *cw = data;
2387 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2388 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2390 ELOGF("COMP", "Hide. intercepted", cw->ec);
2395 if (cw->ec->launching == EINA_TRUE)
2397 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2398 cw->ec->launching = EINA_FALSE;
2403 /* hidden flag = just do it */
2404 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2405 evas_object_hide(obj);
2407 wl_signal_emit_mutable(&cw->events.hide, NULL);
2412 if (cw->ec->input_only)
2414 /* input_only = who cares */
2415 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2416 evas_object_hide(obj);
2418 wl_signal_emit_mutable(&cw->events.hide, NULL);
2422 /* already hidden or currently animating */
2423 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2425 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2429 /* don't try hiding during shutdown */
2430 cw->defer_hide |= stopping;
2431 if (!cw->defer_hide)
2433 if ((!cw->ec->iconic) && (!cw->ec->override))
2434 /* unset delete requested so the client doesn't break */
2435 cw->ec->delete_requested = 0;
2436 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2438 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2439 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2442 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2445 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2447 _e_comp_object_animating_begin(cw);
2448 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2450 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2451 cw->defer_hide = !!cw->animating;
2453 e_comp_object_effect_set(obj, NULL);
2456 if (cw->animating) return;
2457 /* if we have no animations running, go ahead and hide */
2459 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2460 evas_object_hide(obj);
2462 wl_signal_emit_mutable(&cw->events.hide, NULL);
2466 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2468 E_Client *ec = cw->ec;
2471 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2473 if (ec->show_pending.count > 0)
2475 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2476 ec->show_pending.running = EINA_TRUE;
2480 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2481 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2483 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2488 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,
2489 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2490 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2493 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2496 if (ec->iconic && cw->animating)
2498 /* triggered during iconify animation */
2499 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2502 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2505 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2506 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2508 evas_object_move(cw->smart_obj, ec->x, ec->y);
2509 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2510 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2512 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2513 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2516 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2517 evas_object_show(cw->smart_obj);
2520 e_client_focus_defer_set(ec);
2524 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2528 pw = ec->client.w, ph = ec->client.h;
2530 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2532 ec->changes.visible = !ec->hidden;
2535 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2539 cw->updates = eina_tiler_new(pw, ph);
2542 ec->changes.visible = !ec->hidden;
2545 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2550 eina_tiler_tile_size_set(cw->updates, 1, 1);
2553 /* ignore until client idler first run */
2554 ec->changes.visible = !ec->hidden;
2557 ELOGF("COMP", "show_helper. return. new_client", ec);
2564 evas_object_move(cw->smart_obj, ec->x, ec->y);
2565 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2566 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2567 evas_object_show(cw->smart_obj);
2570 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2572 /* start_drag not received */
2573 ec->changes.visible = 1;
2576 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2579 /* re-set geometry */
2580 evas_object_move(cw->smart_obj, ec->x, ec->y);
2581 /* force resize in case it hasn't happened yet, or just to update size */
2582 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2583 if ((cw->w < 1) || (cw->h < 1))
2585 /* if resize didn't go through, try again */
2586 ec->visible = ec->changes.visible = 1;
2588 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2591 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2592 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2593 e_pixmap_clear(ec->pixmap);
2595 if (cw->real_hid && w && h)
2598 /* force comp theming in case it didn't happen already */
2599 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2600 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2601 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2604 /* only do the show if show is allowed */
2607 if (ec->internal) //internal clients render when they feel like it
2608 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2610 if (!e_client_is_iconified_by_client(ec)||
2611 e_policy_visibility_client_is_uniconic(ec))
2613 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2614 evas_object_show(cw->smart_obj);
2616 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2617 it is rendered in idle callback without native surface and
2618 compositor shows an empty frame if other objects aren't shown
2619 because job callback of e_comp called at the next loop.
2620 it causes a visual defect when windows are switched.
2624 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2625 e_comp_object_dirty(cw->smart_obj);
2626 e_comp_object_render(cw->smart_obj);
2631 wl_signal_emit_mutable(&cw->events.show, NULL);
2635 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2637 E_Comp_Object *cw = data;
2638 E_Client *ec = cw->ec;
2640 E_Input_Rect_Data *input_rect_data;
2641 E_Input_Rect_Smart_Data *input_rect_sd;
2644 if (ec->ignored) return;
2648 //INF("SHOW2 %p", ec);
2649 _e_comp_intercept_show_helper(cw);
2652 //INF("SHOW %p", ec);
2655 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2656 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2657 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2658 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2662 if ((!cw->obj) && (cw->external_content))
2664 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2668 _e_comp_object_setup(cw);
2671 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2672 cw->obj = evas_object_image_filled_add(e_comp->evas);
2673 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2674 e_util_size_debug_set(cw->obj, 1);
2675 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2676 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2677 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2678 evas_object_name_set(cw->obj, "cw->obj");
2679 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2681 _e_comp_object_alpha_set(cw);
2684 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2687 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2688 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2691 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2694 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2696 if (input_rect_data->obj)
2698 evas_object_geometry_set(input_rect_data->obj,
2699 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2700 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2701 input_rect_data->rect.w, input_rect_data->rect.h);
2708 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2710 _e_comp_intercept_show_helper(cw);
2714 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2716 E_Comp_Object *cw = data;
2720 /* note: this is here as it seems there are enough apps that do not even
2721 * expect us to emulate a look of focus but not actually set x input
2722 * focus as we do - so simply abort any focus set on such windows */
2723 /* be strict about accepting focus hint */
2724 /* be strict about accepting focus hint */
2725 if ((!ec->icccm.accepts_focus) &&
2726 (!ec->icccm.take_focus))
2730 if (e_client_focused_get() == ec)
2731 e_client_focused_set(NULL);
2733 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2734 evas_object_focus_set(obj, focus);
2738 if (focus && ec->lock_focus_out) return;
2739 if (e_object_is_del(E_OBJECT(ec)) && focus)
2740 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2742 /* filter focus setting based on current state */
2747 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2748 evas_object_focus_set(obj, focus);
2751 if ((ec->iconic) && (!ec->deskshow))
2753 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2755 /* don't focus an iconified window. that's silly! */
2756 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2757 e_client_uniconify(ec);
2758 e_client_focus_latest_set(ec);
2772 /* not yet visible, wait till the next time... */
2773 ec->want_focus = !ec->hidden;
2778 e_client_focused_set(ec);
2782 if (e_client_focused_get() == ec)
2783 e_client_focused_set(NULL);
2787 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2789 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2791 evas_object_focus_set(obj, focus);
2795 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2797 E_Comp_Object *cw = data;
2799 if (cw->transparent.set)
2801 cw->transparent.user_r = r;
2802 cw->transparent.user_g = g;
2803 cw->transparent.user_b = b;
2804 cw->transparent.user_a = a;
2806 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2808 cw->transparent.user_r,
2809 cw->transparent.user_g,
2810 cw->transparent.user_b,
2811 cw->transparent.user_a);
2815 evas_object_color_set(obj, r, g, b, a);
2818 ////////////////////////////////////////////////////
2821 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2823 int w, h, ox, oy, ow, oh;
2825 Eina_Bool pass_event_flag = EINA_FALSE;
2826 E_Input_Rect_Data *input_rect_data;
2827 E_Input_Rect_Smart_Data *input_rect_sd;
2829 if (cw->frame_object)
2831 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2832 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2833 /* set a fixed size, force edje calc, check size difference */
2834 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2835 edje_object_message_signal_process(cw->frame_object);
2836 edje_object_calc_force(cw->frame_object);
2837 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2838 cw->client_inset.l = ox;
2839 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2840 cw->client_inset.t = oy;
2841 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2842 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2843 evas_object_resize(cw->frame_object, w, h);
2847 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2850 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2852 if (input_rect_data->obj)
2854 pass_event_flag = EINA_TRUE;
2860 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2861 evas_object_pass_events_set(cw->obj, pass_event_flag);
2865 cw->client_inset.l = 0;
2866 cw->client_inset.r = 0;
2867 cw->client_inset.t = 0;
2868 cw->client_inset.b = 0;
2870 cw->client_inset.calc = !!cw->frame_object;
2874 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2876 E_Comp_Object *cw = data;
2880 /* - get current size
2882 * - readjust for new frame size
2885 w = cw->ec->w, h = cw->ec->h;
2886 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2888 _e_comp_object_frame_recalc(cw);
2890 if (!cw->ec->fullscreen)
2891 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2893 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2894 if (cw->ec->fullscreen)
2896 zone = e_comp_zone_find_by_ec(cw->ec);
2898 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2900 else if (cw->ec->new_client)
2902 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2903 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2904 evas_object_resize(cw->ec->frame, w, h);
2906 else if ((w != cw->ec->w) || (h != cw->ec->h))
2907 evas_object_resize(cw->ec->frame, w, h);
2911 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2913 E_Comp_Object *cw = data;
2915 _e_comp_object_shadow_setup(cw);
2916 if (cw->frame_object)
2918 _e_comp_object_shadow(cw);
2919 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2920 _e_comp_object_frame_recalc(cw);
2921 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2926 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2928 E_Comp_Object *cw = data;
2930 if (_e_comp_object_shadow_setup(cw))
2931 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2932 if (cw->frame_object)
2934 _e_comp_object_shadow(cw);
2935 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2936 _e_comp_object_frame_recalc(cw);
2937 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2942 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2944 E_Comp_Object *cw = data;
2946 if (cw->frame_object)
2948 _e_comp_object_shadow(cw);
2949 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2950 _e_comp_object_frame_recalc(cw);
2951 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2956 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2958 E_Comp_Object *cw = data;
2960 if (_e_comp_object_shadow_setup(cw))
2963 cw->ec->changes.size = 1;
2965 if (cw->frame_object)
2967 _e_comp_object_shadow(cw);
2968 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2969 _e_comp_object_frame_recalc(cw);
2970 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2975 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2977 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2981 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2983 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2987 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2989 E_Comp_Object *cw = data;
2991 if (!cw->ec) return; //NYI
2992 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2996 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2998 E_Comp_Object *cw = data;
3000 if (!cw->ec) return; //NYI
3001 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3005 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3007 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3011 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3013 E_Comp_Object *cw = data;
3015 if (!e_object_is_del(E_OBJECT(cw->ec)))
3016 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3020 _e_comp_input_obj_smart_add(Evas_Object *obj)
3022 E_Input_Rect_Smart_Data *input_rect_sd;
3023 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3025 if (!input_rect_sd) return;
3026 evas_object_smart_data_set(obj, input_rect_sd);
3030 _e_comp_input_obj_smart_del(Evas_Object *obj)
3032 E_Input_Rect_Smart_Data *input_rect_sd;
3033 E_Input_Rect_Data *input_rect_data;
3035 input_rect_sd = evas_object_smart_data_get(obj);
3036 if (!input_rect_sd) return;
3038 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3040 if (input_rect_data->obj)
3042 evas_object_smart_member_del(input_rect_data->obj);
3043 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3045 E_FREE(input_rect_data);
3047 E_FREE(input_rect_sd);
3051 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3053 E_Input_Rect_Smart_Data *input_rect_sd;
3054 E_Input_Rect_Data *input_rect_data;
3058 input_rect_sd = evas_object_smart_data_get(obj);
3059 if (!input_rect_sd) return;
3061 cw = input_rect_sd->cw;
3062 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3064 if (input_rect_data->obj)
3066 evas_object_geometry_set(input_rect_data->obj,
3067 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3068 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3069 input_rect_data->rect.w, input_rect_data->rect.h);
3075 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3077 E_Input_Rect_Smart_Data *input_rect_sd;
3078 E_Input_Rect_Data *input_rect_data;
3082 input_rect_sd = evas_object_smart_data_get(obj);
3083 if (!input_rect_sd) return;
3085 cw = input_rect_sd->cw;
3086 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3088 if (input_rect_data->obj)
3090 evas_object_geometry_set(input_rect_data->obj,
3091 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3092 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3093 input_rect_data->rect.w, input_rect_data->rect.h);
3099 _e_comp_input_obj_smart_show(Evas_Object *obj)
3101 E_Input_Rect_Smart_Data *input_rect_sd;
3102 E_Input_Rect_Data *input_rect_data;
3105 input_rect_sd = evas_object_smart_data_get(obj);
3106 if (!input_rect_sd) return;
3108 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3110 if (input_rect_data->obj)
3112 evas_object_show(input_rect_data->obj);
3118 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3120 E_Input_Rect_Smart_Data *input_rect_sd;
3121 E_Input_Rect_Data *input_rect_data;
3124 input_rect_sd = evas_object_smart_data_get(obj);
3125 if (!input_rect_sd) return;
3127 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3129 if (input_rect_data->obj)
3131 evas_object_hide(input_rect_data->obj);
3137 _e_comp_input_obj_smart_init(void)
3139 if (_e_comp_input_obj_smart) return;
3141 static const Evas_Smart_Class sc =
3143 INPUT_OBJ_SMART_NAME,
3144 EVAS_SMART_CLASS_VERSION,
3145 _e_comp_input_obj_smart_add,
3146 _e_comp_input_obj_smart_del,
3147 _e_comp_input_obj_smart_move,
3148 _e_comp_input_obj_smart_resize,
3149 _e_comp_input_obj_smart_show,
3150 _e_comp_input_obj_smart_hide,
3163 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3169 _e_comp_smart_add(Evas_Object *obj)
3173 cw = E_NEW(E_Comp_Object, 1);
3174 EINA_SAFETY_ON_NULL_RETURN(cw);
3176 wl_signal_init(&cw->events.lower);
3177 #ifdef REFACTOR_DESK_AREA
3178 wl_signal_init(&cw->events.lower_done);
3179 wl_signal_init(&cw->events.raise);
3181 wl_signal_init(&cw->events.show);
3182 wl_signal_init(&cw->events.hide);
3183 #ifdef REFACTOR_DESK_AREA
3184 wl_signal_init(&cw->events.set_layer);
3185 wl_signal_init(&cw->events.stack_above);
3186 wl_signal_init(&cw->events.stack_below);
3189 cw->smart_obj = obj;
3190 cw->x = cw->y = cw->w = cw->h = -1;
3191 evas_object_smart_data_set(obj, cw);
3192 cw->opacity = 255.0;
3193 cw->external_content = 0;
3194 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3195 cw->transform_bg_color.r = 0;
3196 cw->transform_bg_color.g = 0;
3197 cw->transform_bg_color.b = 0;
3198 cw->transform_bg_color.a = 255;
3199 evas_object_data_set(obj, "comp_obj", cw);
3200 evas_object_move(obj, -1, -1);
3201 /* intercept ALL the callbacks! */
3202 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3203 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3204 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3205 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3206 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3207 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3208 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3209 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3210 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3211 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3212 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3214 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3215 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3216 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3217 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3219 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3220 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3222 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3223 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3225 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3227 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3228 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3232 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3235 evas_object_color_set(cw->clip, r, g, b, a);
3236 evas_object_smart_callback_call(obj, "color_set", NULL);
3241 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3244 evas_object_clip_set(cw->clip, clip);
3248 _e_comp_smart_clip_unset(Evas_Object *obj)
3251 evas_object_clip_unset(cw->clip);
3255 _e_comp_smart_hide(Evas_Object *obj)
3257 TRACE_DS_BEGIN(COMP:SMART HIDE);
3262 evas_object_hide(cw->clip);
3263 if (cw->input_obj) evas_object_hide(cw->input_obj);
3264 evas_object_hide(cw->effect_obj);
3265 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3266 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3267 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3274 /* unset native surface if current displaying buffer was destroied */
3275 if (!cw->buffer_destroy_listener.notify)
3277 Evas_Native_Surface *ns;
3278 ns = evas_object_image_native_surface_get(cw->obj);
3279 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3280 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3283 if (!cw->ec->input_only)
3285 edje_object_freeze(cw->effect_obj);
3286 edje_object_freeze(cw->shobj);
3287 edje_object_play_set(cw->shobj, 0);
3288 if (cw->frame_object)
3289 edje_object_play_set(cw->frame_object, 0);
3292 e_comp_render_queue(); //force nocomp recheck
3298 _e_comp_smart_show(Evas_Object *obj)
3306 if ((cw->w < 0) || (cw->h < 0))
3307 CRI("ACK! ec:%p", cw->ec);
3309 TRACE_DS_BEGIN(COMP:SMART SHOW);
3311 e_comp_object_map_update(obj);
3313 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3314 evas_object_show(tmp->frame);
3316 evas_object_show(cw->clip);
3317 if (cw->input_obj) evas_object_show(cw->input_obj);
3318 if (!cw->ec->input_only)
3320 edje_object_thaw(cw->effect_obj);
3321 edje_object_thaw(cw->shobj);
3322 edje_object_play_set(cw->shobj, 1);
3323 if (cw->frame_object)
3324 edje_object_play_set(cw->frame_object, 1);
3326 evas_object_show(cw->effect_obj);
3327 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3328 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3329 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3330 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3331 e_comp_render_queue();
3332 if (cw->ec->input_only)
3337 if (cw->ec->iconic && (!cw->ec->new_client))
3339 if (e_client_is_iconified_by_client(cw->ec))
3341 ELOGF("COMP", "Set launching flag..", cw->ec);
3342 cw->ec->launching = EINA_TRUE;
3345 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3347 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3350 ELOGF("COMP", "Set launching flag..", cw->ec);
3351 cw->ec->launching = EINA_TRUE;
3353 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3354 _e_comp_object_animating_begin(cw);
3355 if (!_e_comp_object_effect_visibility_start(cw, 1))
3361 /* ensure some random effect doesn't lock the client offscreen */
3365 e_comp_object_effect_set(obj, NULL);
3368 _e_comp_object_dim_update(cw);
3374 _e_comp_smart_del(Evas_Object *obj)
3380 if (cw->buffer_destroy_listener.notify)
3382 wl_list_remove(&cw->buffer_destroy_listener.link);
3383 cw->buffer_destroy_listener.notify = NULL;
3386 if (cw->tbm_surface)
3388 tbm_surface_internal_unref(cw->tbm_surface);
3389 cw->tbm_surface = NULL;
3392 if (cw->render_update_lock.buffer_ref.buffer)
3394 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3395 cw->ec, cw->render_update_lock.lock);
3396 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3399 e_comp_object_render_update_del(cw->smart_obj);
3400 E_FREE_FUNC(cw->updates, eina_tiler_free);
3401 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3408 EINA_LIST_FREE(cw->obj_mirror, o)
3410 evas_object_image_data_set(o, NULL);
3411 evas_object_freeze_events_set(o, 1);
3412 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3416 #ifdef REFACTOR_DESK_AREA
3418 _e_comp_object_layers_remove(cw);
3420 l = evas_object_data_get(obj, "comp_object-to_del");
3421 E_FREE_LIST(l, evas_object_del);
3422 _e_comp_object_mouse_event_callback_unset(cw);
3423 evas_object_del(cw->clip);
3424 evas_object_del(cw->obj);
3425 evas_object_del(cw->shobj);
3426 evas_object_del(cw->effect_obj);
3427 evas_object_del(cw->frame_object);
3428 evas_object_del(cw->input_obj);
3429 evas_object_del(cw->mask.obj);
3430 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3431 evas_object_del(cw->transform_bg_obj);
3432 evas_object_del(cw->transform_tranp_obj);
3433 evas_object_del(cw->default_input_obj);
3434 eina_stringshare_del(cw->frame_theme);
3435 eina_stringshare_del(cw->frame_name);
3439 e_comp->animating--;
3441 e_object_unref(E_OBJECT(cw->ec));
3443 cw->ec->frame = NULL;
3448 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3452 cw->x = x, cw->y = y;
3453 evas_object_move(cw->effect_obj, x, y);
3454 evas_object_move(cw->default_input_obj, x, y);
3455 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3457 e_comp_object_map_update(obj);
3461 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3463 Eina_Bool first = EINA_FALSE;
3468 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3470 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3472 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3474 if (cw->w != w || cw->h != h)
3475 e_comp_object_map_update(obj);
3477 first = ((cw->w < 1) || (cw->h < 1));
3478 cw->w = w, cw->h = h;
3482 if (cw->frame_object)
3483 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3486 /* verify pixmap:object size */
3487 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3489 if ((ww != pw) || (hh != ph))
3490 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3492 evas_object_resize(cw->effect_obj, tw, th);
3493 evas_object_resize(cw->default_input_obj, w, h);
3495 evas_object_resize(cw->input_obj, w, h);
3497 evas_object_resize(cw->mask.obj, w, h);
3498 /* resize render update tiler */
3501 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3502 cw->updates_full = 0;
3503 if (cw->updates) eina_tiler_clear(cw->updates);
3507 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3508 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3516 e_comp_render_queue();
3522 _e_comp_smart_init(void)
3524 if (_e_comp_smart) return;
3526 static const Evas_Smart_Class sc =
3529 EVAS_SMART_CLASS_VERSION,
3533 _e_comp_smart_resize,
3536 _e_comp_smart_color_set,
3537 _e_comp_smart_clip_set,
3538 _e_comp_smart_clip_unset,
3548 _e_comp_smart = evas_smart_class_new(&sc);
3553 e_comp_object_init(void)
3555 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3556 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3557 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3558 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3562 e_comp_object_shutdown(void)
3568 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3570 API_ENTRY EINA_FALSE;
3571 return !!cw->force_visible;
3573 /////////////////////////////////////////////////////////
3576 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3579 Eina_Bool comp_object;
3581 comp_object = !!evas_object_data_get(obj, "comp_object");
3586 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3588 e_comp_render_queue();
3590 l = evas_object_data_get(obj, "comp_object-to_del");
3591 E_FREE_LIST(l, evas_object_del);
3595 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3597 if (e_comp_util_object_is_above_nocomp(obj) &&
3598 (!evas_object_data_get(obj, "comp_override")))
3600 evas_object_data_set(obj, "comp_override", (void*)1);
3601 e_comp_override_add();
3606 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3608 Eina_Bool ref = EINA_TRUE;
3609 if (evas_object_visible_get(obj))
3613 d = evas_object_data_del(obj, "comp_hiding");
3615 /* currently trying to hide */
3618 /* already visible */
3622 evas_object_show(obj);
3625 evas_object_ref(obj);
3626 evas_object_data_set(obj, "comp_ref", (void*)1);
3628 edje_object_signal_emit(obj, "e,state,visible", "e");
3629 evas_object_data_set(obj, "comp_showing", (void*)1);
3630 if (e_comp_util_object_is_above_nocomp(obj))
3632 evas_object_data_set(obj, "comp_override", (void*)1);
3633 e_comp_override_add();
3638 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3640 if (!evas_object_visible_get(obj)) return;
3641 /* already hiding */
3642 if (evas_object_data_get(obj, "comp_hiding")) return;
3643 if (!evas_object_data_del(obj, "comp_showing"))
3645 evas_object_ref(obj);
3646 evas_object_data_set(obj, "comp_ref", (void*)1);
3648 edje_object_signal_emit(obj, "e,state,hidden", "e");
3649 evas_object_data_set(obj, "comp_hiding", (void*)1);
3651 if (evas_object_data_del(obj, "comp_override"))
3652 e_comp_override_timed_pop();
3656 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3658 if (!e_util_strcmp(emission, "e,action,hide,done"))
3660 if (!evas_object_data_del(obj, "comp_hiding")) return;
3661 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3662 evas_object_hide(obj);
3663 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3666 evas_object_data_del(obj, "comp_showing");
3667 if (evas_object_data_del(obj, "comp_ref"))
3668 evas_object_unref(obj);
3672 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3678 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3682 E_API E_Comp_Object_Hook *
3683 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3685 E_Comp_Object_Hook *ch;
3687 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3688 ch = E_NEW(E_Comp_Object_Hook, 1);
3689 if (!ch) return NULL;
3690 ch->hookpoint = hookpoint;
3692 ch->data = (void*)data;
3693 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3698 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3701 if (_e_comp_object_hooks_walking == 0)
3703 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3707 _e_comp_object_hooks_delete++;
3710 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3711 E_API E_Comp_Object_Intercept_Hook *
3712 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3714 E_Comp_Object_Intercept_Hook *ch;
3716 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3717 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3718 if (!ch) return NULL;
3719 ch->hookpoint = hookpoint;
3721 ch->data = (void*)data;
3722 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3727 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3730 if (_e_comp_object_intercept_hooks_walking == 0)
3732 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3736 _e_comp_object_intercept_hooks_delete++;
3741 e_comp_object_util_add(Evas_Object *obj)
3745 E_Comp_Config *conf = e_comp_config_get();
3746 Eina_Bool skip = EINA_FALSE;
3752 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3754 name = evas_object_name_get(obj);
3755 vis = evas_object_visible_get(obj);
3756 o = edje_object_add(e_comp->evas);
3757 evas_object_data_set(o, "comp_object", (void*)1);
3759 skip = (!strncmp(name, "noshadow", 8));
3761 evas_object_data_set(o, "comp_object_skip", (void*)1);
3763 if (conf->shadow_style)
3765 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3766 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3769 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3770 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3771 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3773 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3775 evas_object_geometry_get(obj, &x, &y, &w, &h);
3776 evas_object_geometry_set(o, x, y, w, h);
3777 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3779 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3781 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3782 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3783 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3784 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3788 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3790 edje_object_part_swallow(o, "e.swallow.content", obj);
3792 _e_comp_object_event_add(o);
3795 evas_object_show(o);
3800 /* utility functions for deleting objects when their "owner" is deleted */
3802 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3807 EINA_SAFETY_ON_NULL_RETURN(to_del);
3808 l = evas_object_data_get(obj, "comp_object-to_del");
3809 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3810 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3811 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3815 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3820 EINA_SAFETY_ON_NULL_RETURN(to_del);
3821 l = evas_object_data_get(obj, "comp_object-to_del");
3823 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3826 /////////////////////////////////////////////////////////
3828 EINTERN Evas_Object *
3829 e_comp_object_client_add(E_Client *ec)
3834 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3835 if (ec->frame) return NULL;
3836 _e_comp_smart_init();
3837 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3838 cw = evas_object_smart_data_get(o);
3839 if (!cw) return NULL;
3840 evas_object_data_set(o, "E_Client", ec);
3843 evas_object_data_set(o, "comp_object", (void*)1);
3845 _e_comp_object_event_add(o);
3850 /* utility functions for getting client inset */
3852 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3855 if (!cw->client_inset.calc)
3861 if (ax) *ax = x - cw->client_inset.l;
3862 if (ay) *ay = y - cw->client_inset.t;
3866 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3869 if (!cw->client_inset.calc)
3875 if (ax) *ax = x + cw->client_inset.l;
3876 if (ay) *ay = y + cw->client_inset.t;
3880 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3883 if (!cw->client_inset.calc)
3889 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3890 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3894 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3897 if (!cw->client_inset.calc)
3903 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3904 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3908 e_comp_object_client_get(Evas_Object *obj)
3913 /* FIXME: remove this when eo is used */
3914 o = evas_object_data_get(obj, "comp_smart_obj");
3916 return e_comp_object_client_get(o);
3917 return cw ? cw->ec : NULL;
3921 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3924 if (cw->frame_extends)
3925 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3930 if (w) *w = cw->ec->w;
3931 if (h) *h = cw->ec->h;
3936 e_comp_object_util_zone_get(Evas_Object *obj)
3938 E_Zone *zone = NULL;
3942 zone = e_comp_zone_find_by_ec(cw->ec);
3947 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3948 zone = e_comp_zone_xy_get(x, y);
3954 e_comp_object_util_center(Evas_Object *obj)
3956 int x, y, w, h, ow, oh;
3961 zone = e_comp_object_util_zone_get(obj);
3962 EINA_SAFETY_ON_NULL_RETURN(zone);
3963 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3964 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3965 ow = cw->ec->w, oh = cw->ec->h;
3967 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3968 x = x + (w - ow) / 2;
3969 y = y + (h - oh) / 2;
3970 evas_object_move(obj, x, y);
3974 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3976 int x, y, w, h, ow, oh;
3979 EINA_SAFETY_ON_NULL_RETURN(on);
3980 evas_object_geometry_get(on, &x, &y, &w, &h);
3981 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3982 ow = cw->ec->w, oh = cw->ec->h;
3984 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3985 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3989 e_comp_object_util_fullscreen(Evas_Object *obj)
3994 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3997 evas_object_move(obj, 0, 0);
3998 evas_object_resize(obj, e_comp->w, e_comp->h);
4003 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4011 ow = cw->w, oh = cw->h;
4013 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4014 zone = e_comp_object_util_zone_get(obj);
4015 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4016 if (x) *x = zx + (zw - ow) / 2;
4017 if (y) *y = zy + (zh - oh) / 2;
4021 e_comp_object_input_objs_del(Evas_Object *obj)
4024 E_Input_Rect_Data *input_rect_data;
4025 E_Input_Rect_Smart_Data *input_rect_sd;
4030 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4031 if (!input_rect_sd) return;
4033 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4035 if (input_rect_data->obj)
4037 evas_object_smart_member_del(input_rect_data->obj);
4038 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4040 E_FREE(input_rect_data);
4045 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4048 E_Input_Rect_Data *input_rect_data = NULL;
4049 E_Input_Rect_Smart_Data *input_rect_sd;
4050 int client_w, client_h;
4052 if (cw->ec->client.w)
4053 client_w = cw->ec->client.w;
4055 client_w = cw->ec->w;
4057 if (cw->ec->client.h)
4058 client_h = cw->ec->client.h;
4060 client_h = cw->ec->h;
4062 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4066 _e_comp_input_obj_smart_init();
4067 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4068 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4069 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4072 input_rect_sd->cw = cw;
4075 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4078 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4079 if (input_rect_data)
4081 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4082 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4086 if ((input_rect_data) &&
4087 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4089 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4090 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4091 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4092 evas_object_clip_set(input_rect_data->obj, cw->clip);
4093 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4094 evas_object_geometry_set(input_rect_data->obj,
4095 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4096 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4097 evas_object_pass_events_set(cw->default_input_obj, 1);
4098 evas_object_pass_events_set(cw->obj, 1);
4101 evas_object_show(input_rect_data->obj);
4102 evas_object_show(cw->input_obj);
4107 evas_object_smart_member_del(cw->input_obj);
4108 E_FREE_FUNC(cw->input_obj, evas_object_del);
4109 evas_object_pass_events_set(cw->default_input_obj, 0);
4110 evas_object_pass_events_set(cw->obj, 0);
4115 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4118 E_Input_Rect_Smart_Data *input_rect_sd;
4119 E_Input_Rect_Data *input_rect_data;
4122 if (!cw->input_obj) return;
4124 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4127 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4129 *list = eina_list_append(*list, &input_rect_data->rect);
4135 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4138 if (l) *l = cw->client_inset.l;
4139 if (r) *r = cw->client_inset.r;
4140 if (t) *t = cw->client_inset.t;
4141 if (b) *b = cw->client_inset.b;
4144 /* set geometry for CSD */
4146 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4152 if (cw->frame_object)
4153 CRI("ACK! ec:%p", cw->ec);
4154 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4155 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4156 calc = cw->client_inset.calc;
4157 cw->client_inset.calc = l || r || t || b;
4158 eina_stringshare_replace(&cw->frame_theme, "borderless");
4159 if (cw->client_inset.calc)
4161 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4162 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4163 e_client_size_set(cw->ec, tw, th);
4165 else if (cw->ec->maximized || cw->ec->fullscreen)
4167 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4168 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4170 if (!cw->ec->new_client)
4172 if (calc && cw->client_inset.calc)
4174 tx = cw->ec->x - (l - cw->client_inset.l);
4175 ty = cw->ec->y - (t - cw->client_inset.t);
4176 e_client_pos_set(cw->ec, tx, ty);
4178 cw->ec->changes.pos = cw->ec->changes.size = 1;
4181 cw->client_inset.l = l;
4182 cw->client_inset.r = r;
4183 cw->client_inset.t = t;
4184 cw->client_inset.b = b;
4188 e_comp_object_frame_allowed(Evas_Object *obj)
4190 API_ENTRY EINA_FALSE;
4191 return (cw->frame_object || (!cw->client_inset.calc));
4195 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4197 API_ENTRY EINA_FALSE;
4198 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4199 eina_stringshare_replace(&cw->frame_name, name);
4200 if (cw->frame_object)
4201 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4206 e_comp_object_frame_exists(Evas_Object *obj)
4208 API_ENTRY EINA_FALSE;
4209 return !!cw->frame_object;
4213 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4215 Evas_Object *o, *pbg;
4218 Eina_Stringshare *theme;
4220 API_ENTRY EINA_FALSE;
4222 if (!e_util_strcmp(cw->frame_theme, name))
4223 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4224 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4225 return _e_comp_object_shadow_setup(cw);
4226 pbg = cw->frame_object;
4227 theme = eina_stringshare_add(name);
4229 if (cw->frame_object)
4233 w = cw->ec->w, h = cw->ec->h;
4234 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4235 if ((cw->ec->w != w) || (cw->ec->h != h))
4237 cw->ec->changes.size = 1;
4240 E_FREE_FUNC(cw->frame_object, evas_object_del);
4241 if (!name) goto reshadow;
4243 o = edje_object_add(e_comp->evas);
4244 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4245 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4246 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4248 cw->frame_object = NULL;
4250 eina_stringshare_del(cw->frame_theme);
4251 cw->frame_theme = theme;
4256 if (theme != e_config->theme_default_border_style)
4258 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4259 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4263 ok = e_theme_edje_object_set(o, "base/theme/border",
4264 "e/widgets/border/default/border");
4265 if (ok && (theme == e_config->theme_default_border_style))
4267 /* Reset default border style to default */
4268 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4269 e_config_save_queue();
4276 cw->frame_object = o;
4277 eina_stringshare_del(cw->frame_theme);
4278 cw->frame_theme = theme;
4279 evas_object_name_set(o, "cw->frame_object");
4282 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4286 cw->ec->changes.icon = 1;
4292 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4297 _e_comp_object_shadow_setup(cw);
4300 int old_x, old_y, new_x = 0, new_y = 0;
4302 old_x = cw->x, old_y = cw->y;
4304 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4306 new_x = cw->ec->x, new_y = cw->ec->y;
4307 else if (cw->ec->placed || (!cw->ec->new_client))
4309 /* if no previous frame:
4310 * - reapply client_inset
4315 if (cw->ec->changes.size)
4323 zone = e_comp_zone_find_by_ec(cw->ec);
4326 x = cw->ec->client.x, y = cw->ec->client.y;
4327 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4328 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4330 new_x = x, new_y = y;
4333 if (old_x != new_x || old_y != new_y)
4335 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4336 cw->y = cw->x = -99999;
4337 evas_object_move(obj, new_x, new_y);
4341 if (cw->ec->maximized)
4343 cw->ec->changes.need_maximize = 1;
4346 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4347 if (cw->frame_object)
4349 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4352 cw->frame_extends = 0;
4353 evas_object_del(pbg);
4358 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4360 E_Comp_Object_Mover *prov;
4363 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4364 edje_object_signal_emit(cw->shobj, sig, src);
4365 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4366 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4367 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4369 /* start with highest priority callback first */
4370 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4372 if (!e_util_glob_match(sig, prov->sig)) continue;
4373 if (prov->func(prov->data, obj, sig)) break;
4378 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4380 /* FIXME: at some point I guess this should use eo to inherit
4381 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4382 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4385 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4389 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4392 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4396 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4399 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4403 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4406 Eina_Rectangle rect;
4409 if (cw->ec->input_only || (!cw->updates)) return;
4410 if (cw->nocomp) return;
4411 rect.x = x, rect.y = y;
4412 rect.w = w, rect.h = h;
4413 evas_object_smart_callback_call(obj, "damage", &rect);
4415 if (e_comp_is_on_overlay(cw->ec))
4417 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4418 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4419 * E module attempts to block screen update due to the particular policy.
4421 if (e_pixmap_resource_get(cw->ec->pixmap))
4422 cw->hwc_need_update = EINA_TRUE;
4425 /* ignore overdraw */
4426 if (cw->updates_full)
4428 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4429 e_comp_object_render_update_add(obj);
4431 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4432 evas_object_show(cw->smart_obj);
4436 /* clip rect to client surface */
4437 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4438 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4439 /* if rect is the total size of the client after clip, clear the updates
4440 * since this is guaranteed to be the whole region anyway
4442 eina_tiler_area_size_get(cw->updates, &tw, &th);
4443 if ((w > tw) || (h > th))
4445 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4446 eina_tiler_clear(cw->updates);
4447 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4449 tw = cw->ec->client.w, th = cw->ec->client.h;
4451 if ((!x) && (!y) && (w == tw) && (h == th))
4453 eina_tiler_clear(cw->updates);
4454 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4455 cw->updates_full = 1;
4456 cw->update_count = 0;
4459 if (cw->update_count > UPDATE_MAX)
4461 /* this is going to get really dumb, so just update the whole thing */
4462 eina_tiler_clear(cw->updates);
4463 cw->update_count = cw->updates_full = 1;
4464 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4465 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4469 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4470 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4472 cw->updates_exist = 1;
4473 e_comp_object_render_update_add(obj);
4475 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4476 evas_object_show(cw->smart_obj);
4480 e_comp_object_damage_exists(Evas_Object *obj)
4482 API_ENTRY EINA_FALSE;
4483 return cw->updates_exist;
4487 e_comp_object_render_update_add(Evas_Object *obj)
4491 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4492 if (cw->render_update_lock.lock) return;
4493 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4497 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4499 e_comp_render_queue();
4503 e_comp_object_render_update_del(Evas_Object *obj)
4507 if (cw->ec->input_only || (!cw->updates)) return;
4508 if (!cw->update) return;
4510 /* this gets called during comp animating to clear the update flag */
4511 if (e_comp->grabbed) return;
4512 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4513 if (!e_comp->updates)
4515 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4516 if (e_comp->render_animator)
4517 ecore_animator_freeze(e_comp->render_animator);
4522 e_comp_object_shape_apply(Evas_Object *obj)
4526 unsigned int i, *pix, *p;
4530 if (!cw->ec) return; //NYI
4531 if (cw->external_content) return;
4534 if ((cw->ec->shape_rects_num >= 1) &&
4535 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4540 ERR("BUGGER: shape with native surface? cw=%p", cw);
4543 evas_object_image_size_get(cw->obj, &w, &h);
4544 if ((w < 1) || (h < 1)) return;
4547 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4548 _e_comp_object_alpha_set(cw);
4549 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4550 evas_object_image_alpha_set(o, 1);
4552 p = pix = evas_object_image_data_get(cw->obj, 1);
4555 evas_object_image_data_set(cw->obj, pix);
4560 unsigned char *spix, *sp;
4562 spix = calloc(w * h, sizeof(unsigned char));
4564 for (i = 0; i < cw->ec->shape_rects_num; i++)
4568 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4569 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4570 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4571 sp = spix + (w * ry) + rx;
4572 for (py = 0; py < rh; py++)
4574 for (px = 0; px < rw; px++)
4582 for (py = 0; py < h; py++)
4584 for (px = 0; px < w; px++)
4586 unsigned int mask, imask;
4588 mask = ((unsigned int)(*sp)) << 24;
4590 imask |= imask >> 8;
4591 imask |= imask >> 8;
4592 *p = mask | (*p & imask);
4593 //if (*sp) *p = 0xff000000 | *p;
4594 //else *p = 0x00000000;
4603 for (py = 0; py < h; py++)
4605 for (px = 0; px < w; px++)
4609 evas_object_image_data_set(cw->obj, pix);
4610 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4611 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4613 evas_object_image_data_set(o, pix);
4614 evas_object_image_data_update_add(o, 0, 0, w, h);
4616 // don't need to fix alpha chanel as blending
4617 // should be totally off here regardless of
4618 // alpha channel content
4622 _e_comp_object_clear(E_Comp_Object *cw)
4627 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4629 if (cw->render_update_lock.lock) return;
4632 e_pixmap_clear(cw->ec->pixmap);
4634 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4635 evas_object_image_size_set(cw->obj, 1, 1);
4636 evas_object_image_data_set(cw->obj, NULL);
4637 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4639 evas_object_image_size_set(o, 1, 1);
4640 evas_object_image_data_set(o, NULL);
4643 e_comp_object_render_update_del(cw->smart_obj);
4647 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4651 API_ENTRY EINA_FALSE;
4653 if (cw->transparent.set == set)
4658 evas_object_color_get(obj, &r, &g, &b, &a);
4659 evas_object_color_set(obj, 0, 0, 0, 0);
4661 cw->transparent.user_r = r;
4662 cw->transparent.user_g = g;
4663 cw->transparent.user_b = b;
4664 cw->transparent.user_a = a;
4666 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4668 cw->transparent.user_r,
4669 cw->transparent.user_g,
4670 cw->transparent.user_b,
4671 cw->transparent.user_a);
4673 cw->transparent.set = EINA_TRUE;
4677 cw->transparent.set = EINA_FALSE;
4679 evas_object_color_set(obj,
4680 cw->transparent.user_r,
4681 cw->transparent.user_g,
4682 cw->transparent.user_b,
4683 cw->transparent.user_a);
4685 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4687 cw->transparent.user_r,
4688 cw->transparent.user_g,
4689 cw->transparent.user_b,
4690 cw->transparent.user_a);
4696 /* helper function to simplify toggling of redirection for display servers which support it */
4698 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4703 if (cw->redirected == set) return;
4704 cw->redirected = set;
4705 if (cw->external_content) return;
4707 e_comp_object_map_update(obj);
4711 if (cw->updates_exist)
4712 e_comp_object_render_update_add(obj);
4714 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4716 _e_comp_object_transparent_set(obj, EINA_FALSE);
4717 evas_object_smart_callback_call(obj, "redirected", NULL);
4721 _e_comp_object_clear(cw);
4722 _e_comp_object_transparent_set(obj, EINA_TRUE);
4723 evas_object_smart_callback_call(obj, "unredirected", NULL);
4728 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4731 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4733 if (cw->buffer_destroy_listener.notify)
4735 cw->buffer_destroy_listener.notify = NULL;
4736 wl_list_remove(&cw->buffer_destroy_listener.link);
4739 if (e_object_is_del(E_OBJECT(cw->ec)))
4741 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4746 /* if it's current displaying buffer, do not remove its content */
4747 if (!evas_object_visible_get(cw->ec->frame))
4748 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4753 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4758 if (cw->buffer_destroy_listener.notify)
4760 wl_list_remove(&cw->buffer_destroy_listener.link);
4761 cw->buffer_destroy_listener.notify = NULL;
4764 if (cw->tbm_surface)
4766 tbm_surface_internal_unref(cw->tbm_surface);
4767 cw->tbm_surface = NULL;
4772 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4774 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4775 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4777 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4779 tbm_surface_internal_ref(ns->data.tbm.buffer);
4780 cw->tbm_surface = ns->data.tbm.buffer;
4784 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4785 evas_object_image_native_surface_set(cw->obj, ns);
4789 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4791 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4792 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4793 evas_object_image_native_surface_set(o, ns);
4800 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4802 Evas_Native_Surface ns;
4805 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4806 if (cw->ec->input_only) return;
4807 if (cw->external_content) return;
4808 if (cw->render_update_lock.lock) return;
4811 memset(&ns, 0, sizeof(Evas_Native_Surface));
4815 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4816 set = (!cw->ec->shaped);
4818 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4822 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4826 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4829 if (cw->ec->input_only) return;
4832 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4833 _e_comp_object_alpha_set(cw);
4835 e_comp_object_native_surface_set(obj, cw->native);
4836 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4840 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4846 if (cw->blanked == set) return;
4848 _e_comp_object_alpha_set(cw);
4851 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4852 evas_object_image_data_set(cw->obj, NULL);
4856 e_comp_object_native_surface_set(obj, 1);
4857 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4861 _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)
4866 if (!_damage_trace) return;
4870 if (!evas_object_visible_get(cw->obj)) return;
4872 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4874 o = evas_object_rectangle_add(e_comp->evas);
4875 evas_object_layer_set(o, E_LAYER_MAX);
4876 evas_object_name_set(o, "damage_trace");
4877 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4878 evas_object_resize(o, dmg_w, dmg_h);
4879 evas_object_color_set(o, 0, 128, 0, 128);
4880 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4881 evas_object_pass_events_set(o, EINA_TRUE);
4882 evas_object_show(o);
4884 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4886 dmg_w, dmg_h, dmg_x, dmg_y,
4887 origin->w, origin->h, origin->x, origin->y);
4889 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4892 /* mark an object as dirty and setup damages */
4894 e_comp_object_dirty(Evas_Object *obj)
4897 Eina_Rectangle *rect;
4901 Eina_Bool dirty, visible;
4905 if (cw->external_content) return;
4906 if (!cw->redirected) return;
4907 if (cw->render_update_lock.lock)
4909 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4912 /* only actually dirty if pixmap is available */
4913 if (!e_pixmap_resource_get(cw->ec->pixmap))
4915 // e_pixmap_size_get returns last attached buffer size
4916 // eventhough it is destroyed
4917 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4920 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4921 visible = cw->visible;
4922 if (!dirty) w = h = 1;
4923 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4925 evas_object_image_data_set(cw->obj, NULL);
4926 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4927 evas_object_image_size_set(cw->obj, tw, th);
4928 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4929 if (cw->pending_updates)
4930 eina_tiler_area_size_set(cw->pending_updates, w, h);
4931 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4933 evas_object_image_pixels_dirty_set(o, dirty);
4935 evas_object_image_data_set(o, NULL);
4936 evas_object_image_size_set(o, tw, th);
4937 visible |= evas_object_visible_get(o);
4941 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4945 e_comp_object_native_surface_set(obj, 1);
4947 m = _e_comp_object_map_damage_transform_get(cw->ec);
4948 it = eina_tiler_iterator_new(cw->updates);
4949 EINA_ITERATOR_FOREACH(it, rect)
4951 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4952 * of evas engine and doesn't convert damage according to evas_map.
4953 * so damage of evas_object_image use surface coordinate.
4957 int damage_x, damage_y, damage_w, damage_h;
4959 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4960 &damage_x, &damage_y, &damage_w, &damage_h);
4961 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4962 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4966 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4967 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4970 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4971 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4972 if (cw->pending_updates)
4973 eina_tiler_rect_add(cw->pending_updates, rect);
4975 eina_iterator_free(it);
4976 if (m) e_map_free(m);
4977 if (cw->pending_updates)
4978 eina_tiler_clear(cw->updates);
4981 cw->pending_updates = cw->updates;
4982 cw->updates = eina_tiler_new(w, h);
4983 eina_tiler_tile_size_set(cw->updates, 1, 1);
4985 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4986 evas_object_smart_callback_call(obj, "dirty", NULL);
4987 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4988 /* force render if main object is hidden but mirrors are visible */
4989 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4990 e_comp_object_render(obj);
4994 e_comp_object_render(Evas_Object *obj)
5001 API_ENTRY EINA_FALSE;
5003 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5004 if (cw->ec->input_only) return EINA_TRUE;
5005 if (cw->external_content) return EINA_TRUE;
5006 if (cw->native) return EINA_FALSE;
5007 /* if comp object is not redirected state, comp object should not be set by newly committed data
5008 because image size of comp object is 1x1 and it should not be shown on canvas */
5009 if (!cw->redirected) return EINA_TRUE;
5010 if (cw->render_update_lock.lock)
5012 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5015 e_comp_object_render_update_del(obj);
5016 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5018 if (!cw->pending_updates)
5020 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5021 evas_object_image_data_set(cw->obj, NULL);
5022 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5023 evas_object_image_data_set(o, NULL);
5027 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5029 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5031 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5034 e_pixmap_image_refresh(cw->ec->pixmap);
5035 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5038 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5039 e_pixmap_image_data_ref(cw->ec->pixmap);
5041 /* set pixel data */
5042 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5043 _e_comp_object_alpha_set(cw);
5044 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5046 evas_object_image_data_set(o, pix);
5047 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5048 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5051 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5053 e_comp_client_post_update_add(cw->ec);
5058 /* create a duplicate of an evas object */
5060 e_comp_object_util_mirror_add(Evas_Object *obj)
5064 unsigned int *pix = NULL;
5065 Eina_Bool argb = EINA_FALSE;
5070 cw = evas_object_data_get(obj, "comp_mirror");
5073 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5074 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5075 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5076 evas_object_image_alpha_set(o, 1);
5077 evas_object_image_source_set(o, obj);
5080 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5081 if (cw->external_content)
5083 ERR("%p of client %p is external content.", obj, cw->ec);
5086 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5087 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5088 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5089 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5090 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5091 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5092 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5093 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5094 evas_object_data_set(o, "comp_mirror", cw);
5096 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5097 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5099 evas_object_image_size_set(o, tw, th);
5102 pix = evas_object_image_data_get(cw->obj, 0);
5108 evas_object_image_native_surface_set(o, cw->ns);
5111 Evas_Native_Surface ns;
5112 memset(&ns, 0, sizeof(Evas_Native_Surface));
5113 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5114 evas_object_image_native_surface_set(o, &ns);
5119 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5120 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5122 (e_pixmap_image_exists(cw->ec->pixmap)))
5123 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5125 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5132 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5133 evas_object_image_pixels_dirty_set(o, dirty);
5134 evas_object_image_data_set(o, pix);
5135 evas_object_image_data_set(cw->obj, pix);
5137 evas_object_image_data_update_add(o, 0, 0, tw, th);
5142 //////////////////////////////////////////////////////
5145 e_comp_object_effect_allowed_get(Evas_Object *obj)
5147 API_ENTRY EINA_FALSE;
5149 if (!cw->shobj) return EINA_FALSE;
5150 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5151 return !e_comp_config_get()->match.disable_borders;
5154 /* setup an api effect for a client */
5156 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5159 Eina_Stringshare *grp;
5160 E_Comp_Config *config;
5161 Eina_Bool loaded = EINA_FALSE;
5163 API_ENTRY EINA_FALSE;
5164 if (!cw->shobj) return EINA_FALSE; //input window
5166 if (!effect) effect = "none";
5167 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5169 config = e_comp_config_get();
5170 if ((config) && (config->effect_file))
5172 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5174 cw->effect_set = EINA_TRUE;
5181 edje_object_file_get(cw->effect_obj, NULL, &grp);
5182 cw->effect_set = !eina_streq(effect, "none");
5183 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5184 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5186 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5187 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5188 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5190 if (cw->effect_running)
5192 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5195 cw->effect_set = EINA_FALSE;
5196 return cw->effect_set;
5200 if (cw->effect_running)
5202 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5205 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5206 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5207 if (cw->effect_clip)
5209 evas_object_clip_unset(cw->clip);
5210 cw->effect_clip = 0;
5212 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5214 _e_comp_object_dim_update(cw);
5216 return cw->effect_set;
5219 /* set params for embryo scripts in effect */
5221 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5223 Edje_Message_Int_Set *msg;
5227 EINA_SAFETY_ON_NULL_RETURN(params);
5228 EINA_SAFETY_ON_FALSE_RETURN(count);
5229 if (!cw->effect_set) return;
5231 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5232 msg->count = (int)count;
5233 for (x = 0; x < count; x++)
5234 msg->val[x] = params[x];
5235 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5236 edje_object_message_signal_process(cw->effect_obj);
5240 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5242 Edje_Signal_Cb end_cb;
5244 E_Comp_Object *cw = data;
5246 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5247 cw->effect_running = 0;
5248 if (!_e_comp_object_animating_end(cw)) return;
5250 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5252 evas_object_data_del(cw->smart_obj, "effect_running");
5253 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5254 e_comp_visibility_calculation_set(EINA_TRUE);
5257 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5258 if (!end_cb) return;
5259 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5260 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5261 end_cb(end_data, cw->smart_obj, emission, source);
5264 /* clip effect to client's zone */
5266 e_comp_object_effect_clip(Evas_Object *obj)
5270 zone = e_comp_zone_find_by_ec(cw->ec);
5272 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5273 if (!cw->effect_clip_able) return;
5274 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5275 cw->effect_clip = 1;
5278 /* unclip effect from client's zone */
5280 e_comp_object_effect_unclip(Evas_Object *obj)
5283 if (!cw->effect_clip) return;
5284 evas_object_clip_unset(cw->smart_obj);
5285 cw->effect_clip = 0;
5288 /* start effect, running end_cb after */
5290 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5292 API_ENTRY EINA_FALSE;
5293 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5294 if (!cw->effect_set) return EINA_FALSE;
5296 if (cw->effect_running)
5298 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5301 e_comp_object_effect_clip(obj);
5302 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5304 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5305 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5306 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5307 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5309 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5310 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5312 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5313 _e_comp_object_animating_begin(cw);
5314 cw->effect_running = 1;
5318 /* stop a currently-running effect immediately */
5320 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5323 Edje_Signal_Cb end_cb_before = NULL;
5324 void *end_data_before = NULL;
5325 API_ENTRY EINA_FALSE;
5327 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5328 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5330 if (end_cb_before != end_cb) return EINA_TRUE;
5331 e_comp_object_effect_unclip(obj);
5332 if (cw->effect_clip)
5334 evas_object_clip_unset(cw->effect_obj);
5335 cw->effect_clip = 0;
5337 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5338 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5340 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5342 evas_object_data_del(cw->smart_obj, "effect_running");
5343 e_comp_visibility_calculation_set(EINA_TRUE);
5346 cw->effect_running = 0;
5347 ret = _e_comp_object_animating_end(cw);
5349 if ((ret) && (end_cb_before))
5351 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5352 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5359 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5361 return a->pri - b->pri;
5364 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5365 E_API E_Comp_Object_Mover *
5366 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5368 E_Comp_Object_Mover *prov;
5370 prov = E_NEW(E_Comp_Object_Mover, 1);
5371 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5372 prov->func = provider;
5373 prov->data = (void*)data;
5376 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5377 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5382 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5384 EINA_SAFETY_ON_NULL_RETURN(prov);
5385 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5390 e_comp_object_effect_object_get(Evas_Object *obj)
5394 return cw->effect_obj;
5398 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5400 API_ENTRY EINA_FALSE;
5401 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5402 if (!cw->effect_set) return EINA_FALSE;
5409 ////////////////////////////////////
5412 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5414 if (e_comp->autoclose.obj)
5416 e_comp_ungrab_input(0, 1);
5417 if (e_comp->autoclose.del_cb)
5418 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5419 else if (!already_del)
5421 evas_object_hide(e_comp->autoclose.obj);
5422 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5424 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5426 e_comp->autoclose.obj = NULL;
5427 e_comp->autoclose.data = NULL;
5428 e_comp->autoclose.del_cb = NULL;
5429 e_comp->autoclose.key_cb = NULL;
5430 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5434 _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)
5436 _e_comp_object_autoclose_cleanup(0);
5440 _e_comp_object_autoclose_setup(Evas_Object *obj)
5442 if (!e_comp->autoclose.rect)
5444 /* create rect just below autoclose object to catch mouse events */
5445 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5446 evas_object_move(e_comp->autoclose.rect, 0, 0);
5447 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5448 evas_object_show(e_comp->autoclose.rect);
5449 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5450 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5451 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5452 e_comp_grab_input(0, 1);
5454 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5455 evas_object_focus_set(obj, 1);
5459 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5461 _e_comp_object_autoclose_setup(obj);
5462 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5466 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5468 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5469 _e_comp_object_autoclose_cleanup(1);
5470 if (e_client_focused_get()) return;
5472 E_Zone *zone = e_zone_current_get();
5475 e_zone_focus_reset(zone);
5479 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5483 if (e_comp->autoclose.obj)
5485 if (e_comp->autoclose.obj == obj) return;
5486 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5487 e_comp->autoclose.obj = obj;
5488 e_comp->autoclose.del_cb = del_cb;
5489 e_comp->autoclose.key_cb = cb;
5490 e_comp->autoclose.data = (void*)data;
5491 if (evas_object_visible_get(obj))
5492 _e_comp_object_autoclose_setup(obj);
5494 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5495 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5498 e_comp->autoclose.obj = obj;
5499 e_comp->autoclose.del_cb = del_cb;
5500 e_comp->autoclose.key_cb = cb;
5501 e_comp->autoclose.data = (void*)data;
5502 if (evas_object_visible_get(obj))
5503 _e_comp_object_autoclose_setup(obj);
5505 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5506 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5510 e_comp_object_is_animating(Evas_Object *obj)
5514 return cw->animating;
5518 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5522 if ((cw->external_content) &&
5523 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5525 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5526 "But current external content is %d object for %p.",
5527 cw->content_type, cw->ec);
5531 cw->user_alpha_set = EINA_TRUE;
5532 cw->user_alpha = alpha;
5534 if (!cw->obj) return;
5536 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5538 evas_object_image_alpha_set(cw->obj, alpha);
5540 if ((!cw->native) && (!cw->external_content))
5541 evas_object_image_data_set(cw->obj, NULL);
5545 e_comp_object_alpha_get(Evas_Object *obj)
5547 API_ENTRY EINA_FALSE;
5549 return evas_object_image_alpha_get(cw->obj);
5553 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5555 Eina_Bool mask_set = EINA_FALSE;
5559 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5560 if (cw->ec->input_only) return;
5567 o = evas_object_rectangle_add(e_comp->evas);
5568 evas_object_color_set(o, 0, 0, 0, 0);
5569 evas_object_clip_set(o, cw->clip);
5570 evas_object_smart_member_add(o, obj);
5571 evas_object_move(o, 0, 0);
5572 evas_object_resize(o, cw->w, cw->h);
5573 /* save render op value to restore when clear a mask.
5575 * NOTE: DO NOT change the render op on ec->frame while mask object
5576 * is set. it will overwrite the changed op value. */
5577 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5578 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5579 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5580 if (cw->visible) evas_object_show(o);
5583 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5584 ELOGF("COMP", " |mask_obj", cw->ec);
5585 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5592 evas_object_smart_member_del(cw->mask.obj);
5593 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5595 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5596 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5602 e_comp_object_mask_has(Evas_Object *obj)
5604 API_ENTRY EINA_FALSE;
5606 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5610 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5615 if ((cw->external_content) &&
5616 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5618 WRN("Can set up size to ONLY evas \"image\" object. "
5619 "But current external content is %d object for %p.",
5620 cw->content_type, cw->ec);
5624 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5626 evas_object_image_size_set(cw->obj, tw, th);
5630 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5632 Eina_Bool transform_set = EINA_FALSE;
5634 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5635 if (cw->ec->input_only) return;
5637 transform_set = !!set;
5641 if (!cw->transform_bg_obj)
5643 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5644 evas_object_move(o, 0, 0);
5645 evas_object_resize(o, 1, 1);
5646 if (cw->transform_bg_color.a >= 255)
5647 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5649 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5650 evas_object_color_set(o,
5651 cw->transform_bg_color.r,
5652 cw->transform_bg_color.g,
5653 cw->transform_bg_color.b,
5654 cw->transform_bg_color.a);
5655 if (cw->visible) evas_object_show(o);
5657 cw->transform_bg_obj = o;
5658 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5660 _e_comp_object_transform_obj_stack_update(obj);
5664 if (cw->transform_bg_obj)
5666 evas_object_smart_member_del(cw->transform_bg_obj);
5667 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5673 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5677 cw->transform_bg_color.r = r;
5678 cw->transform_bg_color.g = g;
5679 cw->transform_bg_color.b = b;
5680 cw->transform_bg_color.a = a;
5682 if (cw->transform_bg_obj)
5684 evas_object_color_set(cw->transform_bg_obj,
5685 cw->transform_bg_color.r,
5686 cw->transform_bg_color.g,
5687 cw->transform_bg_color.b,
5688 cw->transform_bg_color.a);
5693 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5696 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5697 if (cw->ec->input_only) return;
5698 if (!cw->transform_bg_obj) return;
5700 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5704 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5707 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5708 if (cw->ec->input_only) return;
5709 if (!cw->transform_bg_obj) return;
5711 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5715 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5717 Eina_Bool transform_set = EINA_FALSE;
5719 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5720 if (cw->ec->input_only) return;
5722 transform_set = !!set;
5726 if (!cw->transform_tranp_obj)
5728 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5729 evas_object_move(o, 0, 0);
5730 evas_object_resize(o, 1, 1);
5731 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5732 evas_object_color_set(o, 0, 0, 0, 0);
5733 if (cw->visible) evas_object_show(o);
5735 cw->transform_tranp_obj = o;
5736 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5737 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5738 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5740 _e_comp_object_transform_obj_stack_update(obj);
5744 if (cw->transform_tranp_obj)
5746 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5747 evas_object_smart_member_del(cw->transform_tranp_obj);
5748 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5754 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5757 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5758 if (cw->ec->input_only) return;
5759 if (!cw->transform_tranp_obj) return;
5761 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5765 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5768 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5769 if (cw->ec->input_only) return;
5770 if (!cw->transform_tranp_obj) return;
5772 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5775 #ifdef REFACTOR_DESK_AREA
5778 e_comp_object_layer_update(Evas_Object *obj,
5779 Evas_Object *above, Evas_Object *below)
5781 E_Comp_Object *cw2 = NULL;
5782 Evas_Object *o = NULL;
5787 if (cw->ec->layer_block) return;
5788 if ((above) && (below))
5790 ERR("Invalid layer update request! cw=%p", cw);
5798 layer = evas_object_layer_get(o);
5799 cw2 = evas_object_data_get(o, "comp_obj");
5802 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5804 o = evas_object_above_get(o);
5805 if ((!o) || (o == cw->smart_obj)) break;
5806 if (evas_object_layer_get(o) != layer)
5808 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5813 ec = e_client_top_get();
5814 if (ec) o = ec->frame;
5817 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5821 _e_comp_object_layers_remove(cw);
5824 if (cw2->layer > cw->layer)
5825 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5826 else if (cw2->layer == cw->layer)
5829 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5831 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5833 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5836 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5839 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5844 e_comp_object_layer_get(Evas_Object *obj)
5851 e_comp_object_content_set(Evas_Object *obj,
5852 Evas_Object *content,
5853 E_Comp_Object_Content_Type type)
5855 API_ENTRY EINA_FALSE;
5857 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5858 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5859 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5863 ERR("Can't set e.swallow.content to requested content. "
5864 "Previous comp object should not be changed at all.");
5868 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5870 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5871 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5873 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5874 type, content, cw->ec, cw->ec->pixmap);
5878 cw->external_content = EINA_TRUE;
5881 cw->content_type = type;
5882 e_util_size_debug_set(cw->obj, 1);
5883 evas_object_name_set(cw->obj, "cw->obj");
5884 _e_comp_object_alpha_set(cw);
5887 _e_comp_object_shadow_setup(cw);
5893 e_comp_object_content_unset(Evas_Object *obj)
5895 API_ENTRY EINA_FALSE;
5897 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5898 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5900 if (!cw->obj && !cw->ec->visible)
5902 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5906 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5908 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5914 if (cw->frame_object)
5915 edje_object_part_unswallow(cw->frame_object, cw->obj);
5917 edje_object_part_unswallow(cw->shobj, cw->obj);
5919 evas_object_del(cw->obj);
5920 evas_object_hide(cw->obj);
5924 cw->external_content = EINA_FALSE;
5925 if (cw->ec->is_cursor)
5928 DBG("%p is cursor surface..", cw->ec);
5929 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5931 evas_object_resize(cw->ec->frame, pw, ph);
5932 evas_object_hide(cw->ec->frame);
5937 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5938 cw->obj = evas_object_image_filled_add(e_comp->evas);
5939 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5940 e_util_size_debug_set(cw->obj, 1);
5941 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5942 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5943 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5944 evas_object_name_set(cw->obj, "cw->obj");
5945 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5946 _e_comp_object_alpha_set(cw);
5949 _e_comp_object_shadow_setup(cw);
5954 _e_comp_intercept_show_helper(cw);
5958 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5959 e_comp_object_dirty(cw->smart_obj);
5960 e_comp_object_render(cw->smart_obj);
5961 e_comp_object_render_update_add(obj);
5966 EINTERN Evas_Object *
5967 e_comp_object_content_get(Evas_Object *obj)
5971 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5973 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5975 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5982 E_API E_Comp_Object_Content_Type
5983 e_comp_object_content_type_get(Evas_Object *obj)
5985 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5987 return cw->content_type;
5991 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5994 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5995 E_Comp_Config *conf = e_comp_config_get();
5996 if (cw->ec->input_only) return;
5997 if (!conf->dim_rect_enable) return;
5999 cw->dim.mask_set = mask_set;
6005 if (!cw->dim.enable) return;
6006 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6010 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6012 Eina_Bool mask_set = EINA_FALSE;
6016 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6017 E_Comp_Config *conf = e_comp_config_get();
6018 if (cw->ec->input_only) return;
6019 if (!conf->dim_rect_enable) return;
6025 if (cw->dim.mask_obj)
6027 evas_object_smart_member_del(cw->dim.mask_obj);
6028 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6031 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);
6032 o = evas_object_rectangle_add(e_comp->evas);
6033 evas_object_color_set(o, 0, 0, 0, 0);
6034 evas_object_smart_member_add(o, obj);
6035 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6036 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6038 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6039 if (cw->visible) evas_object_show(o);
6041 cw->dim.mask_obj = o;
6042 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6044 evas_object_layer_set(cw->dim.mask_obj, 9998);
6048 if (cw->dim.mask_obj)
6050 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6051 evas_object_smart_member_del(cw->dim.mask_obj);
6052 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6058 e_comp_object_dim_client_set(E_Client *ec)
6060 E_Comp_Config *conf = e_comp_config_get();
6062 if (!conf->dim_rect_enable) return ;
6063 if (dim_client == ec) return;
6065 Eina_Bool prev_dim = EINA_FALSE;
6066 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6068 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6069 prev_dim = EINA_TRUE;
6071 if (prev_dim && dim_client->visible && ec)
6073 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6074 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6078 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6079 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6085 e_comp_object_dim_client_get(void)
6087 E_Comp_Config *conf = e_comp_config_get();
6089 if (!conf->dim_rect_enable ) return NULL;
6095 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6098 char emit[32] = "\0";
6099 E_Comp_Config *conf = e_comp_config_get();
6102 if (!conf->dim_rect_enable) return;
6103 if (!cw->effect_obj) return;
6104 if (enable == cw->dim.enable) return;
6106 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6107 if (noeffect || !conf->dim_rect_effect)
6109 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6113 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6116 cw->dim.enable = enable;
6118 if (cw->dim.mask_set && !enable)
6120 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6121 edje_object_signal_emit(cw->effect_obj, emit, "e");
6123 else if (cw->dim.mask_set && enable)
6125 edje_object_signal_emit(cw->effect_obj, emit, "e");
6126 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6130 edje_object_signal_emit(cw->effect_obj, emit, "e");
6135 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6137 API_ENTRY EINA_FALSE;
6138 E_Comp_Config *conf = e_comp_config_get();
6140 if (!ec) return EINA_FALSE;
6141 if (!conf->dim_rect_enable) return EINA_FALSE;
6143 if (cw->dim.enable) return EINA_TRUE;
6149 _e_comp_object_dim_update(E_Comp_Object *cw)
6151 E_Comp_Config *conf = e_comp_config_get();
6154 if (!conf->dim_rect_enable) return;
6155 if (!cw->effect_obj) return;
6158 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6159 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6161 if (cw->dim.mask_set)
6163 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6169 e_comp_object_clear(Evas_Object *obj)
6173 _e_comp_object_clear(cw);
6177 e_comp_object_hwc_update_exists(Evas_Object *obj)
6179 API_ENTRY EINA_FALSE;
6180 return cw->hwc_need_update;
6185 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6188 cw->hwc_need_update = set;
6192 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6194 API_ENTRY EINA_FALSE;
6195 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6199 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6202 if (cw->indicator.obj != indicator)
6203 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6204 cw->indicator.obj = indicator;
6205 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6209 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6212 if (cw->indicator.obj != indicator) return;
6213 cw->indicator.obj = NULL;
6214 edje_object_part_unswallow(cw->shobj, indicator);
6218 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6221 Edje_Message_Int_Set *msg;
6223 if (!cw->indicator.obj) return;
6225 cw->indicator.w = w;
6226 cw->indicator.h = h;
6228 if (!cw->shobj) return;
6230 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6234 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6235 edje_object_message_signal_process(cw->shobj);
6238 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6240 e_comp_object_map_update(Evas_Object *obj)
6243 E_Client *ec = cw->ec;
6244 E_Comp_Wl_Client_Data *cdata;
6246 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6249 int l, remain = sizeof buffer;
6252 if (e_object_is_del(E_OBJECT(ec))) return;
6253 cdata = e_client_cdata_get(ec);
6256 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6257 * when new buffer is attached.
6259 if (!cdata->buffer_ref.buffer) return;
6261 if ((!cw->redirected) ||
6262 (e_client_video_hw_composition_check(ec)) ||
6263 (!e_comp_wl_output_buffer_transform_get(ec) &&
6264 cdata->scaler.buffer_viewport.buffer.scale == 1))
6266 if (evas_object_map_enable_get(cw->effect_obj))
6268 ELOGF("TRANSFORM", "map: disable", cw->ec);
6269 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6270 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6271 evas_object_resize(cw->effect_obj, tw, th);
6278 EINA_SAFETY_ON_NULL_RETURN(map);
6280 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6286 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6288 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6289 e_map_point_image_uv_set(map, 0, x, y);
6290 l = snprintf(p, remain, "%d,%d", x, y);
6291 p += l, remain -= l;
6293 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6294 e_map_point_image_uv_set(map, 1, x, y);
6295 l = snprintf(p, remain, " %d,%d", x, y);
6296 p += l, remain -= l;
6298 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6299 e_map_point_image_uv_set(map, 2, x, y);
6300 l = snprintf(p, remain, " %d,%d", x, y);
6301 p += l, remain -= l;
6303 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6304 e_map_point_image_uv_set(map, 3, x, y);
6305 l = snprintf(p, remain, " %d,%d", x, y);
6306 p += l, remain -= l;
6308 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6310 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6312 e_comp_object_map_set(cw->effect_obj, map);
6313 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6317 /* if there's screen rotation with comp mode, then ec->effect_obj and
6318 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6320 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6321 evas_object_resize(cw->effect_obj, tw, th);
6325 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6327 API_ENTRY EINA_FALSE;
6329 cw->render_trace = set;
6335 e_comp_object_native_usable_get(Evas_Object *obj)
6337 API_ENTRY EINA_FALSE;
6338 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6340 if (cw->ec->input_only) return EINA_FALSE;
6341 if (cw->external_content) return EINA_FALSE;
6342 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6344 /* just return true value, if it is normal case */
6345 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6348 Evas_Native_Surface *ns;
6349 ns = evas_object_image_native_surface_get(cw->obj);
6351 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6354 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6362 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6364 API_ENTRY EINA_FALSE;
6365 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6366 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6367 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6371 case E_COMP_IMAGE_FILTER_BLUR:
6372 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6374 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6375 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6377 case E_COMP_IMAGE_FILTER_INVERSE:
6378 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6380 case E_COMP_IMAGE_FILTER_NONE:
6382 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6386 cw->image_filter = filter;
6391 EINTERN E_Comp_Image_Filter
6392 e_comp_object_image_filter_get(Evas_Object *obj)
6394 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6395 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6396 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6397 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6399 return cw->image_filter;
6403 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6407 if (!_damage_trace) return;
6409 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6410 evas_object_del(obj);
6412 _damage_trace_post_objs = NULL;
6416 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6418 if (!_damage_trace) return;
6420 _damage_trace_post_objs = _damage_trace_objs;
6421 _damage_trace_objs = NULL;
6425 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6427 if (_damage_trace == onoff) return;
6431 evas_event_callback_add(e_comp->evas,
6432 EVAS_CALLBACK_RENDER_PRE,
6433 _e_comp_object_damage_trace_render_pre_cb,
6436 evas_event_callback_add(e_comp->evas,
6437 EVAS_CALLBACK_RENDER_POST,
6438 _e_comp_object_damage_trace_render_post_cb,
6445 EINA_LIST_FREE(_damage_trace_objs, obj)
6446 evas_object_del(obj);
6448 _damage_trace_objs = NULL;
6450 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6451 evas_object_del(obj);
6453 _damage_trace_post_objs = NULL;
6455 evas_event_callback_del(e_comp->evas,
6456 EVAS_CALLBACK_RENDER_PRE,
6457 _e_comp_object_damage_trace_render_pre_cb);
6459 evas_event_callback_del(e_comp->evas,
6460 EVAS_CALLBACK_RENDER_POST,
6461 _e_comp_object_damage_trace_render_post_cb);
6464 _damage_trace = onoff;
6468 e_comp_object_redirected_get(Evas_Object *obj)
6470 API_ENTRY EINA_FALSE;
6471 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6473 return cw->redirected;
6477 e_comp_object_color_visible_get(Evas_Object *obj)
6479 API_ENTRY EINA_FALSE;
6482 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6484 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6488 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6492 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6496 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6504 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6506 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6508 return e_map_set_to_comp_object(em, obj);
6512 e_comp_object_map_get(const Evas_Object *obj)
6514 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6516 return e_map_get_from_comp_object(obj);
6520 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6522 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6524 evas_object_map_enable_set(obj, enable);
6530 e_comp_object_render_update_lock(Evas_Object *obj)
6532 E_Comp_Wl_Buffer *buffer;
6533 struct wayland_tbm_client_queue *cqueue;
6535 API_ENTRY EINA_FALSE;
6537 if (cw->render_update_lock.lock == 0)
6539 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6541 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6542 if ((buffer) && (buffer->resource))
6544 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6546 wayland_tbm_server_client_queue_flush(cqueue);
6549 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6550 e_comp_object_render_update_del(obj);
6552 ELOGF("COMP", "Render update lock enabled", cw->ec);
6555 cw->render_update_lock.lock++;
6561 e_comp_object_render_update_unlock(Evas_Object *obj)
6565 if (cw->render_update_lock.lock == 0)
6568 cw->render_update_lock.lock--;
6570 if (cw->render_update_lock.lock == 0)
6573 if (cw->render_update_lock.pending_move_set)
6575 evas_object_move(obj,
6576 cw->render_update_lock.pending_move_x,
6577 cw->render_update_lock.pending_move_y);
6578 cw->render_update_lock.pending_move_x = 0;
6579 cw->render_update_lock.pending_move_y = 0;
6580 cw->render_update_lock.pending_move_set = EINA_FALSE;
6583 if (cw->render_update_lock.pending_resize_set)
6585 evas_object_resize(obj,
6586 cw->render_update_lock.pending_resize_w,
6587 cw->render_update_lock.pending_resize_h);
6588 cw->render_update_lock.pending_resize_w = 0;
6589 cw->render_update_lock.pending_resize_h = 0;
6590 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6593 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6595 if ((cw->ec->exp_iconify.buffer_flush) &&
6596 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6597 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6598 e_comp_object_clear(obj);
6600 e_comp_object_render_update_add(obj);
6602 ELOGF("COMP", "Render update lock disabled", cw->ec);
6607 e_comp_object_render_update_lock_get(Evas_Object *obj)
6609 API_ENTRY EINA_FALSE;
6611 if (cw->render_update_lock.lock > 0)
6618 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6622 if (cw->transparent.set)
6624 if (r) *r = cw->transparent.user_r;
6625 if (g) *g = cw->transparent.user_g;
6626 if (b) *b = cw->transparent.user_b;
6627 if (a) *a = cw->transparent.user_a;
6631 evas_object_color_get(obj, r, g, b, a);
6636 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6640 evas_object_render_op_set(cw->obj, op);
6643 EINTERN Evas_Render_Op
6644 e_comp_object_render_op_get(Evas_Object *obj)
6646 API_ENTRY EVAS_RENDER_BLEND;
6648 return evas_object_render_op_get(cw->obj);
6652 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6655 wl_signal_add(&cw->events.lower, listener);
6658 #ifdef REFACTOR_DESK_AREA
6660 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6663 wl_signal_add(&cw->events.lower_done, listener);
6667 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6670 wl_signal_add(&cw->events.raise, listener);
6675 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6678 wl_signal_add(&cw->events.show, listener);
6682 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6685 wl_signal_add(&cw->events.hide, listener);
6688 #ifdef REFACTOR_DESK_AREA
6690 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6693 wl_signal_add(&cw->events.set_layer, listener);
6697 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6700 wl_signal_add(&cw->events.stack_above, listener);
6704 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6707 wl_signal_add(&cw->events.stack_below, listener);