2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
5 #include "e_bindings_intern.h"
6 #include "e_utils_intern.h"
7 #ifdef REFACTOR_DESK_AREA
9 #include "e_comp_canvas_intern.h"
12 #include "e_comp_cfdata_intern.h"
13 #include "e_comp_wl_subsurface_intern.h"
14 #include "e_comp_wl_tbm_intern.h"
15 #include "e_comp_intern.h"
16 #include "e_pixmap_intern.h"
17 #include "e_map_intern.h"
18 #include "e_hwc_window_intern.h"
19 #include "e_hwc_windows_intern.h"
23 = keys that return objects =
24 - E_Client: the client associated with the object (E_Client*)
25 - comp_smart_obj: cw->smart_obj (Evas_Object*)
26 - comp_obj: cw (E_Comp_Object*)
28 = keys that are bool flags =
29 - client_restack: client needs a protocol-level restack
30 - comp_override: object is triggering a nocomp override to force compositing
31 - comp_ref: object has a ref from visibility animations
32 - comp_showing: object is currently running its show animation
33 - comp_hiding: object is currently running its hiding animation
34 - comp_object: object is a compositor-created object
35 - comp_object_skip: object has a name which prohibits theme shadows
36 - comp_object-to_del: list of objects which will be deleted when this object is deleted
37 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
38 - effect_running: object is animating by external module
41 #define UPDATE_MAX 512 // same as evas
42 #define FAILURE_MAX 2 // seems reasonable
43 #define SMART_NAME "e_comp_object"
44 #define INPUT_OBJ_SMART_NAME "input_object"
46 /* for non-util functions */
47 #define API_ENTRY E_Comp_Object *cw; \
48 cw = evas_object_smart_data_get(obj); \
49 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
51 /* for util functions (obj may or may not be E_Comp_Object */
52 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
55 CRI("YOU PASSED NULL! ARGH!"); \
58 cw = evas_object_smart_data_get(obj); \
59 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
61 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
63 /* enable for lots of client size info in console output */
65 # define e_util_size_debug_set(x, y)
68 /* enable along with display-specific damage INF calls to enable render tracing
72 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
74 #define RENDER_DEBUG(...)
77 #ifdef REFACTOR_DESK_AREA
79 typedef struct _E_Comp_Object
83 int x, y, w, h; // geometry
87 E_Comp_Object_Frame client_inset;
89 Eina_Stringshare *frame_theme;
90 Eina_Stringshare *frame_name;
91 Eina_Stringshare *visibility_effect; //effect when toggling visibility
93 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
95 Evas_Object *smart_obj; // smart object
96 Evas_Object *clip; // clipper over effect object
97 Evas_Object *input_obj; // input smart object
98 Evas_Object *obj; // composite object
99 Evas_Object *frame_object; // for client frames
100 Evas_Object *shobj; // shadow object
101 Evas_Object *effect_obj; // effects object
102 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
106 } transform_bg_color;
107 Evas_Object *transform_tranp_obj;// transform transp rect obj
108 Evas_Object *default_input_obj; // default input object
109 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
110 Eina_List *obj_mirror; // extra mirror objects
111 Eina_Tiler *updates; //render update regions
112 Eina_Tiler *pending_updates; //render update regions which are about to render
114 Evas_Native_Surface *ns; //for custom gl rendering
116 struct wl_listener buffer_destroy_listener;
118 unsigned int update_count; // how many updates have happened to this obj
120 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
122 unsigned int animating; // it's busy animating
123 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
124 unsigned int force_visible; //number of visible obj_mirror objects
125 Eina_Bool delete_pending : 1; // delete pending
126 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
127 Eina_Bool showing : 1; // object is currently in "show" animation
128 Eina_Bool hiding : 1; // object is currently in "hide" animation
129 Eina_Bool visible : 1; // is visible
131 Eina_Bool shaped : 1; // is shaped
132 Eina_Bool update : 1; // has updates to fetch
133 Eina_Bool redirected : 1; // has updates to fetch
134 Eina_Bool native : 1; // native
136 Eina_Bool nocomp : 1; // nocomp applied
137 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
138 Eina_Bool real_hid : 1; // last hide was a real window unmap
140 Eina_Bool effect_set : 1; //effect_obj has a valid group
141 Eina_Bool effect_running : 1; //effect_obj is playing an animation
142 Eina_Bool effect_clip : 1; //effect_obj is clipped
143 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
145 Eina_Bool updates_exist : 1;
146 Eina_Bool updates_full : 1; // entire object will be updated
148 Eina_Bool force_move : 1;
149 Eina_Bool frame_extends : 1; //frame may extend beyond object size
150 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
151 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
152 Eina_Bool user_alpha_set : 1;
153 Eina_Bool user_alpha : 1;
157 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
158 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
165 } indicator; //indicator object for internal client
169 Evas_Object *mask_obj;
172 int mask_x, mask_y, mask_w, mask_h;
175 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
177 tbm_surface_h tbm_surface;
178 E_Comp_Image_Filter image_filter;
179 Eina_Bool set_mouse_callbacks;
184 E_Comp_Wl_Buffer_Ref buffer_ref;
185 Eina_Bool pending_move_set;
186 int pending_move_x, pending_move_y;
187 Eina_Bool pending_resize_set;
188 int pending_resize_w, pending_resize_h;
189 } render_update_lock;
202 struct wl_signal lower;
203 //#ifdef REFACTOR_DESK_AREA
204 struct wl_signal raise;
206 struct wl_signal show;
207 struct wl_signal hide;
208 //#ifdef REFACTOR_DESK_AREA
209 struct wl_signal set_layer;
210 struct wl_signal stack_above;
211 struct wl_signal stack_below;
217 typedef struct _E_Input_Rect_Data
223 typedef struct _E_Input_Rect_Smart_Data
225 Eina_List *input_rect_data_list;
227 } E_Input_Rect_Smart_Data;
229 struct E_Comp_Object_Mover
232 E_Comp_Object_Mover_Cb func;
238 static Eina_Inlist *_e_comp_object_movers = NULL;
239 static Evas_Smart *_e_comp_smart = NULL;
240 static Evas_Smart *_e_comp_input_obj_smart = NULL;
242 static int _e_comp_object_hooks_delete = 0;
243 static int _e_comp_object_hooks_walking = 0;
245 static Eina_Inlist *_e_comp_object_hooks[] =
247 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
248 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
249 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
250 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
251 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
252 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
253 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
254 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
257 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
258 static int _e_comp_object_intercept_hooks_delete = 0;
259 static int _e_comp_object_intercept_hooks_walking = 0;
261 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
263 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
264 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
268 static Eina_Bool _damage_trace = EINA_FALSE;
269 static Eina_List *_damage_trace_objs = NULL;
270 static Eina_List *_damage_trace_post_objs = NULL;
272 /* sekrit functionzzz */
273 EINTERN void e_client_focused_set(E_Client *ec);
275 /* emitted every time a new noteworthy comp object is added */
276 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
278 /* ecore event define */
279 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
280 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
281 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
283 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
284 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
285 static void _e_comp_object_dim_update(E_Comp_Object *cw);
286 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
287 #ifdef REFACTOR_DESK_AREA
289 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
292 static E_Client *dim_client = NULL;
295 _e_comp_object_hooks_clean(void)
298 E_Comp_Object_Hook *ch;
301 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
302 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
304 if (!ch->delete_me) continue;
305 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
311 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
313 E_Comp_Object_Hook *ch;
314 Eina_Bool ret = EINA_TRUE;
316 if (e_object_is_del(E_OBJECT(ec)))
318 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
319 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
320 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
321 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
322 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
323 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
324 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
325 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
331 e_object_ref(E_OBJECT(ec));
332 _e_comp_object_hooks_walking++;
333 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
335 if (ch->delete_me) continue;
336 if (!(ch->func(ch->data, ec)))
342 _e_comp_object_hooks_walking--;
343 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
344 _e_comp_object_hooks_clean();
346 e_object_unref(E_OBJECT(ec));
351 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
353 _e_comp_object_intercept_hooks_clean(void)
356 E_Comp_Object_Intercept_Hook *ch;
359 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
360 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
362 if (!ch->delete_me) continue;
363 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
369 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
371 E_Comp_Object_Intercept_Hook *ch;
372 Eina_Bool ret = EINA_TRUE;
374 if (e_object_is_del(E_OBJECT(ec))) return ret;
375 e_object_ref(E_OBJECT(ec));
376 _e_comp_object_intercept_hooks_walking++;
377 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
379 if (ch->delete_me) continue;
380 if (!(ch->func(ch->data, ec)))
386 _e_comp_object_intercept_hooks_walking--;
387 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
388 _e_comp_object_intercept_hooks_clean();
390 e_object_unref(E_OBJECT(ec));
397 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
399 E_Event_Comp_Object *ev = event;
402 ec = evas_object_data_get(ev->comp_object, "E_Client");
406 e_object_unref(E_OBJECT(ec));
408 evas_object_unref(ev->comp_object);
413 _e_comp_object_event_add(Evas_Object *obj)
415 E_Event_Comp_Object *ev;
418 if (stopping) return;
419 ev = E_NEW(E_Event_Comp_Object, 1);
420 EINA_SAFETY_ON_NULL_RETURN(ev);
422 evas_object_ref(obj);
423 ev->comp_object = obj;
424 ec = evas_object_data_get(ev->comp_object, "E_Client");
428 e_object_ref(E_OBJECT(ec));
430 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
434 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
436 E_Event_Comp_Object *ev = event;
439 ec = evas_object_data_get(ev->comp_object, "E_Client");
443 e_object_unref(E_OBJECT(ec));
445 evas_object_unref(ev->comp_object);
450 _e_comp_object_event_simple(Evas_Object *obj, int type)
452 E_Event_Comp_Object *ev;
455 ev = E_NEW(E_Event_Comp_Object, 1);
458 evas_object_ref(obj);
459 ev->comp_object = obj;
460 ec = evas_object_data_get(ev->comp_object, "E_Client");
464 e_object_ref(E_OBJECT(ec));
466 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
468 /////////////////////////////////////
471 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
473 E_Comp_Object *cw = data;
475 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
479 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
481 E_Comp_Object *cw = data;
483 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
484 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
487 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
488 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
492 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
494 E_Comp_Object *cw = data;
497 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
498 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
501 /////////////////////////////////////
503 #ifdef REFACTOR_DESK_AREA
505 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
508 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
513 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
514 if (cw->ec->input_only) return;
516 layer = evas_object_layer_get(obj);
518 if (cw->transform_bg_obj)
520 if (layer != evas_object_layer_get(cw->transform_bg_obj))
522 evas_object_layer_set(cw->transform_bg_obj, layer);
525 evas_object_stack_below(cw->transform_bg_obj, obj);
528 if (cw->transform_tranp_obj)
530 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
532 evas_object_layer_set(cw->transform_tranp_obj, layer);
535 evas_object_stack_below(cw->transform_tranp_obj, obj);
540 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
547 if (!map) return NULL;
549 e_map_util_points_populate_from_object_full(map, obj, 0);
550 e_map_util_points_color_set(map, 255, 255, 255, 255);
552 for (i = 0 ; i < 4 ; ++i)
557 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
558 e_map_point_coord_set(map, i, x, y, 1.0);
565 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
571 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
574 e_comp_object_map_set(obj, map);
575 e_comp_object_map_enable_set(obj, EINA_TRUE);
582 evas_object_map_enable_set(obj, EINA_FALSE);
587 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
593 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
596 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
598 e_comp_object_map_set(obj, map);
599 e_comp_object_map_enable_set(obj, EINA_TRUE);
606 evas_object_map_enable_set(obj, EINA_FALSE);
609 /////////////////////////////////////
611 static inline Eina_Bool
612 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
614 if (num > 1) return EINA_TRUE;
615 if ((rects[0].x == 0) && (rects[0].y == 0) &&
616 ((int)rects[0].w == w) && ((int)rects[0].h == h))
621 /////////////////////////////////////
623 /* add a client to the layer-client list */
624 #ifdef REFACTOR_DESK_AREA
627 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
629 g_rec_mutex_lock(&e_comp->ec_list_mutex);
632 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));
634 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));
635 if ((!above) && (!below))
638 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
639 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
640 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
642 e_comp->layers[cw->layer].clients_count++;
644 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
648 _e_comp_object_layers_remove(E_Comp_Object *cw)
650 g_rec_mutex_lock(&e_comp->ec_list_mutex);
652 if (cw->ec && e_comp->layers[cw->layer].clients)
654 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
655 e_comp->layers[cw->layer].clients_count--;
658 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
662 /////////////////////////////////////
664 _e_comp_object_alpha_set(E_Comp_Object *cw)
666 Eina_Bool alpha = cw->ec->argb;
668 if ((cw->external_content) &&
669 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
674 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
675 if (cw->user_alpha_set) alpha = cw->user_alpha;
677 evas_object_image_alpha_set(cw->obj, alpha);
681 _e_comp_object_shadow(E_Comp_Object *cw)
683 if (e_client_util_shadow_state_get(cw->ec))
684 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
686 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
687 if (cw->frame_object)
688 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
689 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
692 /* convert from the surface coordinates to the buffer coordinates */
694 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
696 E_Comp_Wl_Buffer_Viewport *vp;
697 E_Comp_Wl_Client_Data *cdata;
701 cdata = e_client_cdata_get(ec);
703 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
710 vp = &cdata->scaler.buffer_viewport;
711 transform = e_comp_wl_output_buffer_transform_get(ec);
713 e_pixmap_size_get(ec->pixmap, &bw, &bh);
715 /* for subsurface, it should be swap 90 and 270 */
716 if (e_comp_wl_subsurface_check(ec))
719 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
720 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
722 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
728 case WL_OUTPUT_TRANSFORM_NORMAL:
729 default: tx = sx, ty = sy; break;
730 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
731 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
732 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
733 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
734 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
735 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
736 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
739 tx *= vp->buffer.scale;
740 ty *= vp->buffer.scale;
747 _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)
755 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
756 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
763 if (dw) *dw = MAX(x1, x2) - mx;
764 if (dh) *dh = MAX(y1, y2) - my;
768 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
769 int *dx, int *dy, int *dw, int *dh)
771 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
772 E_Util_Transform_Rect_Vertex sv, dv;
776 e_pixmap_size_get(ec->pixmap, &bw, &bh);
778 sv = e_util_transform_rect_to_vertices(&rect);
780 for (i = 0; i < 4; i++)
782 double x = 0.0, y = 0.0;
784 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
786 /* if evas decide coordinate is outside of map, it returns (0, 0)
787 in this case, full damage is added.
789 if ((i != 0) && (x == 0.0) && (y == 0.0))
792 dv.vertices[i].vertex[0] = x;
793 dv.vertices[i].vertex[1] = y;
794 dv.vertices[i].vertex[2] = 1.0;
795 dv.vertices[i].vertex[3] = 1.0;
798 rect = e_util_transform_vertices_to_rect(&dv);
800 if (dx) *dx = rect.x;
801 if (dy) *dy = rect.y;
802 if (dw) *dw = rect.w;
803 if (dh) *dh = rect.h;
817 _e_comp_object_map_damage_transform_get(E_Client *ec)
824 if (!e_client_transform_core_enable_get(ec))
827 m = e_client_map_get(ec);
831 e_pixmap_size_get(ec->pixmap, &bw, &bh);
832 if ((bw == 0) || (bh == 0))
845 e_map_point_coord_set(m2, 0, 0, 0, 0);
846 e_map_point_coord_set(m2, 1, bw, 0, 0);
847 e_map_point_coord_set(m2, 2, bw, bh, 0);
848 e_map_point_coord_set(m2, 3, 0, bh, 0);
850 for (i = 0; i < 4; i++)
854 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
855 e_map_point_image_uv_set(m2, i, map_x, map_y);
862 /////////////////////////////////////
864 /* handle evas mouse-in events on client object */
866 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
868 Evas_Event_Mouse_In *ev = event_info;
869 E_Comp_Object *cw = data;
871 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
874 /* handle evas mouse-out events on client object */
876 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
878 Evas_Event_Mouse_Out *ev = event_info;
879 E_Comp_Object *cw = data;
881 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
884 /* handle evas mouse wheel events on client object */
886 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
888 Evas_Event_Mouse_Wheel *ev = event_info;
889 E_Comp_Object *cw = data;
890 E_Binding_Event_Wheel ev2;
893 if (e_client_action_get()) return;
894 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
895 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
898 /* handle evas mouse down events on client object */
900 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
902 Evas_Event_Mouse_Down *ev = event_info;
903 E_Comp_Object *cw = data;
904 E_Binding_Event_Mouse_Button ev2;
907 if (e_client_action_get()) return;
908 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
909 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
912 /* handle evas mouse up events on client object */
914 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
916 Evas_Event_Mouse_Up *ev = event_info;
917 E_Comp_Object *cw = data;
918 E_Binding_Event_Mouse_Button ev2;
921 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
922 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
923 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
926 /* handle evas mouse movement events on client object */
928 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
930 Evas_Event_Mouse_Move *ev = event_info;
931 E_Comp_Object *cw = data;
934 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
935 e_client_mouse_move(cw->ec, &ev->cur.output);
937 /////////////////////////////////////
939 /* helper function for checking compositor themes based on user-defined matches */
941 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
943 if (((m->title) && (!ec->netwm.name)) ||
944 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
946 #if defined(__cplusplus) || defined(c_plusplus)
947 if (((m->clas) && (!ec->icccm.cpp_class)) ||
948 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
951 if (((m->clas) && (!ec->icccm.class)) ||
952 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
956 if (((m->role) && (!ec->icccm.window_role)) ||
957 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
963 if ((int)ec->netwm.type != m->primary_type)
966 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
969 if (m->borderless != 0)
973 if (e_client_util_borderless(ec))
975 if (!(((m->borderless == -1) && (!borderless)) ||
976 ((m->borderless == 1) && (borderless))))
983 if (((ec->icccm.transient_for != 0) ||
986 if (!(((m->dialog == -1) && (!dialog)) ||
987 ((m->dialog == 1) && (dialog))))
990 if (m->accepts_focus != 0)
992 int accepts_focus = 0;
994 if (ec->icccm.accepts_focus)
996 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
997 ((m->accepts_focus == 1) && (accepts_focus))))
1006 if (!(((m->vkbd == -1) && (!vkbd)) ||
1007 ((m->vkbd == 1) && (vkbd))))
1012 if (!(((m->argb == -1) && (!ec->argb)) ||
1013 ((m->argb == 1) && (ec->argb))))
1016 if (m->fullscreen != 0)
1018 int fullscreen = ec->fullscreen;
1020 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1021 ((m->fullscreen == 1) && (fullscreen))))
1026 if (!(m->modal == -1))
1032 /* function for setting up a client's compositor frame theme (cw->shobj) */
1034 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1038 Eina_List *list = NULL, *l;
1039 E_Input_Rect_Data *input_rect_data;
1040 E_Input_Rect_Smart_Data *input_rect_sd;
1042 Eina_Stringshare *reshadow_group = NULL;
1043 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1044 Eina_Stringshare *name, *title;
1045 E_Comp_Config *conf = e_comp_config_get();
1047 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1048 /* match correct client type */
1049 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1050 name = cw->ec->icccm.name;
1051 title = cw->ec->icccm.title;
1052 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1053 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1055 /* skipping here is mostly a hack for systray because I hate it */
1058 EINA_LIST_FOREACH(list, l, m)
1060 if (((m->name) && (!name)) ||
1061 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1063 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1066 no_shadow = m->no_shadow;
1067 if (m->shadow_style)
1069 /* fast effects are just themes with "/fast" appended and shorter effect times */
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1077 /* default to non-fast style if fast not available */
1080 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1081 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1085 if (ok && m->visibility_effect)
1086 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1093 if (skip || (cw->ec->e.state.video))
1095 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1097 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1100 if (conf->shadow_style)
1104 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1105 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1107 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1111 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1112 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1114 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1121 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1123 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1127 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1129 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1134 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1139 if (cw->ec->override)
1141 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1142 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1144 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1145 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1151 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1152 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1155 _e_comp_object_shadow(cw);
1158 if (focus || cw->ec->focused || cw->ec->override)
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1161 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1163 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1165 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1166 /* visibility must always be enabled for re_manage clients to prevent
1167 * pop-in animations every time the user sees a persistent client again;
1168 * applying visibility for iconic clients prevents the client from getting
1171 if (cw->visible || cw->ec->re_manage)
1172 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1174 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1176 /* breaks animation counter */
1177 if (cw->frame_object)
1179 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1181 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1182 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1188 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1192 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1195 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1197 if (input_rect_data->obj)
1199 pass_event_flag = EINA_TRUE;
1205 if (cw->indicator.obj)
1207 Evas_Object *indicator;
1208 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1209 if (indicator != cw->indicator.obj)
1211 edje_object_part_unswallow(cw->shobj, indicator);
1212 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1213 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1217 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1218 evas_object_pass_events_set(cw->obj, pass_event_flag);
1223 /////////////////////////////////////////////
1226 _e_comp_object_animating_begin(E_Comp_Object *cw)
1229 if (cw->animating == 1)
1231 e_comp->animating++;
1233 e_object_ref(E_OBJECT(cw->ec));
1238 _e_comp_object_animating_end(E_Comp_Object *cw)
1247 if (cw->ec->launching)
1249 if (!cw->ec->extra_animating)
1251 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1252 cw->ec->launching = EINA_FALSE;
1253 if (cw->ec->first_mapped)
1255 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1256 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1259 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1263 e_comp->animating--;
1264 cw->showing = cw->hiding = 0;
1266 if (e_comp->animating == 0)
1267 e_comp_visibility_calculation_set(EINA_TRUE);
1268 /* remove ref from animation start, account for possibility of deletion from unref */
1269 return !!e_object_unref(E_OBJECT(cw->ec));
1275 /* handle the end of a compositor animation */
1277 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1279 E_Comp_Object *cw = data;
1281 /* visible clients which have never been sized are a bug */
1282 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1283 CRI("ACK! ec:%p", cw->ec);
1284 if (!_e_comp_object_animating_end(cw)) return;
1285 if (cw->animating) return;
1286 /* hide only after animation finishes to guarantee a full run of the animation */
1287 if (!cw->defer_hide) return;
1288 if ((!strcmp(emission, "e,action,hide,done")) ||
1289 (!strcmp(emission, "e,action,done")) ||
1290 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1292 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1293 evas_object_hide(cw->smart_obj);
1297 /* run a visibility compositor effect if available, return false if object is dead */
1299 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1305 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1306 if (!cw->effect_running)
1307 _e_comp_object_animating_begin(cw);
1308 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1309 return _e_comp_object_animating_end(cw);
1310 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1311 return _e_comp_object_animating_end(cw);
1313 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1316 zone = e_comp_zone_find_by_ec(cw->ec);
1318 zw = zone->w, zh = zone->h;
1323 zone = e_comp_object_util_zone_get(cw->smart_obj);
1324 if (!zone) zone = e_zone_current_get();
1331 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1332 cw->w, cw->h, zw, zh, x, y}, 8);
1333 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1334 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1337 /////////////////////////////////////////////
1339 /* create necessary objects for clients that e manages */
1341 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1343 if (cw->set_mouse_callbacks) return;
1344 if (!cw->smart_obj) return;
1346 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1348 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1350 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1351 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1353 cw->set_mouse_callbacks = EINA_TRUE;
1357 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1359 if (!cw->set_mouse_callbacks) return;
1360 if (!cw->smart_obj) return;
1362 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1364 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1366 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1367 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1369 cw->set_mouse_callbacks = EINA_FALSE;
1373 _e_comp_object_setup(E_Comp_Object *cw)
1375 cw->clip = evas_object_rectangle_add(e_comp->evas);
1376 evas_object_move(cw->clip, -9999, -9999);
1377 evas_object_resize(cw->clip, 999999, 999999);
1378 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1379 cw->effect_obj = edje_object_add(e_comp->evas);
1380 evas_object_move(cw->effect_obj, cw->x, cw->y);
1381 evas_object_clip_set(cw->effect_obj, cw->clip);
1382 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1383 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1384 cw->shobj = edje_object_add(e_comp->evas);
1385 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1386 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1387 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1389 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1390 if (cw->ec->override)
1392 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1393 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1394 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1396 else if (!cw->ec->input_only)
1398 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1399 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1400 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1402 cw->real_hid = !cw->ec->input_only;
1403 if (!cw->ec->input_only)
1405 e_util_size_debug_set(cw->effect_obj, 1);
1406 _e_comp_object_mouse_event_callback_set(cw);
1409 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1410 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1411 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1412 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1413 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1414 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1416 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1419 /////////////////////////////////////////////
1421 /* for fast path evas rendering; only called during render */
1423 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1425 E_Comp_Object *cw = data;
1426 E_Client *ec = cw->ec;
1428 int bx, by, bxx, byy;
1430 if (e_object_is_del(E_OBJECT(ec))) return;
1431 if (cw->external_content) return;
1432 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1433 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1436 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1437 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1439 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1441 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1442 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1446 bx = by = bxx = byy = 0;
1447 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1450 Edje_Message_Int_Set *msg;
1451 Edje_Message_Int msg2;
1452 Eina_Bool id = (bx || by || bxx || byy);
1454 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1460 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1462 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1466 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1467 e_comp_client_post_update_add(cw->ec);
1469 else if (e_comp_object_render(ec->frame))
1471 /* apply shape mask if necessary */
1472 if ((!cw->native) && (ec->shaped))
1473 e_comp_object_shape_apply(ec->frame);
1475 /* shaped clients get precise mouse events to handle transparent pixels */
1476 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1478 /* queue another render if client is still dirty; cannot refresh here. */
1479 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1480 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1482 if (cw->render_trace)
1484 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1490 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1492 E_Comp_Object *cw = data;
1493 E_Client *ec = cw->ec;
1495 if (e_object_is_del(E_OBJECT(ec))) return;
1496 if (cw->external_content) return;
1497 if (!e_comp->hwc) return;
1499 e_comp_client_render_list_add(cw->ec);
1501 if (!ec->hwc_window) return;
1503 e_hwc_windows_rendered_window_add(ec->hwc_window);
1506 /////////////////////////////////////////////
1509 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1511 E_Comp_Object *cw = data;
1514 if (cw->render_update_lock.lock)
1516 cw->render_update_lock.pending_move_x = x;
1517 cw->render_update_lock.pending_move_y = y;
1518 cw->render_update_lock.pending_move_set = EINA_TRUE;
1522 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1523 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1524 (cw->external_content))
1526 /* delay to move until the external content is unset */
1527 cw->ec->changes.pos = 1;
1532 if (cw->ec->move_after_resize)
1534 if ((x != cw->ec->x) || (y != cw->ec->y))
1536 if (!cw->ec->is_cursor)
1537 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1538 e_client_pos_set(cw->ec, x, y);
1539 cw->ec->changes.pos = 1;
1545 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1546 (cw->ec->manage_resize.resize_obj))
1548 e_client_pos_set(cw->ec, x, y);
1549 cw->ec->client.x = x + cw->client_inset.l;
1550 cw->ec->client.y = y + cw->client_inset.t;
1551 e_policy_visibility_client_defer_move(cw->ec);
1555 /* if frame_object does not exist, client_inset indicates CSD.
1556 * this means that ec->client matches cw->x/y, the opposite
1559 fx = (!cw->frame_object) * cw->client_inset.l;
1560 fy = (!cw->frame_object) * cw->client_inset.t;
1561 if ((cw->x == x + fx) && (cw->y == y + fy))
1563 if ((cw->ec->x != x) || (cw->ec->y != y))
1565 /* handle case where client tries to move to position and back very quickly */
1566 e_client_pos_set(cw->ec, x, y);
1567 cw->ec->client.x = x + cw->client_inset.l;
1568 cw->ec->client.y = y + cw->client_inset.t;
1572 if (!cw->ec->maximize_override)
1574 /* prevent moving in some directions while directionally maximized */
1575 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1577 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1580 ix = x + cw->client_inset.l;
1581 iy = y + cw->client_inset.t;
1582 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1583 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1584 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1586 /* prevent moving at all if move isn't allowed in current maximize state */
1587 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1588 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1591 zone = e_comp_zone_find_by_ec(cw->ec);
1594 cw->ec->changes.need_unmaximize = 1;
1595 cw->ec->saved.x = ix - zone->x;
1596 cw->ec->saved.y = iy - zone->y;
1597 cw->ec->saved.w = cw->ec->client.w;
1598 cw->ec->saved.h = cw->ec->client.h;
1602 /* only update during resize if triggered by resize */
1603 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1604 /* delay to move while surface waits paired commit serial*/
1605 if (e_client_pending_geometry_has(cw->ec))
1607 /* do nothing while waiting paired commit serial*/
1611 e_client_pos_set(cw->ec, x, y);
1612 if (cw->ec->new_client)
1614 /* don't actually do anything until first client idler loop */
1615 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1616 cw->ec->changes.pos = 1;
1621 /* only update xy position of client to avoid invalid
1622 * first damage region if it is not a new_client. */
1623 cw->ec->client.x = ix;
1624 cw->ec->client.y = iy;
1627 if (!cw->frame_object)
1629 evas_object_move(obj, x, y);
1634 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1636 E_Comp_Object *cw = data;
1637 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1640 if (cw->render_update_lock.lock)
1642 cw->render_update_lock.pending_resize_w = w;
1643 cw->render_update_lock.pending_resize_h = h;
1644 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1648 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1650 e_client_size_set(cw->ec, w, h);
1651 evas_object_resize(obj, w, h);
1655 /* if frame_object does not exist, client_inset indicates CSD.
1656 * this means that ec->client matches cw->w/h, the opposite
1659 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1660 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1661 if ((cw->w == w + fw) && (cw->h == h + fh))
1663 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1664 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1665 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1667 /* handle case where client tries to resize itself and back very quickly */
1668 e_client_size_set(cw->ec, w, h);
1669 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1670 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1671 evas_object_smart_callback_call(obj, "client_resize", NULL);
1675 /* guarantee that fullscreen is fullscreen */
1676 zone = e_comp_zone_find_by_ec(cw->ec);
1678 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1680 if (!e_client_transform_core_enable_get(cw->ec))
1683 /* calculate client size */
1684 iw = w - cw->client_inset.l - cw->client_inset.r;
1685 ih = h - cw->client_inset.t - cw->client_inset.b;
1686 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1688 /* prevent resizing while maximized depending on direction and config */
1689 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1691 Eina_Bool reject = EINA_FALSE;
1692 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1694 if (cw->ec->client.h != ih)
1696 cw->ec->saved.h = ih;
1697 cw->ec->saved.y = cw->ec->client.y - zone->y;
1698 reject = cw->ec->changes.need_unmaximize = 1;
1701 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1703 if (cw->ec->client.w != iw)
1705 cw->ec->saved.w = iw;
1706 cw->ec->saved.x = cw->ec->client.x - zone->x;
1707 reject = cw->ec->changes.need_unmaximize = 1;
1716 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1718 /* do nothing until client idler loops */
1719 if ((cw->ec->w != w) || (cw->ec->h != h))
1721 e_client_size_set(cw->ec, w, h);
1722 cw->ec->changes.size = 1;
1727 if (e_client_pending_geometry_has(cw->ec))
1729 /* do nothing while waiting paired commit serial*/
1733 e_client_size_set(cw->ec, w, h);
1735 cw->ec->client.w = iw;
1736 cw->ec->client.h = ih;
1737 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1739 /* The size of non-compositing window can be changed, so there is a
1740 * need to check that cw is H/W composited if cw is not redirected.
1741 * And of course we have to change size of evas object of H/W composited cw,
1742 * otherwise cw can't receive input events even if it is shown on the screen.
1744 Eina_Bool redirected = cw->redirected;
1746 redirected = e_comp_is_on_overlay(cw->ec);
1748 if ((!cw->ec->input_only) && (redirected) &&
1749 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1750 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1751 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1752 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1755 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1756 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1758 prev_w = cw->w, prev_h = cw->h;
1759 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1760 /* check shading and clamp to pixmap size for regular clients */
1761 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1762 (((w - fw != pw) || (h - fh != ph))))
1764 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1765 evas_object_smart_callback_call(obj, "client_resize", NULL);
1767 if (cw->frame_object || cw->ec->input_only)
1768 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1771 if ((cw->w == w) && (cw->h == h))
1773 /* going to be a noop resize which won't trigger smart resize */
1774 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1775 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1777 evas_object_resize(obj, w, h);
1781 evas_object_smart_callback_call(obj, "client_resize", NULL);
1784 if ((!cw->frame_object) && (!cw->ec->input_only))
1786 /* "just do it" for overrides */
1787 evas_object_resize(obj, w, h);
1789 if (!cw->ec->override)
1791 /* shape probably changed for non-overrides */
1796 /* this fixes positioning jiggles when using a resize mode
1797 * which also changes the client's position
1800 if (cw->frame_object)
1801 x = cw->x, y = cw->y;
1803 x = cw->ec->x, y = cw->ec->y;
1804 switch (cw->ec->resize_mode)
1806 case E_POINTER_RESIZE_BL:
1807 case E_POINTER_RESIZE_L:
1808 evas_object_move(obj, x + prev_w - cw->w, y);
1810 case E_POINTER_RESIZE_TL:
1811 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1813 case E_POINTER_RESIZE_T:
1814 case E_POINTER_RESIZE_TR:
1815 evas_object_move(obj, x, y + prev_h - cw->h);
1824 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1826 #ifdef REFACTOR_DESK_AREA
1827 E_Comp_Object *cw = data;
1828 E_Comp_Object_Data_Set_Layer layer_set_data;
1830 layer_set_data.cw = cw;
1831 layer_set_data.layer = layer;
1833 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1837 e_comp_render_queue();
1838 _e_comp_object_transform_obj_stack_update(obj);
1842 E_Comp_Object *cw = data;
1843 E_Comp_Wl_Client_Data *child_cdata;
1844 unsigned int l = e_comp_canvas_layer_map(layer);
1847 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1849 /* doing a compositor effect, follow directions */
1850 _e_comp_object_layer_set(obj, layer);
1851 if (layer == cw->ec->layer) //trying to put layer back
1855 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1856 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1857 if (cw->layer != l) goto layer_set;
1861 e_comp_render_queue();
1863 ec = e_client_above_get(cw->ec);
1864 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1865 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1866 ec = e_client_above_get(ec);
1867 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1869 ec = e_client_below_get(cw->ec);
1870 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1871 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1872 ec = e_client_below_get(ec);
1873 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1875 evas_object_stack_above(obj, ec->frame);
1880 if (ec && (cw->ec->parent == ec))
1882 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1883 evas_object_stack_above(obj, ec->frame);
1885 evas_object_stack_below(obj, ec->frame);
1888 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1894 if (cw->layer == l) return;
1895 if (e_comp_canvas_client_layer_map(layer) == 9999)
1896 return; //invalid layer for clients not doing comp effects
1897 if (cw->ec->fullscreen)
1899 cw->ec->saved.layer = layer;
1902 oldraise = e_config->transient.raise;
1904 /* clamp to valid client layer */
1905 layer = e_comp_canvas_client_layer_map_nearest(layer);
1906 cw->ec->layer = layer;
1907 if (e_config->transient.layer)
1910 Eina_List *list = eina_list_clone(cw->ec->transients);
1912 /* We need to set raise to one, else the child wont
1913 * follow to the new layer. It should be like this,
1914 * even if the user usually doesn't want to raise
1917 e_config->transient.raise = 1;
1918 EINA_LIST_FREE(list, child)
1920 child_cdata = e_client_cdata_get(child);
1921 if (child_cdata && !child_cdata->mapped)
1923 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1926 e_client_layer_set(child, layer);
1930 e_config->transient.raise = oldraise;
1932 _e_comp_object_layers_remove(cw);
1933 cw->layer = e_comp_canvas_layer_map(layer);
1934 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1935 //if (cw->ec->new_client)
1936 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1937 _e_comp_object_layer_set(obj, layer);
1938 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1939 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1940 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1942 /* can't stack a client above its own layer marker */
1943 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1945 if (!cw->visible) return;
1946 e_comp_render_queue();
1947 _e_comp_object_transform_obj_stack_update(obj);
1951 #ifdef REFACTOR_DESK_AREA
1953 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1956 #ifdef REFACTOR_DESK_AREA
1958 _e_comp_object_raise(Evas_Object *obj)
1961 _e_comp_object_raise(Evas_Object *obj)
1964 evas_object_raise(obj);
1966 if (evas_object_smart_smart_get(obj))
1968 E_Client *ec = e_comp_object_client_get(obj);
1970 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1974 #ifdef REFACTOR_DESK_AREA
1976 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1979 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1982 evas_object_lower(obj);
1984 if (evas_object_smart_smart_get(obj))
1986 E_Client *ec = e_comp_object_client_get(obj);
1989 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1990 #ifdef REFACTOR_DESK_AREA
1991 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1993 wl_signal_emit_mutable(&cw->events.lower, NULL);
1999 #ifdef REFACTOR_DESK_AREA
2001 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2004 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2007 evas_object_stack_above(obj, target);
2009 if (evas_object_smart_smart_get(obj))
2011 E_Client *ec = e_comp_object_client_get(obj);
2013 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2017 #ifdef REFACTOR_DESK_AREA
2019 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2022 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2025 evas_object_stack_below(obj, target);
2027 if (evas_object_smart_smart_get(obj))
2029 E_Client *ec = e_comp_object_client_get(obj);
2031 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2035 #ifdef REFACTOR_DESK_AREA
2037 e_comp_object_layer_set(Evas_Object *obj, short layer)
2040 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2043 evas_object_layer_set(obj, layer);
2045 if (evas_object_smart_smart_get(obj))
2047 E_Client *ec = e_comp_object_client_get(obj);
2049 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2053 #ifdef REFACTOR_DESK_AREA
2056 _e_comp_object_is_pending(E_Client *ec)
2060 if (!ec) return EINA_FALSE;
2062 topmost = e_comp_wl_topmost_parent_get(ec);
2064 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2068 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2070 E_Comp_Object *cw2 = NULL;
2073 Evas_Object *o = stack;
2074 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2076 /* We should consider topmost's layer_pending for subsurface */
2077 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2079 if (_e_comp_object_is_pending(cw->ec))
2080 e_comp_object_layer_update(cw->smart_obj,
2081 raising? stack : NULL,
2082 raising? NULL : stack);
2084 /* obey compositor effects! */
2085 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2086 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2087 stack_cb(cw->smart_obj, stack);
2088 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2089 evas_object_data_del(cw->smart_obj, "client_restack");
2093 cw2 = evas_object_data_get(o, "comp_obj");
2095 /* assume someone knew what they were doing during client init */
2096 if (cw->ec->new_client)
2097 layer = cw->ec->layer;
2098 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2099 layer = cw2->ec->layer;
2101 layer = evas_object_layer_get(stack);
2102 ecstack = e_client_below_get(cw->ec);
2103 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2105 evas_object_layer_set(cw->smart_obj, layer);
2106 /* we got our layer wrangled, return now! */
2107 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2110 /* check if we're stacking below another client */
2113 /* check for non-client layer object */
2114 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2116 /* find an existing client to use for layering
2117 * by walking up the object stack
2119 * this is guaranteed to be pretty quick since we'll either:
2120 * - run out of client layers
2121 * - find a stacking client
2123 o = evas_object_above_get(o);
2124 if ((!o) || (o == cw->smart_obj)) break;
2125 if (evas_object_layer_get(o) != layer)
2127 /* reached the top client layer somehow
2128 * use top client object
2130 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2133 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2134 * return here since the top client layer window
2139 ec = e_client_top_get();
2144 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2147 if (cw2 && cw->layer != cw2->layer)
2150 /* remove existing layers */
2151 _e_comp_object_layers_remove(cw);
2154 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2155 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2156 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2157 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2158 else //if no stacking objects found, either raise or lower
2159 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2162 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2164 /* find new object for stacking if cw2 is on state of layer_pending */
2165 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2167 E_Client *new_stack = NULL, *current_ec = NULL;
2168 current_ec = cw2->ec;
2171 while ((new_stack = e_client_below_get(current_ec)))
2173 current_ec = new_stack;
2174 if (new_stack == cw->ec) continue;
2175 if (new_stack->layer != cw2->ec->layer) break;
2176 if (!_e_comp_object_is_pending(new_stack)) break;
2178 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2179 stack = new_stack->frame;
2182 /* stack it above layer object */
2184 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2185 stack = e_comp->layers[below_layer].obj;
2190 while ((new_stack = e_client_above_get(current_ec)))
2192 current_ec = new_stack;
2193 if (new_stack == cw->ec) continue;
2194 if (new_stack->layer != cw2->ec->layer) break;
2195 if (!_e_comp_object_is_pending(new_stack)) break;
2197 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2198 stack = new_stack->frame;
2200 stack = e_comp->layers[cw2->layer].obj;
2204 /* set restack if stacking has changed */
2205 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2206 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2207 stack_cb(cw->smart_obj, stack);
2208 if (e_comp->layers[cw->layer].obj)
2209 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2211 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2213 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2214 evas_object_data_del(cw->smart_obj, "client_restack");
2215 if (!cw->visible) return;
2216 e_comp_render_queue();
2221 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2223 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2225 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2227 #ifdef REFACTOR_DESK_AREA
2228 E_Comp_Object *cw = data;
2229 E_Comp_Object_Data_Stack_Above stack_above_data;
2231 stack_above_data.cw = cw;
2232 stack_above_data.above_obj = above;
2234 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2236 if (evas_object_below_get(obj) == above)
2238 e_comp_object_layer_update(obj, above, NULL);
2242 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2244 _e_comp_object_transform_obj_stack_update(obj);
2245 _e_comp_object_transform_obj_stack_update(above);
2252 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2254 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2256 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2258 #ifdef REFACTOR_DESK_AREA
2259 E_Comp_Object *cw = data;
2260 E_Comp_Object_Data_Stack_Below stack_below_data;
2262 stack_below_data.cw = cw;
2263 stack_below_data.below_obj = below;
2265 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2268 e_comp_render_queue();
2270 if (evas_object_above_get(obj) == below)
2272 e_comp_object_layer_update(obj, NULL, below);
2276 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2278 if (evas_object_smart_smart_get(obj))
2279 _e_comp_object_transform_obj_stack_update(obj);
2280 if (evas_object_smart_smart_get(below))
2281 _e_comp_object_transform_obj_stack_update(below);
2288 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2290 E_Comp_Object *cw = data;
2292 #ifdef REFACTOR_DESK_AREA
2297 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2299 #ifdef REFACTOR_DESK_AREA
2300 wl_signal_emit_mutable(&cw->events.lower, cw);
2302 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2304 if (cw->ec->layer_pending)
2305 e_comp_object_layer_update(obj, NULL, obj);
2307 _e_comp_object_lower(cw, obj);
2310 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2311 o = evas_object_below_get(obj);
2312 _e_comp_object_layers_remove(cw);
2313 /* prepend to client list since this client should be the first item now */
2314 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2315 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2316 evas_object_data_set(obj, "client_restack", (void*)1);
2317 _e_comp_object_lower(cw, obj);
2318 evas_object_data_del(obj, "client_restack");
2319 if (!cw->visible) goto end;
2320 e_comp_render_queue();
2321 _e_comp_object_transform_obj_stack_update(obj);
2329 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2331 E_Comp_Object *cw = data;
2332 #ifdef REFACTOR_DESK_AREA
2338 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2340 #ifdef REFACTOR_DESK_AREA
2341 wl_signal_emit_mutable(&cw->events.raise, cw);
2343 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2345 if (cw->ec->layer_pending)
2347 int obj_layer = evas_object_layer_get(obj);
2348 if (cw->ec->layer != obj_layer)
2349 e_comp_object_layer_update(obj, NULL, NULL);
2352 _e_comp_object_raise(obj);
2355 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2356 o = evas_object_above_get(obj);
2357 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2359 /* still stack below override below the layer marker */
2360 for (op = o = e_comp->layers[cw->layer].obj;
2361 o && o != e_comp->layers[cw->layer - 1].obj;
2362 op = o, o = evas_object_below_get(o))
2364 if (evas_object_smart_smart_get(o))
2368 ec = e_comp_object_client_get(o);
2369 if (ec && (!ec->override)) break;
2372 _e_comp_object_stack_below(obj, op);
2373 e_client_focus_defer_set(cw->ec);
2375 if (!cw->visible) goto end;
2376 e_comp_render_queue();
2377 _e_comp_object_transform_obj_stack_update(obj);
2385 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2387 E_Comp_Object *cw = data;
2389 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2390 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2392 ELOGF("COMP", "Hide. intercepted", cw->ec);
2397 if (cw->ec->launching == EINA_TRUE)
2399 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2400 cw->ec->launching = EINA_FALSE;
2405 /* hidden flag = just do it */
2406 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2407 evas_object_hide(obj);
2409 wl_signal_emit_mutable(&cw->events.hide, NULL);
2414 if (cw->ec->input_only)
2416 /* input_only = who cares */
2417 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2418 evas_object_hide(obj);
2420 wl_signal_emit_mutable(&cw->events.hide, NULL);
2424 /* already hidden or currently animating */
2425 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2427 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2431 /* don't try hiding during shutdown */
2432 cw->defer_hide |= stopping;
2433 if (!cw->defer_hide)
2435 if ((!cw->ec->iconic) && (!cw->ec->override))
2436 /* unset delete requested so the client doesn't break */
2437 cw->ec->delete_requested = 0;
2438 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2440 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2441 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2444 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2447 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2449 _e_comp_object_animating_begin(cw);
2450 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2452 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2453 cw->defer_hide = !!cw->animating;
2455 e_comp_object_effect_set(obj, NULL);
2458 if (cw->animating) return;
2459 /* if we have no animations running, go ahead and hide */
2461 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2462 evas_object_hide(obj);
2464 wl_signal_emit_mutable(&cw->events.hide, NULL);
2468 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2470 E_Client *ec = cw->ec;
2473 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2475 if (ec->show_pending.count > 0)
2477 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2478 ec->show_pending.running = EINA_TRUE;
2482 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2483 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2485 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2490 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,
2491 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2492 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2495 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2498 if (ec->iconic && cw->animating)
2500 /* triggered during iconify animation */
2501 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2504 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2507 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2508 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2510 evas_object_move(cw->smart_obj, ec->x, ec->y);
2511 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2512 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2514 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2515 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2518 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2519 evas_object_show(cw->smart_obj);
2522 e_client_focus_defer_set(ec);
2526 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2530 pw = ec->client.w, ph = ec->client.h;
2532 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2534 ec->changes.visible = !ec->hidden;
2537 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2541 cw->updates = eina_tiler_new(pw, ph);
2544 ec->changes.visible = !ec->hidden;
2547 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2552 eina_tiler_tile_size_set(cw->updates, 1, 1);
2555 /* ignore until client idler first run */
2556 ec->changes.visible = !ec->hidden;
2559 ELOGF("COMP", "show_helper. return. new_client", ec);
2566 evas_object_move(cw->smart_obj, ec->x, ec->y);
2567 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2568 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2569 evas_object_show(cw->smart_obj);
2572 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2574 /* start_drag not received */
2575 ec->changes.visible = 1;
2578 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2581 /* re-set geometry */
2582 evas_object_move(cw->smart_obj, ec->x, ec->y);
2583 /* force resize in case it hasn't happened yet, or just to update size */
2584 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2585 if ((cw->w < 1) || (cw->h < 1))
2587 /* if resize didn't go through, try again */
2588 ec->visible = ec->changes.visible = 1;
2590 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2593 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2594 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2595 e_pixmap_clear(ec->pixmap);
2597 if (cw->real_hid && w && h)
2600 /* force comp theming in case it didn't happen already */
2601 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2602 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2603 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2606 /* only do the show if show is allowed */
2609 if (ec->internal) //internal clients render when they feel like it
2610 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2612 if (!e_client_is_iconified_by_client(ec)||
2613 e_policy_visibility_client_is_uniconic(ec))
2615 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2616 evas_object_show(cw->smart_obj);
2618 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2619 it is rendered in idle callback without native surface and
2620 compositor shows an empty frame if other objects aren't shown
2621 because job callback of e_comp called at the next loop.
2622 it causes a visual defect when windows are switched.
2626 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2627 e_comp_object_dirty(cw->smart_obj);
2628 e_comp_object_render(cw->smart_obj);
2633 wl_signal_emit_mutable(&cw->events.show, NULL);
2637 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2639 E_Comp_Object *cw = data;
2640 E_Client *ec = cw->ec;
2642 E_Input_Rect_Data *input_rect_data;
2643 E_Input_Rect_Smart_Data *input_rect_sd;
2646 if (ec->ignored) return;
2650 //INF("SHOW2 %p", ec);
2651 _e_comp_intercept_show_helper(cw);
2654 //INF("SHOW %p", ec);
2657 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2658 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2659 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2660 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2664 if ((!cw->obj) && (cw->external_content))
2666 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2670 _e_comp_object_setup(cw);
2673 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2674 cw->obj = evas_object_image_filled_add(e_comp->evas);
2675 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2676 e_util_size_debug_set(cw->obj, 1);
2677 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2678 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2679 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2680 evas_object_name_set(cw->obj, "cw->obj");
2681 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2683 _e_comp_object_alpha_set(cw);
2686 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2689 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2690 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2693 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2696 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2698 if (input_rect_data->obj)
2700 evas_object_geometry_set(input_rect_data->obj,
2701 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2702 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2703 input_rect_data->rect.w, input_rect_data->rect.h);
2710 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2712 _e_comp_intercept_show_helper(cw);
2716 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2718 E_Comp_Object *cw = data;
2722 /* note: this is here as it seems there are enough apps that do not even
2723 * expect us to emulate a look of focus but not actually set x input
2724 * focus as we do - so simply abort any focus set on such windows */
2725 /* be strict about accepting focus hint */
2726 /* be strict about accepting focus hint */
2727 if ((!ec->icccm.accepts_focus) &&
2728 (!ec->icccm.take_focus))
2732 if (e_client_focused_get() == ec)
2733 e_client_focused_set(NULL);
2735 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2736 evas_object_focus_set(obj, focus);
2740 if (focus && ec->lock_focus_out) return;
2741 if (e_object_is_del(E_OBJECT(ec)) && focus)
2742 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2744 /* filter focus setting based on current state */
2749 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2750 evas_object_focus_set(obj, focus);
2753 if ((ec->iconic) && (!ec->deskshow))
2755 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2757 /* don't focus an iconified window. that's silly! */
2758 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2759 e_client_uniconify(ec);
2760 e_client_focus_latest_set(ec);
2774 /* not yet visible, wait till the next time... */
2775 ec->want_focus = !ec->hidden;
2780 e_client_focused_set(ec);
2784 if (e_client_focused_get() == ec)
2785 e_client_focused_set(NULL);
2789 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2791 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2793 evas_object_focus_set(obj, focus);
2797 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2799 E_Comp_Object *cw = data;
2801 if (cw->transparent.set)
2803 cw->transparent.user_r = r;
2804 cw->transparent.user_g = g;
2805 cw->transparent.user_b = b;
2806 cw->transparent.user_a = a;
2808 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2810 cw->transparent.user_r,
2811 cw->transparent.user_g,
2812 cw->transparent.user_b,
2813 cw->transparent.user_a);
2817 evas_object_color_set(obj, r, g, b, a);
2820 ////////////////////////////////////////////////////
2823 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2825 int w, h, ox, oy, ow, oh;
2827 Eina_Bool pass_event_flag = EINA_FALSE;
2828 E_Input_Rect_Data *input_rect_data;
2829 E_Input_Rect_Smart_Data *input_rect_sd;
2831 if (cw->frame_object)
2833 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2834 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2835 /* set a fixed size, force edje calc, check size difference */
2836 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2837 edje_object_message_signal_process(cw->frame_object);
2838 edje_object_calc_force(cw->frame_object);
2839 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2840 cw->client_inset.l = ox;
2841 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2842 cw->client_inset.t = oy;
2843 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2844 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2845 evas_object_resize(cw->frame_object, w, h);
2849 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2852 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2854 if (input_rect_data->obj)
2856 pass_event_flag = EINA_TRUE;
2862 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2863 evas_object_pass_events_set(cw->obj, pass_event_flag);
2867 cw->client_inset.l = 0;
2868 cw->client_inset.r = 0;
2869 cw->client_inset.t = 0;
2870 cw->client_inset.b = 0;
2872 cw->client_inset.calc = !!cw->frame_object;
2876 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2878 E_Comp_Object *cw = data;
2882 /* - get current size
2884 * - readjust for new frame size
2887 w = cw->ec->w, h = cw->ec->h;
2888 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2890 _e_comp_object_frame_recalc(cw);
2892 if (!cw->ec->fullscreen)
2893 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2895 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2896 if (cw->ec->fullscreen)
2898 zone = e_comp_zone_find_by_ec(cw->ec);
2900 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2902 else if (cw->ec->new_client)
2904 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2905 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2906 evas_object_resize(cw->ec->frame, w, h);
2908 else if ((w != cw->ec->w) || (h != cw->ec->h))
2909 evas_object_resize(cw->ec->frame, w, h);
2913 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2915 E_Comp_Object *cw = data;
2917 _e_comp_object_shadow_setup(cw);
2918 if (cw->frame_object)
2920 _e_comp_object_shadow(cw);
2921 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2922 _e_comp_object_frame_recalc(cw);
2923 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2928 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2930 E_Comp_Object *cw = data;
2932 if (_e_comp_object_shadow_setup(cw))
2933 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2934 if (cw->frame_object)
2936 _e_comp_object_shadow(cw);
2937 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2938 _e_comp_object_frame_recalc(cw);
2939 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2944 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2946 E_Comp_Object *cw = data;
2948 if (cw->frame_object)
2950 _e_comp_object_shadow(cw);
2951 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2952 _e_comp_object_frame_recalc(cw);
2953 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2958 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2960 E_Comp_Object *cw = data;
2962 if (_e_comp_object_shadow_setup(cw))
2965 cw->ec->changes.size = 1;
2967 if (cw->frame_object)
2969 _e_comp_object_shadow(cw);
2970 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2971 _e_comp_object_frame_recalc(cw);
2972 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2977 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2979 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2983 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2985 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2989 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2991 E_Comp_Object *cw = data;
2993 if (!cw->ec) return; //NYI
2994 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2998 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3000 E_Comp_Object *cw = data;
3002 if (!cw->ec) return; //NYI
3003 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3007 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3009 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3013 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3015 E_Comp_Object *cw = data;
3017 if (!e_object_is_del(E_OBJECT(cw->ec)))
3018 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3022 _e_comp_input_obj_smart_add(Evas_Object *obj)
3024 E_Input_Rect_Smart_Data *input_rect_sd;
3025 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3027 if (!input_rect_sd) return;
3028 evas_object_smart_data_set(obj, input_rect_sd);
3032 _e_comp_input_obj_smart_del(Evas_Object *obj)
3034 E_Input_Rect_Smart_Data *input_rect_sd;
3035 E_Input_Rect_Data *input_rect_data;
3037 input_rect_sd = evas_object_smart_data_get(obj);
3038 if (!input_rect_sd) return;
3040 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3042 if (input_rect_data->obj)
3044 evas_object_smart_member_del(input_rect_data->obj);
3045 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3047 E_FREE(input_rect_data);
3049 E_FREE(input_rect_sd);
3053 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3055 E_Input_Rect_Smart_Data *input_rect_sd;
3056 E_Input_Rect_Data *input_rect_data;
3060 input_rect_sd = evas_object_smart_data_get(obj);
3061 if (!input_rect_sd) return;
3063 cw = input_rect_sd->cw;
3064 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3066 if (input_rect_data->obj)
3068 evas_object_geometry_set(input_rect_data->obj,
3069 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3070 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3071 input_rect_data->rect.w, input_rect_data->rect.h);
3077 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3079 E_Input_Rect_Smart_Data *input_rect_sd;
3080 E_Input_Rect_Data *input_rect_data;
3084 input_rect_sd = evas_object_smart_data_get(obj);
3085 if (!input_rect_sd) return;
3087 cw = input_rect_sd->cw;
3088 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3090 if (input_rect_data->obj)
3092 evas_object_geometry_set(input_rect_data->obj,
3093 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3094 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3095 input_rect_data->rect.w, input_rect_data->rect.h);
3101 _e_comp_input_obj_smart_show(Evas_Object *obj)
3103 E_Input_Rect_Smart_Data *input_rect_sd;
3104 E_Input_Rect_Data *input_rect_data;
3107 input_rect_sd = evas_object_smart_data_get(obj);
3108 if (!input_rect_sd) return;
3110 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3112 if (input_rect_data->obj)
3114 evas_object_show(input_rect_data->obj);
3120 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3122 E_Input_Rect_Smart_Data *input_rect_sd;
3123 E_Input_Rect_Data *input_rect_data;
3126 input_rect_sd = evas_object_smart_data_get(obj);
3127 if (!input_rect_sd) return;
3129 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3131 if (input_rect_data->obj)
3133 evas_object_hide(input_rect_data->obj);
3139 _e_comp_input_obj_smart_init(void)
3141 if (_e_comp_input_obj_smart) return;
3143 static const Evas_Smart_Class sc =
3145 INPUT_OBJ_SMART_NAME,
3146 EVAS_SMART_CLASS_VERSION,
3147 _e_comp_input_obj_smart_add,
3148 _e_comp_input_obj_smart_del,
3149 _e_comp_input_obj_smart_move,
3150 _e_comp_input_obj_smart_resize,
3151 _e_comp_input_obj_smart_show,
3152 _e_comp_input_obj_smart_hide,
3165 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3171 _e_comp_smart_add(Evas_Object *obj)
3175 cw = E_NEW(E_Comp_Object, 1);
3176 EINA_SAFETY_ON_NULL_RETURN(cw);
3178 wl_signal_init(&cw->events.lower);
3179 #ifdef REFACTOR_DESK_AREA
3180 wl_signal_init(&cw->events.lower_done);
3181 wl_signal_init(&cw->events.raise);
3183 wl_signal_init(&cw->events.show);
3184 wl_signal_init(&cw->events.hide);
3185 #ifdef REFACTOR_DESK_AREA
3186 wl_signal_init(&cw->events.set_layer);
3187 wl_signal_init(&cw->events.stack_above);
3188 wl_signal_init(&cw->events.stack_below);
3191 cw->smart_obj = obj;
3192 cw->x = cw->y = cw->w = cw->h = -1;
3193 evas_object_smart_data_set(obj, cw);
3194 cw->opacity = 255.0;
3195 cw->external_content = 0;
3196 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3197 cw->transform_bg_color.r = 0;
3198 cw->transform_bg_color.g = 0;
3199 cw->transform_bg_color.b = 0;
3200 cw->transform_bg_color.a = 255;
3201 evas_object_data_set(obj, "comp_obj", cw);
3202 evas_object_move(obj, -1, -1);
3203 /* intercept ALL the callbacks! */
3204 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3205 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3206 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3207 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3208 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3209 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3210 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3211 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3212 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3213 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3214 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3216 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3217 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3218 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3219 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3221 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3222 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3224 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3225 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3227 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3229 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3230 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3234 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3237 evas_object_color_set(cw->clip, r, g, b, a);
3238 evas_object_smart_callback_call(obj, "color_set", NULL);
3243 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3246 evas_object_clip_set(cw->clip, clip);
3250 _e_comp_smart_clip_unset(Evas_Object *obj)
3253 evas_object_clip_unset(cw->clip);
3257 _e_comp_smart_hide(Evas_Object *obj)
3259 TRACE_DS_BEGIN(COMP:SMART HIDE);
3264 evas_object_hide(cw->clip);
3265 if (cw->input_obj) evas_object_hide(cw->input_obj);
3266 evas_object_hide(cw->effect_obj);
3267 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3268 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3269 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3276 /* unset native surface if current displaying buffer was destroied */
3277 if (!cw->buffer_destroy_listener.notify)
3279 Evas_Native_Surface *ns;
3280 ns = evas_object_image_native_surface_get(cw->obj);
3281 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3282 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3285 if (!cw->ec->input_only)
3287 edje_object_freeze(cw->effect_obj);
3288 edje_object_freeze(cw->shobj);
3289 edje_object_play_set(cw->shobj, 0);
3290 if (cw->frame_object)
3291 edje_object_play_set(cw->frame_object, 0);
3294 e_comp_render_queue(); //force nocomp recheck
3300 _e_comp_smart_show(Evas_Object *obj)
3308 if ((cw->w < 0) || (cw->h < 0))
3309 CRI("ACK! ec:%p", cw->ec);
3311 TRACE_DS_BEGIN(COMP:SMART SHOW);
3313 e_comp_object_map_update(obj);
3315 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3316 evas_object_show(tmp->frame);
3318 evas_object_show(cw->clip);
3319 if (cw->input_obj) evas_object_show(cw->input_obj);
3320 if (!cw->ec->input_only)
3322 edje_object_thaw(cw->effect_obj);
3323 edje_object_thaw(cw->shobj);
3324 edje_object_play_set(cw->shobj, 1);
3325 if (cw->frame_object)
3326 edje_object_play_set(cw->frame_object, 1);
3328 evas_object_show(cw->effect_obj);
3329 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3330 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3331 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3332 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3333 e_comp_render_queue();
3334 if (cw->ec->input_only)
3339 if (cw->ec->iconic && (!cw->ec->new_client))
3341 if (e_client_is_iconified_by_client(cw->ec))
3343 ELOGF("COMP", "Set launching flag..", cw->ec);
3344 cw->ec->launching = EINA_TRUE;
3347 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3349 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3352 ELOGF("COMP", "Set launching flag..", cw->ec);
3353 cw->ec->launching = EINA_TRUE;
3355 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3356 _e_comp_object_animating_begin(cw);
3357 if (!_e_comp_object_effect_visibility_start(cw, 1))
3363 /* ensure some random effect doesn't lock the client offscreen */
3367 e_comp_object_effect_set(obj, NULL);
3370 _e_comp_object_dim_update(cw);
3376 _e_comp_smart_del(Evas_Object *obj)
3382 if (cw->buffer_destroy_listener.notify)
3384 wl_list_remove(&cw->buffer_destroy_listener.link);
3385 cw->buffer_destroy_listener.notify = NULL;
3388 if (cw->tbm_surface)
3390 tbm_surface_internal_unref(cw->tbm_surface);
3391 cw->tbm_surface = NULL;
3394 if (cw->render_update_lock.buffer_ref.buffer)
3396 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3397 cw->ec, cw->render_update_lock.lock);
3398 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3401 e_comp_object_render_update_del(cw->smart_obj);
3402 E_FREE_FUNC(cw->updates, eina_tiler_free);
3403 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3410 EINA_LIST_FREE(cw->obj_mirror, o)
3412 evas_object_image_data_set(o, NULL);
3413 evas_object_freeze_events_set(o, 1);
3414 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3418 #ifdef REFACTOR_DESK_AREA
3420 _e_comp_object_layers_remove(cw);
3422 l = evas_object_data_get(obj, "comp_object-to_del");
3423 E_FREE_LIST(l, evas_object_del);
3424 _e_comp_object_mouse_event_callback_unset(cw);
3425 evas_object_del(cw->clip);
3426 evas_object_del(cw->obj);
3427 evas_object_del(cw->shobj);
3428 evas_object_del(cw->effect_obj);
3429 evas_object_del(cw->frame_object);
3430 evas_object_del(cw->input_obj);
3431 evas_object_del(cw->mask.obj);
3432 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3433 evas_object_del(cw->transform_bg_obj);
3434 evas_object_del(cw->transform_tranp_obj);
3435 evas_object_del(cw->default_input_obj);
3436 eina_stringshare_del(cw->frame_theme);
3437 eina_stringshare_del(cw->frame_name);
3441 e_comp->animating--;
3443 e_object_unref(E_OBJECT(cw->ec));
3445 cw->ec->frame = NULL;
3450 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3454 cw->x = x, cw->y = y;
3455 evas_object_move(cw->effect_obj, x, y);
3456 evas_object_move(cw->default_input_obj, x, y);
3457 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3459 e_comp_object_map_update(obj);
3463 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3465 Eina_Bool first = EINA_FALSE;
3470 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3472 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3474 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3476 if (cw->w != w || cw->h != h)
3477 e_comp_object_map_update(obj);
3479 first = ((cw->w < 1) || (cw->h < 1));
3480 cw->w = w, cw->h = h;
3484 if (cw->frame_object)
3485 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3488 /* verify pixmap:object size */
3489 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3491 if ((ww != pw) || (hh != ph))
3492 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3494 evas_object_resize(cw->effect_obj, tw, th);
3495 evas_object_resize(cw->default_input_obj, w, h);
3497 evas_object_resize(cw->input_obj, w, h);
3499 evas_object_resize(cw->mask.obj, w, h);
3500 /* resize render update tiler */
3503 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3504 cw->updates_full = 0;
3505 if (cw->updates) eina_tiler_clear(cw->updates);
3509 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3510 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3518 e_comp_render_queue();
3524 _e_comp_smart_init(void)
3526 if (_e_comp_smart) return;
3528 static const Evas_Smart_Class sc =
3531 EVAS_SMART_CLASS_VERSION,
3535 _e_comp_smart_resize,
3538 _e_comp_smart_color_set,
3539 _e_comp_smart_clip_set,
3540 _e_comp_smart_clip_unset,
3550 _e_comp_smart = evas_smart_class_new(&sc);
3555 e_comp_object_init(void)
3557 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3558 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3559 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3560 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3564 e_comp_object_shutdown(void)
3570 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3572 API_ENTRY EINA_FALSE;
3573 return !!cw->force_visible;
3575 /////////////////////////////////////////////////////////
3578 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3581 Eina_Bool comp_object;
3583 comp_object = !!evas_object_data_get(obj, "comp_object");
3588 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3590 e_comp_render_queue();
3592 l = evas_object_data_get(obj, "comp_object-to_del");
3593 E_FREE_LIST(l, evas_object_del);
3597 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3599 if (e_comp_util_object_is_above_nocomp(obj) &&
3600 (!evas_object_data_get(obj, "comp_override")))
3602 evas_object_data_set(obj, "comp_override", (void*)1);
3603 e_comp_override_add();
3608 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3610 Eina_Bool ref = EINA_TRUE;
3611 if (evas_object_visible_get(obj))
3615 d = evas_object_data_del(obj, "comp_hiding");
3617 /* currently trying to hide */
3620 /* already visible */
3624 evas_object_show(obj);
3627 evas_object_ref(obj);
3628 evas_object_data_set(obj, "comp_ref", (void*)1);
3630 edje_object_signal_emit(obj, "e,state,visible", "e");
3631 evas_object_data_set(obj, "comp_showing", (void*)1);
3632 if (e_comp_util_object_is_above_nocomp(obj))
3634 evas_object_data_set(obj, "comp_override", (void*)1);
3635 e_comp_override_add();
3640 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3642 if (!evas_object_visible_get(obj)) return;
3643 /* already hiding */
3644 if (evas_object_data_get(obj, "comp_hiding")) return;
3645 if (!evas_object_data_del(obj, "comp_showing"))
3647 evas_object_ref(obj);
3648 evas_object_data_set(obj, "comp_ref", (void*)1);
3650 edje_object_signal_emit(obj, "e,state,hidden", "e");
3651 evas_object_data_set(obj, "comp_hiding", (void*)1);
3653 if (evas_object_data_del(obj, "comp_override"))
3654 e_comp_override_timed_pop();
3658 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3660 if (!e_util_strcmp(emission, "e,action,hide,done"))
3662 if (!evas_object_data_del(obj, "comp_hiding")) return;
3663 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3664 evas_object_hide(obj);
3665 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3668 evas_object_data_del(obj, "comp_showing");
3669 if (evas_object_data_del(obj, "comp_ref"))
3670 evas_object_unref(obj);
3674 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3680 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3684 E_API E_Comp_Object_Hook *
3685 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3687 E_Comp_Object_Hook *ch;
3689 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3690 ch = E_NEW(E_Comp_Object_Hook, 1);
3691 if (!ch) return NULL;
3692 ch->hookpoint = hookpoint;
3694 ch->data = (void*)data;
3695 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3700 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3703 if (_e_comp_object_hooks_walking == 0)
3705 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3709 _e_comp_object_hooks_delete++;
3712 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3713 E_API E_Comp_Object_Intercept_Hook *
3714 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3716 E_Comp_Object_Intercept_Hook *ch;
3718 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3719 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3720 if (!ch) return NULL;
3721 ch->hookpoint = hookpoint;
3723 ch->data = (void*)data;
3724 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3729 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3732 if (_e_comp_object_intercept_hooks_walking == 0)
3734 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3738 _e_comp_object_intercept_hooks_delete++;
3743 e_comp_object_util_add(Evas_Object *obj)
3747 E_Comp_Config *conf = e_comp_config_get();
3748 Eina_Bool skip = EINA_FALSE;
3754 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3756 name = evas_object_name_get(obj);
3757 vis = evas_object_visible_get(obj);
3758 o = edje_object_add(e_comp->evas);
3759 evas_object_data_set(o, "comp_object", (void*)1);
3761 skip = (!strncmp(name, "noshadow", 8));
3763 evas_object_data_set(o, "comp_object_skip", (void*)1);
3765 if (conf->shadow_style)
3767 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3768 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3771 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3772 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3773 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3775 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3777 evas_object_geometry_get(obj, &x, &y, &w, &h);
3778 evas_object_geometry_set(o, x, y, w, h);
3779 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3781 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3783 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3784 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3787 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3788 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3790 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3792 edje_object_part_swallow(o, "e.swallow.content", obj);
3794 _e_comp_object_event_add(o);
3797 evas_object_show(o);
3802 /* utility functions for deleting objects when their "owner" is deleted */
3804 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3809 EINA_SAFETY_ON_NULL_RETURN(to_del);
3810 l = evas_object_data_get(obj, "comp_object-to_del");
3811 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3812 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3813 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3817 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3822 EINA_SAFETY_ON_NULL_RETURN(to_del);
3823 l = evas_object_data_get(obj, "comp_object-to_del");
3825 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3828 /////////////////////////////////////////////////////////
3830 EINTERN Evas_Object *
3831 e_comp_object_client_add(E_Client *ec)
3836 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3837 if (ec->frame) return NULL;
3838 _e_comp_smart_init();
3839 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3840 cw = evas_object_smart_data_get(o);
3841 if (!cw) return NULL;
3842 evas_object_data_set(o, "E_Client", ec);
3845 evas_object_data_set(o, "comp_object", (void*)1);
3847 _e_comp_object_event_add(o);
3852 /* utility functions for getting client inset */
3854 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3857 if (!cw->client_inset.calc)
3863 if (ax) *ax = x - cw->client_inset.l;
3864 if (ay) *ay = y - cw->client_inset.t;
3868 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3871 if (!cw->client_inset.calc)
3877 if (ax) *ax = x + cw->client_inset.l;
3878 if (ay) *ay = y + cw->client_inset.t;
3882 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3885 if (!cw->client_inset.calc)
3891 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3892 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3896 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3899 if (!cw->client_inset.calc)
3905 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3906 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3910 e_comp_object_client_get(Evas_Object *obj)
3915 /* FIXME: remove this when eo is used */
3916 o = evas_object_data_get(obj, "comp_smart_obj");
3918 return e_comp_object_client_get(o);
3919 return cw ? cw->ec : NULL;
3923 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3926 if (cw->frame_extends)
3927 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3932 if (w) *w = cw->ec->w;
3933 if (h) *h = cw->ec->h;
3938 e_comp_object_util_zone_get(Evas_Object *obj)
3940 E_Zone *zone = NULL;
3944 zone = e_comp_zone_find_by_ec(cw->ec);
3949 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3950 zone = e_comp_zone_xy_get(x, y);
3956 e_comp_object_util_center(Evas_Object *obj)
3958 int x, y, w, h, ow, oh;
3963 zone = e_comp_object_util_zone_get(obj);
3964 EINA_SAFETY_ON_NULL_RETURN(zone);
3965 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3966 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3967 ow = cw->ec->w, oh = cw->ec->h;
3969 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3970 x = x + (w - ow) / 2;
3971 y = y + (h - oh) / 2;
3972 evas_object_move(obj, x, y);
3976 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3978 int x, y, w, h, ow, oh;
3981 EINA_SAFETY_ON_NULL_RETURN(on);
3982 evas_object_geometry_get(on, &x, &y, &w, &h);
3983 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3984 ow = cw->ec->w, oh = cw->ec->h;
3986 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3987 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3991 e_comp_object_util_fullscreen(Evas_Object *obj)
3996 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3999 evas_object_move(obj, 0, 0);
4000 evas_object_resize(obj, e_comp->w, e_comp->h);
4005 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4013 ow = cw->w, oh = cw->h;
4015 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4016 zone = e_comp_object_util_zone_get(obj);
4017 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4018 if (x) *x = zx + (zw - ow) / 2;
4019 if (y) *y = zy + (zh - oh) / 2;
4023 e_comp_object_input_objs_del(Evas_Object *obj)
4026 E_Input_Rect_Data *input_rect_data;
4027 E_Input_Rect_Smart_Data *input_rect_sd;
4032 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4033 if (!input_rect_sd) return;
4035 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4037 if (input_rect_data->obj)
4039 evas_object_smart_member_del(input_rect_data->obj);
4040 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4042 E_FREE(input_rect_data);
4047 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4050 E_Input_Rect_Data *input_rect_data = NULL;
4051 E_Input_Rect_Smart_Data *input_rect_sd;
4052 int client_w, client_h;
4054 if (cw->ec->client.w)
4055 client_w = cw->ec->client.w;
4057 client_w = cw->ec->w;
4059 if (cw->ec->client.h)
4060 client_h = cw->ec->client.h;
4062 client_h = cw->ec->h;
4064 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4068 _e_comp_input_obj_smart_init();
4069 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4070 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4071 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4074 input_rect_sd->cw = cw;
4077 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4080 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4081 if (input_rect_data)
4083 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4084 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4088 if ((input_rect_data) &&
4089 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4091 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4092 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4093 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4094 evas_object_clip_set(input_rect_data->obj, cw->clip);
4095 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4096 evas_object_geometry_set(input_rect_data->obj,
4097 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4098 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4099 evas_object_pass_events_set(cw->default_input_obj, 1);
4100 evas_object_pass_events_set(cw->obj, 1);
4103 evas_object_show(input_rect_data->obj);
4104 evas_object_show(cw->input_obj);
4109 evas_object_smart_member_del(cw->input_obj);
4110 E_FREE_FUNC(cw->input_obj, evas_object_del);
4111 evas_object_pass_events_set(cw->default_input_obj, 0);
4112 evas_object_pass_events_set(cw->obj, 0);
4117 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4120 E_Input_Rect_Smart_Data *input_rect_sd;
4121 E_Input_Rect_Data *input_rect_data;
4124 if (!cw->input_obj) return;
4126 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4129 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4131 *list = eina_list_append(*list, &input_rect_data->rect);
4137 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4140 if (l) *l = cw->client_inset.l;
4141 if (r) *r = cw->client_inset.r;
4142 if (t) *t = cw->client_inset.t;
4143 if (b) *b = cw->client_inset.b;
4146 /* set geometry for CSD */
4148 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4154 if (cw->frame_object)
4155 CRI("ACK! ec:%p", cw->ec);
4156 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4157 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4158 calc = cw->client_inset.calc;
4159 cw->client_inset.calc = l || r || t || b;
4160 eina_stringshare_replace(&cw->frame_theme, "borderless");
4161 if (cw->client_inset.calc)
4163 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4164 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4165 e_client_size_set(cw->ec, tw, th);
4167 else if (cw->ec->maximized || cw->ec->fullscreen)
4169 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4170 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4172 if (!cw->ec->new_client)
4174 if (calc && cw->client_inset.calc)
4176 tx = cw->ec->x - (l - cw->client_inset.l);
4177 ty = cw->ec->y - (t - cw->client_inset.t);
4178 e_client_pos_set(cw->ec, tx, ty);
4180 cw->ec->changes.pos = cw->ec->changes.size = 1;
4183 cw->client_inset.l = l;
4184 cw->client_inset.r = r;
4185 cw->client_inset.t = t;
4186 cw->client_inset.b = b;
4190 e_comp_object_frame_allowed(Evas_Object *obj)
4192 API_ENTRY EINA_FALSE;
4193 return (cw->frame_object || (!cw->client_inset.calc));
4197 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4199 API_ENTRY EINA_FALSE;
4200 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4201 eina_stringshare_replace(&cw->frame_name, name);
4202 if (cw->frame_object)
4203 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4208 e_comp_object_frame_exists(Evas_Object *obj)
4210 API_ENTRY EINA_FALSE;
4211 return !!cw->frame_object;
4215 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4217 Evas_Object *o, *pbg;
4220 Eina_Stringshare *theme;
4222 API_ENTRY EINA_FALSE;
4224 if (!e_util_strcmp(cw->frame_theme, name))
4225 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4226 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4227 return _e_comp_object_shadow_setup(cw);
4228 pbg = cw->frame_object;
4229 theme = eina_stringshare_add(name);
4231 if (cw->frame_object)
4235 w = cw->ec->w, h = cw->ec->h;
4236 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4237 if ((cw->ec->w != w) || (cw->ec->h != h))
4239 cw->ec->changes.size = 1;
4242 E_FREE_FUNC(cw->frame_object, evas_object_del);
4243 if (!name) goto reshadow;
4245 o = edje_object_add(e_comp->evas);
4246 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4247 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4248 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4250 cw->frame_object = NULL;
4252 eina_stringshare_del(cw->frame_theme);
4253 cw->frame_theme = theme;
4258 if (theme != e_config->theme_default_border_style)
4260 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4261 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4265 ok = e_theme_edje_object_set(o, "base/theme/border",
4266 "e/widgets/border/default/border");
4267 if (ok && (theme == e_config->theme_default_border_style))
4269 /* Reset default border style to default */
4270 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4271 e_config_save_queue();
4278 cw->frame_object = o;
4279 eina_stringshare_del(cw->frame_theme);
4280 cw->frame_theme = theme;
4281 evas_object_name_set(o, "cw->frame_object");
4284 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4288 cw->ec->changes.icon = 1;
4294 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4299 _e_comp_object_shadow_setup(cw);
4302 int old_x, old_y, new_x = 0, new_y = 0;
4304 old_x = cw->x, old_y = cw->y;
4306 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4308 new_x = cw->ec->x, new_y = cw->ec->y;
4309 else if (cw->ec->placed || (!cw->ec->new_client))
4311 /* if no previous frame:
4312 * - reapply client_inset
4317 if (cw->ec->changes.size)
4325 zone = e_comp_zone_find_by_ec(cw->ec);
4328 x = cw->ec->client.x, y = cw->ec->client.y;
4329 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4330 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4332 new_x = x, new_y = y;
4335 if (old_x != new_x || old_y != new_y)
4337 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4338 cw->y = cw->x = -99999;
4339 evas_object_move(obj, new_x, new_y);
4343 if (cw->ec->maximized)
4345 cw->ec->changes.need_maximize = 1;
4348 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4349 if (cw->frame_object)
4351 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4354 cw->frame_extends = 0;
4355 evas_object_del(pbg);
4360 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4362 E_Comp_Object_Mover *prov;
4365 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4366 edje_object_signal_emit(cw->shobj, sig, src);
4367 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4368 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4369 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4371 /* start with highest priority callback first */
4372 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4374 if (!e_util_glob_match(sig, prov->sig)) continue;
4375 if (prov->func(prov->data, obj, sig)) break;
4380 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4382 /* FIXME: at some point I guess this should use eo to inherit
4383 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4384 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4387 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4391 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4394 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4398 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4401 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4405 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4408 Eina_Rectangle rect;
4411 if (cw->ec->input_only || (!cw->updates)) return;
4412 if (cw->nocomp) return;
4413 rect.x = x, rect.y = y;
4414 rect.w = w, rect.h = h;
4415 evas_object_smart_callback_call(obj, "damage", &rect);
4417 if (e_comp_is_on_overlay(cw->ec))
4419 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4420 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4421 * E module attempts to block screen update due to the particular policy.
4423 if (e_pixmap_resource_get(cw->ec->pixmap))
4424 cw->hwc_need_update = EINA_TRUE;
4427 /* ignore overdraw */
4428 if (cw->updates_full)
4430 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4431 e_comp_object_render_update_add(obj);
4433 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4434 evas_object_show(cw->smart_obj);
4438 /* clip rect to client surface */
4439 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4440 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4441 /* if rect is the total size of the client after clip, clear the updates
4442 * since this is guaranteed to be the whole region anyway
4444 eina_tiler_area_size_get(cw->updates, &tw, &th);
4445 if ((w > tw) || (h > th))
4447 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4448 eina_tiler_clear(cw->updates);
4449 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4451 tw = cw->ec->client.w, th = cw->ec->client.h;
4453 if ((!x) && (!y) && (w == tw) && (h == th))
4455 eina_tiler_clear(cw->updates);
4456 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4457 cw->updates_full = 1;
4458 cw->update_count = 0;
4461 if (cw->update_count > UPDATE_MAX)
4463 /* this is going to get really dumb, so just update the whole thing */
4464 eina_tiler_clear(cw->updates);
4465 cw->update_count = cw->updates_full = 1;
4466 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4467 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4471 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4472 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4474 cw->updates_exist = 1;
4475 e_comp_object_render_update_add(obj);
4477 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4478 evas_object_show(cw->smart_obj);
4482 e_comp_object_damage_exists(Evas_Object *obj)
4484 API_ENTRY EINA_FALSE;
4485 return cw->updates_exist;
4489 e_comp_object_render_update_add(Evas_Object *obj)
4493 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4494 if (cw->render_update_lock.lock) return;
4495 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4499 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4501 e_comp_render_queue();
4505 e_comp_object_render_update_del(Evas_Object *obj)
4509 if (cw->ec->input_only || (!cw->updates)) return;
4510 if (!cw->update) return;
4512 /* this gets called during comp animating to clear the update flag */
4513 if (e_comp->grabbed) return;
4514 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4515 if (!e_comp->updates)
4517 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4518 if (e_comp->render_animator)
4519 ecore_animator_freeze(e_comp->render_animator);
4524 e_comp_object_shape_apply(Evas_Object *obj)
4528 unsigned int i, *pix, *p;
4532 if (!cw->ec) return; //NYI
4533 if (cw->external_content) return;
4536 if ((cw->ec->shape_rects_num >= 1) &&
4537 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4542 ERR("BUGGER: shape with native surface? cw=%p", cw);
4545 evas_object_image_size_get(cw->obj, &w, &h);
4546 if ((w < 1) || (h < 1)) return;
4549 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4550 _e_comp_object_alpha_set(cw);
4551 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4552 evas_object_image_alpha_set(o, 1);
4554 p = pix = evas_object_image_data_get(cw->obj, 1);
4557 evas_object_image_data_set(cw->obj, pix);
4562 unsigned char *spix, *sp;
4564 spix = calloc(w * h, sizeof(unsigned char));
4566 for (i = 0; i < cw->ec->shape_rects_num; i++)
4570 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4571 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4572 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4573 sp = spix + (w * ry) + rx;
4574 for (py = 0; py < rh; py++)
4576 for (px = 0; px < rw; px++)
4584 for (py = 0; py < h; py++)
4586 for (px = 0; px < w; px++)
4588 unsigned int mask, imask;
4590 mask = ((unsigned int)(*sp)) << 24;
4592 imask |= imask >> 8;
4593 imask |= imask >> 8;
4594 *p = mask | (*p & imask);
4595 //if (*sp) *p = 0xff000000 | *p;
4596 //else *p = 0x00000000;
4605 for (py = 0; py < h; py++)
4607 for (px = 0; px < w; px++)
4611 evas_object_image_data_set(cw->obj, pix);
4612 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4613 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4615 evas_object_image_data_set(o, pix);
4616 evas_object_image_data_update_add(o, 0, 0, w, h);
4618 // don't need to fix alpha chanel as blending
4619 // should be totally off here regardless of
4620 // alpha channel content
4624 _e_comp_object_clear(E_Comp_Object *cw)
4629 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4631 if (cw->render_update_lock.lock) return;
4634 e_pixmap_clear(cw->ec->pixmap);
4636 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4637 evas_object_image_size_set(cw->obj, 1, 1);
4638 evas_object_image_data_set(cw->obj, NULL);
4639 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4641 evas_object_image_size_set(o, 1, 1);
4642 evas_object_image_data_set(o, NULL);
4645 e_comp_object_render_update_del(cw->smart_obj);
4649 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4653 API_ENTRY EINA_FALSE;
4655 if (cw->transparent.set == set)
4660 evas_object_color_get(obj, &r, &g, &b, &a);
4661 evas_object_color_set(obj, 0, 0, 0, 0);
4663 cw->transparent.user_r = r;
4664 cw->transparent.user_g = g;
4665 cw->transparent.user_b = b;
4666 cw->transparent.user_a = a;
4668 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4670 cw->transparent.user_r,
4671 cw->transparent.user_g,
4672 cw->transparent.user_b,
4673 cw->transparent.user_a);
4675 cw->transparent.set = EINA_TRUE;
4679 cw->transparent.set = EINA_FALSE;
4681 evas_object_color_set(obj,
4682 cw->transparent.user_r,
4683 cw->transparent.user_g,
4684 cw->transparent.user_b,
4685 cw->transparent.user_a);
4687 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4689 cw->transparent.user_r,
4690 cw->transparent.user_g,
4691 cw->transparent.user_b,
4692 cw->transparent.user_a);
4698 /* helper function to simplify toggling of redirection for display servers which support it */
4700 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4705 if (cw->redirected == set) return;
4706 cw->redirected = set;
4707 if (cw->external_content) return;
4709 e_comp_object_map_update(obj);
4713 if (cw->updates_exist)
4714 e_comp_object_render_update_add(obj);
4716 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4718 _e_comp_object_transparent_set(obj, EINA_FALSE);
4719 evas_object_smart_callback_call(obj, "redirected", NULL);
4723 _e_comp_object_clear(cw);
4724 _e_comp_object_transparent_set(obj, EINA_TRUE);
4725 evas_object_smart_callback_call(obj, "unredirected", NULL);
4730 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4733 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4735 if (cw->buffer_destroy_listener.notify)
4737 cw->buffer_destroy_listener.notify = NULL;
4738 wl_list_remove(&cw->buffer_destroy_listener.link);
4741 if (e_object_is_del(E_OBJECT(cw->ec)))
4743 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4748 /* if it's current displaying buffer, do not remove its content */
4749 if (!evas_object_visible_get(cw->ec->frame))
4750 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4755 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4760 if (cw->buffer_destroy_listener.notify)
4762 wl_list_remove(&cw->buffer_destroy_listener.link);
4763 cw->buffer_destroy_listener.notify = NULL;
4766 if (cw->tbm_surface)
4768 tbm_surface_internal_unref(cw->tbm_surface);
4769 cw->tbm_surface = NULL;
4774 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4776 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4777 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4779 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4781 tbm_surface_internal_ref(ns->data.tbm.buffer);
4782 cw->tbm_surface = ns->data.tbm.buffer;
4786 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4787 evas_object_image_native_surface_set(cw->obj, ns);
4791 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4793 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4794 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4795 evas_object_image_native_surface_set(o, ns);
4802 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4804 Evas_Native_Surface ns;
4807 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4808 if (cw->ec->input_only) return;
4809 if (cw->external_content) return;
4810 if (cw->render_update_lock.lock) return;
4813 memset(&ns, 0, sizeof(Evas_Native_Surface));
4817 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4818 set = (!cw->ec->shaped);
4820 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4824 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4828 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4831 if (cw->ec->input_only) return;
4834 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4835 _e_comp_object_alpha_set(cw);
4837 e_comp_object_native_surface_set(obj, cw->native);
4838 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4842 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4848 if (cw->blanked == set) return;
4850 _e_comp_object_alpha_set(cw);
4853 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4854 evas_object_image_data_set(cw->obj, NULL);
4858 e_comp_object_native_surface_set(obj, 1);
4859 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4863 _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)
4868 if (!_damage_trace) return;
4872 if (!evas_object_visible_get(cw->obj)) return;
4874 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4876 o = evas_object_rectangle_add(e_comp->evas);
4877 evas_object_layer_set(o, E_LAYER_MAX);
4878 evas_object_name_set(o, "damage_trace");
4879 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4880 evas_object_resize(o, dmg_w, dmg_h);
4881 evas_object_color_set(o, 0, 128, 0, 128);
4882 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4883 evas_object_pass_events_set(o, EINA_TRUE);
4884 evas_object_show(o);
4886 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4888 dmg_w, dmg_h, dmg_x, dmg_y,
4889 origin->w, origin->h, origin->x, origin->y);
4891 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4894 /* mark an object as dirty and setup damages */
4896 e_comp_object_dirty(Evas_Object *obj)
4899 Eina_Rectangle *rect;
4903 Eina_Bool dirty, visible;
4907 if (cw->external_content) return;
4908 if (!cw->redirected) return;
4909 if (cw->render_update_lock.lock)
4911 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4914 /* only actually dirty if pixmap is available */
4915 if (!e_pixmap_resource_get(cw->ec->pixmap))
4917 // e_pixmap_size_get returns last attached buffer size
4918 // eventhough it is destroyed
4919 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4922 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4923 visible = cw->visible;
4924 if (!dirty) w = h = 1;
4925 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4927 evas_object_image_data_set(cw->obj, NULL);
4928 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4929 evas_object_image_size_set(cw->obj, tw, th);
4930 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4931 if (cw->pending_updates)
4932 eina_tiler_area_size_set(cw->pending_updates, w, h);
4933 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4935 evas_object_image_pixels_dirty_set(o, dirty);
4937 evas_object_image_data_set(o, NULL);
4938 evas_object_image_size_set(o, tw, th);
4939 visible |= evas_object_visible_get(o);
4943 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4947 e_comp_object_native_surface_set(obj, 1);
4949 m = _e_comp_object_map_damage_transform_get(cw->ec);
4950 it = eina_tiler_iterator_new(cw->updates);
4951 EINA_ITERATOR_FOREACH(it, rect)
4953 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4954 * of evas engine and doesn't convert damage according to evas_map.
4955 * so damage of evas_object_image use surface coordinate.
4959 int damage_x, damage_y, damage_w, damage_h;
4961 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4962 &damage_x, &damage_y, &damage_w, &damage_h);
4963 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4964 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4968 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4969 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4972 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4973 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4974 if (cw->pending_updates)
4975 eina_tiler_rect_add(cw->pending_updates, rect);
4977 eina_iterator_free(it);
4978 if (m) e_map_free(m);
4979 if (cw->pending_updates)
4980 eina_tiler_clear(cw->updates);
4983 cw->pending_updates = cw->updates;
4984 cw->updates = eina_tiler_new(w, h);
4985 eina_tiler_tile_size_set(cw->updates, 1, 1);
4987 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4988 evas_object_smart_callback_call(obj, "dirty", NULL);
4989 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4990 /* force render if main object is hidden but mirrors are visible */
4991 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4992 e_comp_object_render(obj);
4996 e_comp_object_render(Evas_Object *obj)
5003 API_ENTRY EINA_FALSE;
5005 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5006 if (cw->ec->input_only) return EINA_TRUE;
5007 if (cw->external_content) return EINA_TRUE;
5008 if (cw->native) return EINA_FALSE;
5009 /* if comp object is not redirected state, comp object should not be set by newly committed data
5010 because image size of comp object is 1x1 and it should not be shown on canvas */
5011 if (!cw->redirected) return EINA_TRUE;
5012 if (cw->render_update_lock.lock)
5014 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5017 e_comp_object_render_update_del(obj);
5018 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5020 if (!cw->pending_updates)
5022 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5023 evas_object_image_data_set(cw->obj, NULL);
5024 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5025 evas_object_image_data_set(o, NULL);
5029 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5031 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5033 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5036 e_pixmap_image_refresh(cw->ec->pixmap);
5037 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5040 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5041 e_pixmap_image_data_ref(cw->ec->pixmap);
5043 /* set pixel data */
5044 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5045 _e_comp_object_alpha_set(cw);
5046 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5048 evas_object_image_data_set(o, pix);
5049 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5050 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5053 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5055 e_comp_client_post_update_add(cw->ec);
5060 /* create a duplicate of an evas object */
5062 e_comp_object_util_mirror_add(Evas_Object *obj)
5066 unsigned int *pix = NULL;
5067 Eina_Bool argb = EINA_FALSE;
5072 cw = evas_object_data_get(obj, "comp_mirror");
5075 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5076 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5077 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5078 evas_object_image_alpha_set(o, 1);
5079 evas_object_image_source_set(o, obj);
5082 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5083 if (cw->external_content)
5085 ERR("%p of client %p is external content.", obj, cw->ec);
5088 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5089 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5090 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5091 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5092 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5093 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5094 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5095 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5096 evas_object_data_set(o, "comp_mirror", cw);
5098 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5099 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5101 evas_object_image_size_set(o, tw, th);
5104 pix = evas_object_image_data_get(cw->obj, 0);
5110 evas_object_image_native_surface_set(o, cw->ns);
5113 Evas_Native_Surface ns;
5114 memset(&ns, 0, sizeof(Evas_Native_Surface));
5115 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5116 evas_object_image_native_surface_set(o, &ns);
5121 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5122 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5124 (e_pixmap_image_exists(cw->ec->pixmap)))
5125 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5127 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5134 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5135 evas_object_image_pixels_dirty_set(o, dirty);
5136 evas_object_image_data_set(o, pix);
5137 evas_object_image_data_set(cw->obj, pix);
5139 evas_object_image_data_update_add(o, 0, 0, tw, th);
5144 //////////////////////////////////////////////////////
5147 e_comp_object_effect_allowed_get(Evas_Object *obj)
5149 API_ENTRY EINA_FALSE;
5151 if (!cw->shobj) return EINA_FALSE;
5152 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5153 return !e_comp_config_get()->match.disable_borders;
5156 /* setup an api effect for a client */
5158 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5161 Eina_Stringshare *grp;
5162 E_Comp_Config *config;
5163 Eina_Bool loaded = EINA_FALSE;
5165 API_ENTRY EINA_FALSE;
5166 if (!cw->shobj) return EINA_FALSE; //input window
5168 if (!effect) effect = "none";
5169 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5171 config = e_comp_config_get();
5172 if ((config) && (config->effect_file))
5174 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5176 cw->effect_set = EINA_TRUE;
5183 edje_object_file_get(cw->effect_obj, NULL, &grp);
5184 cw->effect_set = !eina_streq(effect, "none");
5185 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5186 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5188 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5189 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5190 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5192 if (cw->effect_running)
5194 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5197 cw->effect_set = EINA_FALSE;
5198 return cw->effect_set;
5202 if (cw->effect_running)
5204 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5207 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5208 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5209 if (cw->effect_clip)
5211 evas_object_clip_unset(cw->clip);
5212 cw->effect_clip = 0;
5214 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5216 _e_comp_object_dim_update(cw);
5218 return cw->effect_set;
5221 /* set params for embryo scripts in effect */
5223 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5225 Edje_Message_Int_Set *msg;
5229 EINA_SAFETY_ON_NULL_RETURN(params);
5230 EINA_SAFETY_ON_FALSE_RETURN(count);
5231 if (!cw->effect_set) return;
5233 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5234 msg->count = (int)count;
5235 for (x = 0; x < count; x++)
5236 msg->val[x] = params[x];
5237 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5238 edje_object_message_signal_process(cw->effect_obj);
5242 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5244 Edje_Signal_Cb end_cb;
5246 E_Comp_Object *cw = data;
5248 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5249 cw->effect_running = 0;
5250 if (!_e_comp_object_animating_end(cw)) return;
5252 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5254 evas_object_data_del(cw->smart_obj, "effect_running");
5255 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5256 e_comp_visibility_calculation_set(EINA_TRUE);
5259 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5260 if (!end_cb) return;
5261 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5262 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5263 end_cb(end_data, cw->smart_obj, emission, source);
5266 /* clip effect to client's zone */
5268 e_comp_object_effect_clip(Evas_Object *obj)
5272 zone = e_comp_zone_find_by_ec(cw->ec);
5274 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5275 if (!cw->effect_clip_able) return;
5276 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5277 cw->effect_clip = 1;
5280 /* unclip effect from client's zone */
5282 e_comp_object_effect_unclip(Evas_Object *obj)
5285 if (!cw->effect_clip) return;
5286 evas_object_clip_unset(cw->smart_obj);
5287 cw->effect_clip = 0;
5290 /* start effect, running end_cb after */
5292 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5294 API_ENTRY EINA_FALSE;
5295 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5296 if (!cw->effect_set) return EINA_FALSE;
5298 if (cw->effect_running)
5300 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5303 e_comp_object_effect_clip(obj);
5304 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5306 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5307 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5308 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5309 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5311 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5312 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5314 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5315 _e_comp_object_animating_begin(cw);
5316 cw->effect_running = 1;
5320 /* stop a currently-running effect immediately */
5322 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5325 Edje_Signal_Cb end_cb_before = NULL;
5326 void *end_data_before = NULL;
5327 API_ENTRY EINA_FALSE;
5329 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5330 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5332 if (end_cb_before != end_cb) return EINA_TRUE;
5333 e_comp_object_effect_unclip(obj);
5334 if (cw->effect_clip)
5336 evas_object_clip_unset(cw->effect_obj);
5337 cw->effect_clip = 0;
5339 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5340 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5342 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5344 evas_object_data_del(cw->smart_obj, "effect_running");
5345 e_comp_visibility_calculation_set(EINA_TRUE);
5348 cw->effect_running = 0;
5349 ret = _e_comp_object_animating_end(cw);
5351 if ((ret) && (end_cb_before))
5353 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5354 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5361 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5363 return a->pri - b->pri;
5366 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5367 E_API E_Comp_Object_Mover *
5368 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5370 E_Comp_Object_Mover *prov;
5372 prov = E_NEW(E_Comp_Object_Mover, 1);
5373 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5374 prov->func = provider;
5375 prov->data = (void*)data;
5378 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5379 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5384 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5386 EINA_SAFETY_ON_NULL_RETURN(prov);
5387 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5392 e_comp_object_effect_object_get(Evas_Object *obj)
5396 return cw->effect_obj;
5400 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5402 API_ENTRY EINA_FALSE;
5403 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5404 if (!cw->effect_set) return EINA_FALSE;
5411 ////////////////////////////////////
5414 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5416 if (e_comp->autoclose.obj)
5418 e_comp_ungrab_input(0, 1);
5419 if (e_comp->autoclose.del_cb)
5420 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5421 else if (!already_del)
5423 evas_object_hide(e_comp->autoclose.obj);
5424 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5426 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5428 e_comp->autoclose.obj = NULL;
5429 e_comp->autoclose.data = NULL;
5430 e_comp->autoclose.del_cb = NULL;
5431 e_comp->autoclose.key_cb = NULL;
5432 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5436 _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)
5438 _e_comp_object_autoclose_cleanup(0);
5442 _e_comp_object_autoclose_setup(Evas_Object *obj)
5444 if (!e_comp->autoclose.rect)
5446 /* create rect just below autoclose object to catch mouse events */
5447 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5448 evas_object_move(e_comp->autoclose.rect, 0, 0);
5449 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5450 evas_object_show(e_comp->autoclose.rect);
5451 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5452 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5453 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5454 e_comp_grab_input(0, 1);
5456 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5457 evas_object_focus_set(obj, 1);
5461 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5463 _e_comp_object_autoclose_setup(obj);
5464 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5468 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5470 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5471 _e_comp_object_autoclose_cleanup(1);
5472 if (e_client_focused_get()) return;
5474 E_Zone *zone = e_zone_current_get();
5477 e_zone_focus_reset(zone);
5481 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5485 if (e_comp->autoclose.obj)
5487 if (e_comp->autoclose.obj == obj) return;
5488 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5489 e_comp->autoclose.obj = obj;
5490 e_comp->autoclose.del_cb = del_cb;
5491 e_comp->autoclose.key_cb = cb;
5492 e_comp->autoclose.data = (void*)data;
5493 if (evas_object_visible_get(obj))
5494 _e_comp_object_autoclose_setup(obj);
5496 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5497 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5500 e_comp->autoclose.obj = obj;
5501 e_comp->autoclose.del_cb = del_cb;
5502 e_comp->autoclose.key_cb = cb;
5503 e_comp->autoclose.data = (void*)data;
5504 if (evas_object_visible_get(obj))
5505 _e_comp_object_autoclose_setup(obj);
5507 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5508 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5512 e_comp_object_is_animating(Evas_Object *obj)
5516 return cw->animating;
5520 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5524 if ((cw->external_content) &&
5525 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5527 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5528 "But current external content is %d object for %p.",
5529 cw->content_type, cw->ec);
5533 cw->user_alpha_set = EINA_TRUE;
5534 cw->user_alpha = alpha;
5536 if (!cw->obj) return;
5538 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5540 evas_object_image_alpha_set(cw->obj, alpha);
5542 if ((!cw->native) && (!cw->external_content))
5543 evas_object_image_data_set(cw->obj, NULL);
5547 e_comp_object_alpha_get(Evas_Object *obj)
5549 API_ENTRY EINA_FALSE;
5551 return evas_object_image_alpha_get(cw->obj);
5555 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5557 Eina_Bool mask_set = EINA_FALSE;
5561 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5562 if (cw->ec->input_only) return;
5569 o = evas_object_rectangle_add(e_comp->evas);
5570 evas_object_color_set(o, 0, 0, 0, 0);
5571 evas_object_clip_set(o, cw->clip);
5572 evas_object_smart_member_add(o, obj);
5573 evas_object_move(o, 0, 0);
5574 evas_object_resize(o, cw->w, cw->h);
5575 /* save render op value to restore when clear a mask.
5577 * NOTE: DO NOT change the render op on ec->frame while mask object
5578 * is set. it will overwrite the changed op value. */
5579 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5580 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5581 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5582 if (cw->visible) evas_object_show(o);
5585 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5586 ELOGF("COMP", " |mask_obj", cw->ec);
5587 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5594 evas_object_smart_member_del(cw->mask.obj);
5595 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5597 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5598 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5604 e_comp_object_mask_has(Evas_Object *obj)
5606 API_ENTRY EINA_FALSE;
5608 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5612 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5617 if ((cw->external_content) &&
5618 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5620 WRN("Can set up size to ONLY evas \"image\" object. "
5621 "But current external content is %d object for %p.",
5622 cw->content_type, cw->ec);
5626 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5628 evas_object_image_size_set(cw->obj, tw, th);
5632 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5634 Eina_Bool transform_set = EINA_FALSE;
5636 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5637 if (cw->ec->input_only) return;
5639 transform_set = !!set;
5643 if (!cw->transform_bg_obj)
5645 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5646 evas_object_move(o, 0, 0);
5647 evas_object_resize(o, 1, 1);
5648 if (cw->transform_bg_color.a >= 255)
5649 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5651 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5652 evas_object_color_set(o,
5653 cw->transform_bg_color.r,
5654 cw->transform_bg_color.g,
5655 cw->transform_bg_color.b,
5656 cw->transform_bg_color.a);
5657 if (cw->visible) evas_object_show(o);
5659 cw->transform_bg_obj = o;
5660 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5662 _e_comp_object_transform_obj_stack_update(obj);
5666 if (cw->transform_bg_obj)
5668 evas_object_smart_member_del(cw->transform_bg_obj);
5669 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5675 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5679 cw->transform_bg_color.r = r;
5680 cw->transform_bg_color.g = g;
5681 cw->transform_bg_color.b = b;
5682 cw->transform_bg_color.a = a;
5684 if (cw->transform_bg_obj)
5686 evas_object_color_set(cw->transform_bg_obj,
5687 cw->transform_bg_color.r,
5688 cw->transform_bg_color.g,
5689 cw->transform_bg_color.b,
5690 cw->transform_bg_color.a);
5695 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5698 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5699 if (cw->ec->input_only) return;
5700 if (!cw->transform_bg_obj) return;
5702 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5706 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5709 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5710 if (cw->ec->input_only) return;
5711 if (!cw->transform_bg_obj) return;
5713 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5717 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5719 Eina_Bool transform_set = EINA_FALSE;
5721 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5722 if (cw->ec->input_only) return;
5724 transform_set = !!set;
5728 if (!cw->transform_tranp_obj)
5730 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5731 evas_object_move(o, 0, 0);
5732 evas_object_resize(o, 1, 1);
5733 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5734 evas_object_color_set(o, 0, 0, 0, 0);
5735 if (cw->visible) evas_object_show(o);
5737 cw->transform_tranp_obj = o;
5738 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5739 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5740 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5742 _e_comp_object_transform_obj_stack_update(obj);
5746 if (cw->transform_tranp_obj)
5748 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5749 evas_object_smart_member_del(cw->transform_tranp_obj);
5750 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5756 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5759 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5760 if (cw->ec->input_only) return;
5761 if (!cw->transform_tranp_obj) return;
5763 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5767 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5770 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5771 if (cw->ec->input_only) return;
5772 if (!cw->transform_tranp_obj) return;
5774 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5777 #ifdef REFACTOR_DESK_AREA
5780 e_comp_object_layer_update(Evas_Object *obj,
5781 Evas_Object *above, Evas_Object *below)
5783 E_Comp_Object *cw2 = NULL;
5784 Evas_Object *o = NULL;
5789 if (cw->ec->layer_block) return;
5790 if ((above) && (below))
5792 ERR("Invalid layer update request! cw=%p", cw);
5800 layer = evas_object_layer_get(o);
5801 cw2 = evas_object_data_get(o, "comp_obj");
5804 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5806 o = evas_object_above_get(o);
5807 if ((!o) || (o == cw->smart_obj)) break;
5808 if (evas_object_layer_get(o) != layer)
5810 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5815 ec = e_client_top_get();
5816 if (ec) o = ec->frame;
5819 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5823 _e_comp_object_layers_remove(cw);
5826 if (cw2->layer > cw->layer)
5827 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5828 else if (cw2->layer == cw->layer)
5831 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5833 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5835 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5838 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5841 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5846 e_comp_object_layer_get(Evas_Object *obj)
5853 e_comp_object_content_set(Evas_Object *obj,
5854 Evas_Object *content,
5855 E_Comp_Object_Content_Type type)
5857 API_ENTRY EINA_FALSE;
5859 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5860 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5861 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5865 ERR("Can't set e.swallow.content to requested content. "
5866 "Previous comp object should not be changed at all.");
5870 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5872 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5873 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5875 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5876 type, content, cw->ec, cw->ec->pixmap);
5880 cw->external_content = EINA_TRUE;
5883 cw->content_type = type;
5884 e_util_size_debug_set(cw->obj, 1);
5885 evas_object_name_set(cw->obj, "cw->obj");
5886 _e_comp_object_alpha_set(cw);
5889 _e_comp_object_shadow_setup(cw);
5895 e_comp_object_content_unset(Evas_Object *obj)
5897 API_ENTRY EINA_FALSE;
5899 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5900 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5902 if (!cw->obj && !cw->ec->visible)
5904 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5908 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5910 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5916 if (cw->frame_object)
5917 edje_object_part_unswallow(cw->frame_object, cw->obj);
5919 edje_object_part_unswallow(cw->shobj, cw->obj);
5921 evas_object_del(cw->obj);
5922 evas_object_hide(cw->obj);
5926 cw->external_content = EINA_FALSE;
5927 if (cw->ec->is_cursor)
5930 DBG("%p is cursor surface..", cw->ec);
5931 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5933 evas_object_resize(cw->ec->frame, pw, ph);
5934 evas_object_hide(cw->ec->frame);
5939 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5940 cw->obj = evas_object_image_filled_add(e_comp->evas);
5941 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5942 e_util_size_debug_set(cw->obj, 1);
5943 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5944 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5945 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5946 evas_object_name_set(cw->obj, "cw->obj");
5947 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5948 _e_comp_object_alpha_set(cw);
5951 _e_comp_object_shadow_setup(cw);
5956 _e_comp_intercept_show_helper(cw);
5960 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5961 e_comp_object_dirty(cw->smart_obj);
5962 e_comp_object_render(cw->smart_obj);
5963 e_comp_object_render_update_add(obj);
5968 EINTERN Evas_Object *
5969 e_comp_object_content_get(Evas_Object *obj)
5973 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5975 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5977 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5984 E_API E_Comp_Object_Content_Type
5985 e_comp_object_content_type_get(Evas_Object *obj)
5987 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5989 return cw->content_type;
5993 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5996 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5997 E_Comp_Config *conf = e_comp_config_get();
5998 if (cw->ec->input_only) return;
5999 if (!conf->dim_rect_enable) return;
6001 cw->dim.mask_set = mask_set;
6007 if (!cw->dim.enable) return;
6008 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6012 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6014 Eina_Bool mask_set = EINA_FALSE;
6018 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6019 E_Comp_Config *conf = e_comp_config_get();
6020 if (cw->ec->input_only) return;
6021 if (!conf->dim_rect_enable) return;
6027 if (cw->dim.mask_obj)
6029 evas_object_smart_member_del(cw->dim.mask_obj);
6030 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6033 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);
6034 o = evas_object_rectangle_add(e_comp->evas);
6035 evas_object_color_set(o, 0, 0, 0, 0);
6036 evas_object_smart_member_add(o, obj);
6037 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6038 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6040 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6041 if (cw->visible) evas_object_show(o);
6043 cw->dim.mask_obj = o;
6044 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6046 evas_object_layer_set(cw->dim.mask_obj, 9998);
6050 if (cw->dim.mask_obj)
6052 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6053 evas_object_smart_member_del(cw->dim.mask_obj);
6054 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6060 e_comp_object_dim_client_set(E_Client *ec)
6062 E_Comp_Config *conf = e_comp_config_get();
6064 if (!conf->dim_rect_enable) return ;
6065 if (dim_client == ec) return;
6067 Eina_Bool prev_dim = EINA_FALSE;
6068 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6070 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6071 prev_dim = EINA_TRUE;
6073 if (prev_dim && dim_client->visible && ec)
6075 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6076 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6080 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6081 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6087 e_comp_object_dim_client_get(void)
6089 E_Comp_Config *conf = e_comp_config_get();
6091 if (!conf->dim_rect_enable ) return NULL;
6097 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6100 char emit[32] = "\0";
6101 E_Comp_Config *conf = e_comp_config_get();
6104 if (!conf->dim_rect_enable) return;
6105 if (!cw->effect_obj) return;
6106 if (enable == cw->dim.enable) return;
6108 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6109 if (noeffect || !conf->dim_rect_effect)
6111 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6115 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6118 cw->dim.enable = enable;
6120 if (cw->dim.mask_set && !enable)
6122 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6123 edje_object_signal_emit(cw->effect_obj, emit, "e");
6125 else if (cw->dim.mask_set && enable)
6127 edje_object_signal_emit(cw->effect_obj, emit, "e");
6128 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6132 edje_object_signal_emit(cw->effect_obj, emit, "e");
6137 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6139 API_ENTRY EINA_FALSE;
6140 E_Comp_Config *conf = e_comp_config_get();
6142 if (!ec) return EINA_FALSE;
6143 if (!conf->dim_rect_enable) return EINA_FALSE;
6145 if (cw->dim.enable) return EINA_TRUE;
6151 _e_comp_object_dim_update(E_Comp_Object *cw)
6153 E_Comp_Config *conf = e_comp_config_get();
6156 if (!conf->dim_rect_enable) return;
6157 if (!cw->effect_obj) return;
6160 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6161 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6163 if (cw->dim.mask_set)
6165 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6171 e_comp_object_clear(Evas_Object *obj)
6175 _e_comp_object_clear(cw);
6179 e_comp_object_hwc_update_exists(Evas_Object *obj)
6181 API_ENTRY EINA_FALSE;
6182 return cw->hwc_need_update;
6187 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6190 cw->hwc_need_update = set;
6194 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6196 API_ENTRY EINA_FALSE;
6197 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6201 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6204 if (cw->indicator.obj != indicator)
6205 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6206 cw->indicator.obj = indicator;
6207 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6211 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6214 if (cw->indicator.obj != indicator) return;
6215 cw->indicator.obj = NULL;
6216 edje_object_part_unswallow(cw->shobj, indicator);
6220 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6223 Edje_Message_Int_Set *msg;
6225 if (!cw->indicator.obj) return;
6227 cw->indicator.w = w;
6228 cw->indicator.h = h;
6230 if (!cw->shobj) return;
6232 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6236 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6237 edje_object_message_signal_process(cw->shobj);
6240 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6242 e_comp_object_map_update(Evas_Object *obj)
6245 E_Client *ec = cw->ec;
6246 E_Comp_Wl_Client_Data *cdata;
6248 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6251 int l, remain = sizeof buffer;
6254 if (e_object_is_del(E_OBJECT(ec))) return;
6255 cdata = e_client_cdata_get(ec);
6258 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6259 * when new buffer is attached.
6261 if (!cdata->buffer_ref.buffer) return;
6263 if ((!cw->redirected) ||
6264 (e_client_video_hw_composition_check(ec)) ||
6265 (!e_comp_wl_output_buffer_transform_get(ec) &&
6266 cdata->scaler.buffer_viewport.buffer.scale == 1))
6268 if (evas_object_map_enable_get(cw->effect_obj))
6270 ELOGF("TRANSFORM", "map: disable", cw->ec);
6271 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6272 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6273 evas_object_resize(cw->effect_obj, tw, th);
6280 EINA_SAFETY_ON_NULL_RETURN(map);
6282 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6288 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6290 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6291 e_map_point_image_uv_set(map, 0, x, y);
6292 l = snprintf(p, remain, "%d,%d", x, y);
6293 p += l, remain -= l;
6295 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6296 e_map_point_image_uv_set(map, 1, x, y);
6297 l = snprintf(p, remain, " %d,%d", x, y);
6298 p += l, remain -= l;
6300 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6301 e_map_point_image_uv_set(map, 2, x, y);
6302 l = snprintf(p, remain, " %d,%d", x, y);
6303 p += l, remain -= l;
6305 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6306 e_map_point_image_uv_set(map, 3, x, y);
6307 l = snprintf(p, remain, " %d,%d", x, y);
6308 p += l, remain -= l;
6310 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6312 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6314 e_comp_object_map_set(cw->effect_obj, map);
6315 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6319 /* if there's screen rotation with comp mode, then ec->effect_obj and
6320 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6322 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6323 evas_object_resize(cw->effect_obj, tw, th);
6327 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6329 API_ENTRY EINA_FALSE;
6331 cw->render_trace = set;
6337 e_comp_object_native_usable_get(Evas_Object *obj)
6339 API_ENTRY EINA_FALSE;
6340 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6342 if (cw->ec->input_only) return EINA_FALSE;
6343 if (cw->external_content) return EINA_FALSE;
6344 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6346 /* just return true value, if it is normal case */
6347 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6350 Evas_Native_Surface *ns;
6351 ns = evas_object_image_native_surface_get(cw->obj);
6353 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6356 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6364 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6366 API_ENTRY EINA_FALSE;
6367 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6368 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6369 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6373 case E_COMP_IMAGE_FILTER_BLUR:
6374 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6376 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6377 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6379 case E_COMP_IMAGE_FILTER_INVERSE:
6380 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6382 case E_COMP_IMAGE_FILTER_NONE:
6384 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6388 cw->image_filter = filter;
6393 EINTERN E_Comp_Image_Filter
6394 e_comp_object_image_filter_get(Evas_Object *obj)
6396 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6397 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6398 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6399 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6401 return cw->image_filter;
6405 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6409 if (!_damage_trace) return;
6411 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6412 evas_object_del(obj);
6414 _damage_trace_post_objs = NULL;
6418 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6420 if (!_damage_trace) return;
6422 _damage_trace_post_objs = _damage_trace_objs;
6423 _damage_trace_objs = NULL;
6427 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6429 if (_damage_trace == onoff) return;
6433 evas_event_callback_add(e_comp->evas,
6434 EVAS_CALLBACK_RENDER_PRE,
6435 _e_comp_object_damage_trace_render_pre_cb,
6438 evas_event_callback_add(e_comp->evas,
6439 EVAS_CALLBACK_RENDER_POST,
6440 _e_comp_object_damage_trace_render_post_cb,
6447 EINA_LIST_FREE(_damage_trace_objs, obj)
6448 evas_object_del(obj);
6450 _damage_trace_objs = NULL;
6452 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6453 evas_object_del(obj);
6455 _damage_trace_post_objs = NULL;
6457 evas_event_callback_del(e_comp->evas,
6458 EVAS_CALLBACK_RENDER_PRE,
6459 _e_comp_object_damage_trace_render_pre_cb);
6461 evas_event_callback_del(e_comp->evas,
6462 EVAS_CALLBACK_RENDER_POST,
6463 _e_comp_object_damage_trace_render_post_cb);
6466 _damage_trace = onoff;
6470 e_comp_object_redirected_get(Evas_Object *obj)
6472 API_ENTRY EINA_FALSE;
6473 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6475 return cw->redirected;
6479 e_comp_object_color_visible_get(Evas_Object *obj)
6481 API_ENTRY EINA_FALSE;
6484 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6486 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6490 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6494 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6498 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6506 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6508 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6510 return e_map_set_to_comp_object(em, obj);
6514 e_comp_object_map_get(const Evas_Object *obj)
6516 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6518 return e_map_get_from_comp_object(obj);
6522 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6524 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6526 evas_object_map_enable_set(obj, enable);
6532 e_comp_object_render_update_lock(Evas_Object *obj)
6534 E_Comp_Wl_Buffer *buffer;
6535 struct wayland_tbm_client_queue *cqueue;
6537 API_ENTRY EINA_FALSE;
6539 if (cw->render_update_lock.lock == 0)
6541 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6543 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6544 if ((buffer) && (buffer->resource))
6546 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6548 wayland_tbm_server_client_queue_flush(cqueue);
6551 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6552 e_comp_object_render_update_del(obj);
6554 ELOGF("COMP", "Render update lock enabled", cw->ec);
6557 cw->render_update_lock.lock++;
6563 e_comp_object_render_update_unlock(Evas_Object *obj)
6567 if (cw->render_update_lock.lock == 0)
6570 cw->render_update_lock.lock--;
6572 if (cw->render_update_lock.lock == 0)
6575 if (cw->render_update_lock.pending_move_set)
6577 evas_object_move(obj,
6578 cw->render_update_lock.pending_move_x,
6579 cw->render_update_lock.pending_move_y);
6580 cw->render_update_lock.pending_move_x = 0;
6581 cw->render_update_lock.pending_move_y = 0;
6582 cw->render_update_lock.pending_move_set = EINA_FALSE;
6585 if (cw->render_update_lock.pending_resize_set)
6587 evas_object_resize(obj,
6588 cw->render_update_lock.pending_resize_w,
6589 cw->render_update_lock.pending_resize_h);
6590 cw->render_update_lock.pending_resize_w = 0;
6591 cw->render_update_lock.pending_resize_h = 0;
6592 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6595 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6597 if ((cw->ec->exp_iconify.buffer_flush) &&
6598 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6599 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6600 e_comp_object_clear(obj);
6602 e_comp_object_render_update_add(obj);
6604 ELOGF("COMP", "Render update lock disabled", cw->ec);
6609 e_comp_object_render_update_lock_get(Evas_Object *obj)
6611 API_ENTRY EINA_FALSE;
6613 if (cw->render_update_lock.lock > 0)
6620 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6624 if (cw->transparent.set)
6626 if (r) *r = cw->transparent.user_r;
6627 if (g) *g = cw->transparent.user_g;
6628 if (b) *b = cw->transparent.user_b;
6629 if (a) *a = cw->transparent.user_a;
6633 evas_object_color_get(obj, r, g, b, a);
6638 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6642 evas_object_render_op_set(cw->obj, op);
6645 EINTERN Evas_Render_Op
6646 e_comp_object_render_op_get(Evas_Object *obj)
6648 API_ENTRY EVAS_RENDER_BLEND;
6650 return evas_object_render_op_get(cw->obj);
6654 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6657 wl_signal_add(&cw->events.lower, listener);
6660 #ifdef REFACTOR_DESK_AREA
6662 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6665 wl_signal_add(&cw->events.lower_done, listener);
6669 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6672 wl_signal_add(&cw->events.raise, listener);
6677 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6680 wl_signal_add(&cw->events.show, listener);
6684 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6687 wl_signal_add(&cw->events.hide, listener);
6690 #ifdef REFACTOR_DESK_AREA
6692 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6695 wl_signal_add(&cw->events.set_layer, listener);
6699 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6702 wl_signal_add(&cw->events.stack_above, listener);
6706 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6709 wl_signal_add(&cw->events.stack_below, listener);