2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
5 #include "e_bindings_intern.h"
9 = keys that return objects =
10 - E_Client: the client associated with the object (E_Client*)
11 - comp_smart_obj: cw->smart_obj (Evas_Object*)
12 - comp_obj: cw (E_Comp_Object*)
14 = keys that are bool flags =
15 - client_restack: client needs a protocol-level restack
16 - comp_override: object is triggering a nocomp override to force compositing
17 - comp_ref: object has a ref from visibility animations
18 - comp_showing: object is currently running its show animation
19 - comp_hiding: object is currently running its hiding animation
20 - comp_object: object is a compositor-created object
21 - comp_object_skip: object has a name which prohibits theme shadows
22 - comp_object-to_del: list of objects which will be deleted when this object is deleted
23 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
24 - effect_running: object is animating by external module
27 #define UPDATE_MAX 512 // same as evas
28 #define FAILURE_MAX 2 // seems reasonable
29 #define SMART_NAME "e_comp_object"
30 #define INPUT_OBJ_SMART_NAME "input_object"
32 /* for non-util functions */
33 #define API_ENTRY E_Comp_Object *cw; \
34 cw = evas_object_smart_data_get(obj); \
35 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
37 /* for util functions (obj may or may not be E_Comp_Object */
38 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
41 CRI("YOU PASSED NULL! ARGH!"); \
44 cw = evas_object_smart_data_get(obj); \
45 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
47 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
49 /* enable for lots of client size info in console output */
51 # define e_util_size_debug_set(x, y)
54 /* enable along with display-specific damage INF calls to enable render tracing
58 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
60 #define RENDER_DEBUG(...)
63 #ifdef REFACTOR_DESK_AREA
65 typedef struct _E_Comp_Object
69 int x, y, w, h; // geometry
73 E_Comp_Object_Frame client_inset;
75 Eina_Stringshare *frame_theme;
76 Eina_Stringshare *frame_name;
77 Eina_Stringshare *visibility_effect; //effect when toggling visibility
79 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
81 Evas_Object *smart_obj; // smart object
82 Evas_Object *clip; // clipper over effect object
83 Evas_Object *input_obj; // input smart object
84 Evas_Object *obj; // composite object
85 Evas_Object *frame_object; // for client frames
86 Evas_Object *shobj; // shadow object
87 Evas_Object *effect_obj; // effects object
88 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
93 Evas_Object *transform_tranp_obj;// transform transp rect obj
94 Evas_Object *default_input_obj; // default input object
95 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
96 Eina_List *obj_mirror; // extra mirror objects
97 Eina_Tiler *updates; //render update regions
98 Eina_Tiler *pending_updates; //render update regions which are about to render
100 Evas_Native_Surface *ns; //for custom gl rendering
102 struct wl_listener buffer_destroy_listener;
104 unsigned int update_count; // how many updates have happened to this obj
106 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
108 unsigned int animating; // it's busy animating
109 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
110 unsigned int force_visible; //number of visible obj_mirror objects
111 Eina_Bool delete_pending : 1; // delete pending
112 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
113 Eina_Bool showing : 1; // object is currently in "show" animation
114 Eina_Bool hiding : 1; // object is currently in "hide" animation
115 Eina_Bool visible : 1; // is visible
117 Eina_Bool shaped : 1; // is shaped
118 Eina_Bool update : 1; // has updates to fetch
119 Eina_Bool redirected : 1; // has updates to fetch
120 Eina_Bool native : 1; // native
122 Eina_Bool nocomp : 1; // nocomp applied
123 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
124 Eina_Bool real_hid : 1; // last hide was a real window unmap
126 Eina_Bool effect_set : 1; //effect_obj has a valid group
127 Eina_Bool effect_running : 1; //effect_obj is playing an animation
128 Eina_Bool effect_clip : 1; //effect_obj is clipped
129 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
131 Eina_Bool updates_exist : 1;
132 Eina_Bool updates_full : 1; // entire object will be updated
134 Eina_Bool force_move : 1;
135 Eina_Bool frame_extends : 1; //frame may extend beyond object size
136 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
137 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
138 Eina_Bool user_alpha_set : 1;
139 Eina_Bool user_alpha : 1;
143 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
144 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
151 } indicator; //indicator object for internal client
155 Evas_Object *mask_obj;
158 int mask_x, mask_y, mask_w, mask_h;
161 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
163 tbm_surface_h tbm_surface;
164 E_Comp_Image_Filter image_filter;
165 Eina_Bool set_mouse_callbacks;
170 E_Comp_Wl_Buffer_Ref buffer_ref;
171 Eina_Bool pending_move_set;
172 int pending_move_x, pending_move_y;
173 Eina_Bool pending_resize_set;
174 int pending_resize_w, pending_resize_h;
175 } render_update_lock;
188 struct wl_signal lower;
189 //#ifdef REFACTOR_DESK_AREA
190 struct wl_signal raise;
192 struct wl_signal show;
193 struct wl_signal hide;
194 //#ifdef REFACTOR_DESK_AREA
195 struct wl_signal set_layer;
196 struct wl_signal stack_above;
197 struct wl_signal stack_below;
203 typedef struct _E_Input_Rect_Data
209 typedef struct _E_Input_Rect_Smart_Data
211 Eina_List *input_rect_data_list;
213 } E_Input_Rect_Smart_Data;
215 struct E_Comp_Object_Mover
218 E_Comp_Object_Mover_Cb func;
224 static Eina_Inlist *_e_comp_object_movers = NULL;
225 static Evas_Smart *_e_comp_smart = NULL;
226 static Evas_Smart *_e_comp_input_obj_smart = NULL;
228 static int _e_comp_object_hooks_delete = 0;
229 static int _e_comp_object_hooks_walking = 0;
231 static Eina_Inlist *_e_comp_object_hooks[] =
233 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
234 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
235 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
236 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
237 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
238 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
239 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
240 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
243 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
244 static int _e_comp_object_intercept_hooks_delete = 0;
245 static int _e_comp_object_intercept_hooks_walking = 0;
247 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
249 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
250 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
254 static Eina_Bool _damage_trace = EINA_FALSE;
255 static Eina_List *_damage_trace_objs = NULL;
256 static Eina_List *_damage_trace_post_objs = NULL;
258 /* sekrit functionzzz */
259 EINTERN void e_client_focused_set(E_Client *ec);
261 /* emitted every time a new noteworthy comp object is added */
262 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
264 /* ecore event define */
265 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
266 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
267 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
269 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
270 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
271 static void _e_comp_object_dim_update(E_Comp_Object *cw);
272 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
273 #ifdef REFACTOR_DESK_AREA
275 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
278 static E_Client *dim_client = NULL;
281 _e_comp_object_hooks_clean(void)
284 E_Comp_Object_Hook *ch;
287 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
288 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
290 if (!ch->delete_me) continue;
291 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
297 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
299 E_Comp_Object_Hook *ch;
300 Eina_Bool ret = EINA_TRUE;
302 if (e_object_is_del(E_OBJECT(ec)))
304 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
305 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
306 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
307 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
308 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
309 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
310 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
311 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
317 e_object_ref(E_OBJECT(ec));
318 _e_comp_object_hooks_walking++;
319 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
321 if (ch->delete_me) continue;
322 if (!(ch->func(ch->data, ec)))
328 _e_comp_object_hooks_walking--;
329 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
330 _e_comp_object_hooks_clean();
332 e_object_unref(E_OBJECT(ec));
337 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
339 _e_comp_object_intercept_hooks_clean(void)
342 E_Comp_Object_Intercept_Hook *ch;
345 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
346 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
348 if (!ch->delete_me) continue;
349 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
355 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
357 E_Comp_Object_Intercept_Hook *ch;
358 Eina_Bool ret = EINA_TRUE;
360 if (e_object_is_del(E_OBJECT(ec))) return ret;
361 e_object_ref(E_OBJECT(ec));
362 _e_comp_object_intercept_hooks_walking++;
363 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
365 if (ch->delete_me) continue;
366 if (!(ch->func(ch->data, ec)))
372 _e_comp_object_intercept_hooks_walking--;
373 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
374 _e_comp_object_intercept_hooks_clean();
376 e_object_unref(E_OBJECT(ec));
383 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
385 E_Event_Comp_Object *ev = event;
388 ec = evas_object_data_get(ev->comp_object, "E_Client");
392 e_object_unref(E_OBJECT(ec));
394 evas_object_unref(ev->comp_object);
399 _e_comp_object_event_add(Evas_Object *obj)
401 E_Event_Comp_Object *ev;
404 if (stopping) return;
405 ev = E_NEW(E_Event_Comp_Object, 1);
406 EINA_SAFETY_ON_NULL_RETURN(ev);
408 evas_object_ref(obj);
409 ev->comp_object = obj;
410 ec = evas_object_data_get(ev->comp_object, "E_Client");
414 e_object_ref(E_OBJECT(ec));
416 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
420 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
422 E_Event_Comp_Object *ev = event;
425 ec = evas_object_data_get(ev->comp_object, "E_Client");
429 e_object_unref(E_OBJECT(ec));
431 evas_object_unref(ev->comp_object);
436 _e_comp_object_event_simple(Evas_Object *obj, int type)
438 E_Event_Comp_Object *ev;
441 ev = E_NEW(E_Event_Comp_Object, 1);
444 evas_object_ref(obj);
445 ev->comp_object = obj;
446 ec = evas_object_data_get(ev->comp_object, "E_Client");
450 e_object_ref(E_OBJECT(ec));
452 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
454 /////////////////////////////////////
457 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
459 E_Comp_Object *cw = data;
461 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
465 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
467 E_Comp_Object *cw = data;
469 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
470 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
473 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
474 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
478 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
480 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_normal", cw->ec);
487 /////////////////////////////////////
489 #ifdef REFACTOR_DESK_AREA
491 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
494 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
499 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
500 if (cw->ec->input_only) return;
502 layer = evas_object_layer_get(obj);
504 if (cw->transform_bg_obj)
506 if (layer != evas_object_layer_get(cw->transform_bg_obj))
508 evas_object_layer_set(cw->transform_bg_obj, layer);
511 evas_object_stack_below(cw->transform_bg_obj, obj);
514 if (cw->transform_tranp_obj)
516 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
518 evas_object_layer_set(cw->transform_tranp_obj, layer);
521 evas_object_stack_below(cw->transform_tranp_obj, obj);
526 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
533 if (!map) return NULL;
535 e_map_util_points_populate_from_object_full(map, obj, 0);
536 e_map_util_points_color_set(map, 255, 255, 255, 255);
538 for (i = 0 ; i < 4 ; ++i)
543 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
544 e_map_point_coord_set(map, i, x, y, 1.0);
551 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
557 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
560 e_comp_object_map_set(obj, map);
561 e_comp_object_map_enable_set(obj, EINA_TRUE);
568 evas_object_map_enable_set(obj, EINA_FALSE);
573 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
579 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
582 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
584 e_comp_object_map_set(obj, map);
585 e_comp_object_map_enable_set(obj, EINA_TRUE);
592 evas_object_map_enable_set(obj, EINA_FALSE);
595 /////////////////////////////////////
597 static inline Eina_Bool
598 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
600 if (num > 1) return EINA_TRUE;
601 if ((rects[0].x == 0) && (rects[0].y == 0) &&
602 ((int)rects[0].w == w) && ((int)rects[0].h == h))
607 /////////////////////////////////////
609 /* add a client to the layer-client list */
610 #ifdef REFACTOR_DESK_AREA
613 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
615 g_rec_mutex_lock(&e_comp->ec_list_mutex);
618 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));
620 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));
621 if ((!above) && (!below))
624 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
625 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
626 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
628 e_comp->layers[cw->layer].clients_count++;
630 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
634 _e_comp_object_layers_remove(E_Comp_Object *cw)
636 g_rec_mutex_lock(&e_comp->ec_list_mutex);
638 if (cw->ec && e_comp->layers[cw->layer].clients)
640 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
641 e_comp->layers[cw->layer].clients_count--;
644 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
648 /////////////////////////////////////
650 _e_comp_object_alpha_set(E_Comp_Object *cw)
652 Eina_Bool alpha = cw->ec->argb;
654 if ((cw->external_content) &&
655 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
660 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
661 if (cw->user_alpha_set) alpha = cw->user_alpha;
663 evas_object_image_alpha_set(cw->obj, alpha);
667 _e_comp_object_shadow(E_Comp_Object *cw)
669 if (e_client_util_shadow_state_get(cw->ec))
670 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
672 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
673 if (cw->frame_object)
674 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
675 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
678 /* convert from the surface coordinates to the buffer coordinates */
680 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
682 E_Comp_Wl_Buffer_Viewport *vp;
683 E_Comp_Wl_Client_Data *cdata;
687 cdata = e_client_cdata_get(ec);
689 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
696 vp = &cdata->scaler.buffer_viewport;
697 transform = e_comp_wl_output_buffer_transform_get(ec);
699 e_pixmap_size_get(ec->pixmap, &bw, &bh);
701 /* for subsurface, it should be swap 90 and 270 */
702 if (e_comp_wl_subsurface_check(ec))
705 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
706 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
707 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
708 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
714 case WL_OUTPUT_TRANSFORM_NORMAL:
715 default: tx = sx, ty = sy; break;
716 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
717 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
718 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
719 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
722 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
725 tx *= vp->buffer.scale;
726 ty *= vp->buffer.scale;
733 _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)
741 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
742 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
749 if (dw) *dw = MAX(x1, x2) - mx;
750 if (dh) *dh = MAX(y1, y2) - my;
754 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
755 int *dx, int *dy, int *dw, int *dh)
757 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
758 E_Util_Transform_Rect_Vertex sv, dv;
762 e_pixmap_size_get(ec->pixmap, &bw, &bh);
764 sv = e_util_transform_rect_to_vertices(&rect);
766 for (i = 0; i < 4; i++)
768 double x = 0.0, y = 0.0;
770 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
772 /* if evas decide coordinate is outside of map, it returns (0, 0)
773 in this case, full damage is added.
775 if ((i != 0) && (x == 0.0) && (y == 0.0))
778 dv.vertices[i].vertex[0] = x;
779 dv.vertices[i].vertex[1] = y;
780 dv.vertices[i].vertex[2] = 1.0;
781 dv.vertices[i].vertex[3] = 1.0;
784 rect = e_util_transform_vertices_to_rect(&dv);
786 if (dx) *dx = rect.x;
787 if (dy) *dy = rect.y;
788 if (dw) *dw = rect.w;
789 if (dh) *dh = rect.h;
803 _e_comp_object_map_damage_transform_get(E_Client *ec)
810 if (!e_client_transform_core_enable_get(ec))
813 m = e_client_map_get(ec);
817 e_pixmap_size_get(ec->pixmap, &bw, &bh);
818 if ((bw == 0) || (bh == 0))
831 e_map_point_coord_set(m2, 0, 0, 0, 0);
832 e_map_point_coord_set(m2, 1, bw, 0, 0);
833 e_map_point_coord_set(m2, 2, bw, bh, 0);
834 e_map_point_coord_set(m2, 3, 0, bh, 0);
836 for (i = 0; i < 4; i++)
840 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
841 e_map_point_image_uv_set(m2, i, map_x, map_y);
848 /////////////////////////////////////
850 /* handle evas mouse-in events on client object */
852 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
854 Evas_Event_Mouse_In *ev = event_info;
855 E_Comp_Object *cw = data;
857 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
860 /* handle evas mouse-out events on client object */
862 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
864 Evas_Event_Mouse_Out *ev = event_info;
865 E_Comp_Object *cw = data;
867 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
870 /* handle evas mouse wheel events on client object */
872 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
874 Evas_Event_Mouse_Wheel *ev = event_info;
875 E_Comp_Object *cw = data;
876 E_Binding_Event_Wheel ev2;
879 if (e_client_action_get()) return;
880 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
881 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
884 /* handle evas mouse down events on client object */
886 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
888 Evas_Event_Mouse_Down *ev = event_info;
889 E_Comp_Object *cw = data;
890 E_Binding_Event_Mouse_Button ev2;
893 if (e_client_action_get()) return;
894 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
895 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
898 /* handle evas mouse up events on client object */
900 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
902 Evas_Event_Mouse_Up *ev = event_info;
903 E_Comp_Object *cw = data;
904 E_Binding_Event_Mouse_Button ev2;
907 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
908 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
909 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
912 /* handle evas mouse movement events on client object */
914 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
916 Evas_Event_Mouse_Move *ev = event_info;
917 E_Comp_Object *cw = data;
920 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
921 e_client_mouse_move(cw->ec, &ev->cur.output);
923 /////////////////////////////////////
925 /* helper function for checking compositor themes based on user-defined matches */
927 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
929 if (((m->title) && (!ec->netwm.name)) ||
930 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
932 #if defined(__cplusplus) || defined(c_plusplus)
933 if (((m->clas) && (!ec->icccm.cpp_class)) ||
934 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
937 if (((m->clas) && (!ec->icccm.class)) ||
938 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
942 if (((m->role) && (!ec->icccm.window_role)) ||
943 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
949 if ((int)ec->netwm.type != m->primary_type)
952 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
955 if (m->borderless != 0)
959 if (e_client_util_borderless(ec))
961 if (!(((m->borderless == -1) && (!borderless)) ||
962 ((m->borderless == 1) && (borderless))))
969 if (((ec->icccm.transient_for != 0) ||
972 if (!(((m->dialog == -1) && (!dialog)) ||
973 ((m->dialog == 1) && (dialog))))
976 if (m->accepts_focus != 0)
978 int accepts_focus = 0;
980 if (ec->icccm.accepts_focus)
982 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
983 ((m->accepts_focus == 1) && (accepts_focus))))
992 if (!(((m->vkbd == -1) && (!vkbd)) ||
993 ((m->vkbd == 1) && (vkbd))))
998 if (!(((m->argb == -1) && (!ec->argb)) ||
999 ((m->argb == 1) && (ec->argb))))
1002 if (m->fullscreen != 0)
1004 int fullscreen = ec->fullscreen;
1006 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1007 ((m->fullscreen == 1) && (fullscreen))))
1012 if (!(m->modal == -1))
1018 /* function for setting up a client's compositor frame theme (cw->shobj) */
1020 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1024 Eina_List *list = NULL, *l;
1025 E_Input_Rect_Data *input_rect_data;
1026 E_Input_Rect_Smart_Data *input_rect_sd;
1028 Eina_Stringshare *reshadow_group = NULL;
1029 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1030 Eina_Stringshare *name, *title;
1031 E_Comp_Config *conf = e_comp_config_get();
1033 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1034 /* match correct client type */
1035 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1036 name = cw->ec->icccm.name;
1037 title = cw->ec->icccm.title;
1038 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1039 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1041 /* skipping here is mostly a hack for systray because I hate it */
1044 EINA_LIST_FOREACH(list, l, m)
1046 if (((m->name) && (!name)) ||
1047 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1049 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1052 no_shadow = m->no_shadow;
1053 if (m->shadow_style)
1055 /* fast effects are just themes with "/fast" appended and shorter effect times */
1058 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1059 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1061 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1063 /* default to non-fast style if fast not available */
1066 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1067 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1069 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1071 if (ok && m->visibility_effect)
1072 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1079 if (skip || (cw->ec->e.state.video))
1081 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1086 if (conf->shadow_style)
1090 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1091 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1093 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1097 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1098 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1107 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1109 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1120 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1125 if (cw->ec->override)
1127 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1128 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1130 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1131 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1137 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1138 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1141 _e_comp_object_shadow(cw);
1144 if (focus || cw->ec->focused || cw->ec->override)
1145 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1147 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1149 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1152 /* visibility must always be enabled for re_manage clients to prevent
1153 * pop-in animations every time the user sees a persistent client again;
1154 * applying visibility for iconic clients prevents the client from getting
1157 if (cw->visible || cw->ec->re_manage)
1158 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1160 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1162 /* breaks animation counter */
1163 if (cw->frame_object)
1165 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1166 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1167 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1168 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1178 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1181 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1183 if (input_rect_data->obj)
1185 pass_event_flag = EINA_TRUE;
1191 if (cw->indicator.obj)
1193 Evas_Object *indicator;
1194 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1195 if (indicator != cw->indicator.obj)
1197 edje_object_part_unswallow(cw->shobj, indicator);
1198 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1199 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1203 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1204 evas_object_pass_events_set(cw->obj, pass_event_flag);
1209 /////////////////////////////////////////////
1212 _e_comp_object_animating_begin(E_Comp_Object *cw)
1215 if (cw->animating == 1)
1217 e_comp->animating++;
1219 e_object_ref(E_OBJECT(cw->ec));
1224 _e_comp_object_animating_end(E_Comp_Object *cw)
1233 if (cw->ec->launching)
1235 if (!cw->ec->extra_animating)
1237 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1238 cw->ec->launching = EINA_FALSE;
1239 if (cw->ec->first_mapped)
1241 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1242 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1245 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1249 e_comp->animating--;
1250 cw->showing = cw->hiding = 0;
1252 if (e_comp->animating == 0)
1253 e_comp_visibility_calculation_set(EINA_TRUE);
1254 /* remove ref from animation start, account for possibility of deletion from unref */
1255 return !!e_object_unref(E_OBJECT(cw->ec));
1261 /* handle the end of a compositor animation */
1263 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1265 E_Comp_Object *cw = data;
1267 /* visible clients which have never been sized are a bug */
1268 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1269 CRI("ACK! ec:%p", cw->ec);
1270 if (!_e_comp_object_animating_end(cw)) return;
1271 if (cw->animating) return;
1272 /* hide only after animation finishes to guarantee a full run of the animation */
1273 if (!cw->defer_hide) return;
1274 if ((!strcmp(emission, "e,action,hide,done")) ||
1275 (!strcmp(emission, "e,action,done")) ||
1276 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1278 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1279 evas_object_hide(cw->smart_obj);
1283 /* run a visibility compositor effect if available, return false if object is dead */
1285 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1291 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1292 if (!cw->effect_running)
1293 _e_comp_object_animating_begin(cw);
1294 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1295 return _e_comp_object_animating_end(cw);
1296 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1297 return _e_comp_object_animating_end(cw);
1299 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1302 zone = e_comp_zone_find_by_ec(cw->ec);
1304 zw = zone->w, zh = zone->h;
1309 zone = e_comp_object_util_zone_get(cw->smart_obj);
1310 if (!zone) zone = e_zone_current_get();
1317 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1318 cw->w, cw->h, zw, zh, x, y}, 8);
1319 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1320 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1323 /////////////////////////////////////////////
1325 /* create necessary objects for clients that e manages */
1327 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1329 if (cw->set_mouse_callbacks) return;
1330 if (!cw->smart_obj) return;
1332 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1336 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1337 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1339 cw->set_mouse_callbacks = EINA_TRUE;
1343 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1345 if (!cw->set_mouse_callbacks) return;
1346 if (!cw->smart_obj) return;
1348 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1352 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1353 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1355 cw->set_mouse_callbacks = EINA_FALSE;
1359 _e_comp_object_setup(E_Comp_Object *cw)
1361 cw->clip = evas_object_rectangle_add(e_comp->evas);
1362 evas_object_move(cw->clip, -9999, -9999);
1363 evas_object_resize(cw->clip, 999999, 999999);
1364 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1365 cw->effect_obj = edje_object_add(e_comp->evas);
1366 evas_object_move(cw->effect_obj, cw->x, cw->y);
1367 evas_object_clip_set(cw->effect_obj, cw->clip);
1368 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1369 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1370 cw->shobj = edje_object_add(e_comp->evas);
1371 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1372 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1373 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1375 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1376 if (cw->ec->override)
1378 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1379 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1380 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1382 else if (!cw->ec->input_only)
1384 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1385 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1386 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1388 cw->real_hid = !cw->ec->input_only;
1389 if (!cw->ec->input_only)
1391 e_util_size_debug_set(cw->effect_obj, 1);
1392 _e_comp_object_mouse_event_callback_set(cw);
1395 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1396 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1397 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1398 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1399 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1400 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1402 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1405 /////////////////////////////////////////////
1407 /* for fast path evas rendering; only called during render */
1409 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1411 E_Comp_Object *cw = data;
1412 E_Client *ec = cw->ec;
1414 int bx, by, bxx, byy;
1416 if (e_object_is_del(E_OBJECT(ec))) return;
1417 if (cw->external_content) return;
1418 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1419 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1422 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1423 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1425 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1427 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1428 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1432 bx = by = bxx = byy = 0;
1433 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1436 Edje_Message_Int_Set *msg;
1437 Edje_Message_Int msg2;
1438 Eina_Bool id = (bx || by || bxx || byy);
1440 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1446 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1448 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1452 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1453 e_comp_client_post_update_add(cw->ec);
1455 else if (e_comp_object_render(ec->frame))
1457 /* apply shape mask if necessary */
1458 if ((!cw->native) && (ec->shaped))
1459 e_comp_object_shape_apply(ec->frame);
1461 /* shaped clients get precise mouse events to handle transparent pixels */
1462 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1464 /* queue another render if client is still dirty; cannot refresh here. */
1465 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1466 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1468 if (cw->render_trace)
1470 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1476 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1478 E_Comp_Object *cw = data;
1479 E_Client *ec = cw->ec;
1481 if (e_object_is_del(E_OBJECT(ec))) return;
1482 if (cw->external_content) return;
1483 if (!e_comp->hwc) return;
1485 e_comp_client_render_list_add(cw->ec);
1487 if (!ec->hwc_window) return;
1489 e_hwc_windows_rendered_window_add(ec->hwc_window);
1492 /////////////////////////////////////////////
1495 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1497 E_Comp_Object *cw = data;
1500 if (cw->render_update_lock.lock)
1502 cw->render_update_lock.pending_move_x = x;
1503 cw->render_update_lock.pending_move_y = y;
1504 cw->render_update_lock.pending_move_set = EINA_TRUE;
1508 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1509 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1510 (cw->external_content))
1512 /* delay to move until the external content is unset */
1513 cw->ec->changes.pos = 1;
1518 if (cw->ec->move_after_resize)
1520 if ((x != cw->ec->x) || (y != cw->ec->y))
1522 if (!cw->ec->is_cursor)
1523 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1524 e_client_pos_set(cw->ec, x, y);
1525 cw->ec->changes.pos = 1;
1531 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1532 (cw->ec->manage_resize.resize_obj))
1534 e_client_pos_set(cw->ec, x, y);
1535 cw->ec->client.x = x + cw->client_inset.l;
1536 cw->ec->client.y = y + cw->client_inset.t;
1537 e_policy_visibility_client_defer_move(cw->ec);
1541 /* if frame_object does not exist, client_inset indicates CSD.
1542 * this means that ec->client matches cw->x/y, the opposite
1545 fx = (!cw->frame_object) * cw->client_inset.l;
1546 fy = (!cw->frame_object) * cw->client_inset.t;
1547 if ((cw->x == x + fx) && (cw->y == y + fy))
1549 if ((cw->ec->x != x) || (cw->ec->y != y))
1551 /* handle case where client tries to move to position and back very quickly */
1552 e_client_pos_set(cw->ec, x, y);
1553 cw->ec->client.x = x + cw->client_inset.l;
1554 cw->ec->client.y = y + cw->client_inset.t;
1558 if (!cw->ec->maximize_override)
1560 /* prevent moving in some directions while directionally maximized */
1561 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1563 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1566 ix = x + cw->client_inset.l;
1567 iy = y + cw->client_inset.t;
1568 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1569 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1570 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1572 /* prevent moving at all if move isn't allowed in current maximize state */
1573 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1574 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1577 zone = e_comp_zone_find_by_ec(cw->ec);
1580 cw->ec->changes.need_unmaximize = 1;
1581 cw->ec->saved.x = ix - zone->x;
1582 cw->ec->saved.y = iy - zone->y;
1583 cw->ec->saved.w = cw->ec->client.w;
1584 cw->ec->saved.h = cw->ec->client.h;
1588 /* only update during resize if triggered by resize */
1589 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1590 /* delay to move while surface waits paired commit serial*/
1591 if (e_client_pending_geometry_has(cw->ec))
1593 /* do nothing while waiting paired commit serial*/
1597 e_client_pos_set(cw->ec, x, y);
1598 if (cw->ec->new_client)
1600 /* don't actually do anything until first client idler loop */
1601 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1602 cw->ec->changes.pos = 1;
1607 /* only update xy position of client to avoid invalid
1608 * first damage region if it is not a new_client. */
1609 cw->ec->client.x = ix;
1610 cw->ec->client.y = iy;
1613 if (!cw->frame_object)
1615 evas_object_move(obj, x, y);
1620 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1622 E_Comp_Object *cw = data;
1623 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1626 if (cw->render_update_lock.lock)
1628 cw->render_update_lock.pending_resize_w = w;
1629 cw->render_update_lock.pending_resize_h = h;
1630 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1634 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1636 e_client_size_set(cw->ec, w, h);
1637 evas_object_resize(obj, w, h);
1641 /* if frame_object does not exist, client_inset indicates CSD.
1642 * this means that ec->client matches cw->w/h, the opposite
1645 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1646 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1647 if ((cw->w == w + fw) && (cw->h == h + fh))
1649 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1650 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1651 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1653 /* handle case where client tries to resize itself and back very quickly */
1654 e_client_size_set(cw->ec, w, h);
1655 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1656 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1657 evas_object_smart_callback_call(obj, "client_resize", NULL);
1661 /* guarantee that fullscreen is fullscreen */
1662 zone = e_comp_zone_find_by_ec(cw->ec);
1664 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1666 if (!e_client_transform_core_enable_get(cw->ec))
1669 /* calculate client size */
1670 iw = w - cw->client_inset.l - cw->client_inset.r;
1671 ih = h - cw->client_inset.t - cw->client_inset.b;
1672 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1674 /* prevent resizing while maximized depending on direction and config */
1675 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1677 Eina_Bool reject = EINA_FALSE;
1678 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1680 if (cw->ec->client.h != ih)
1682 cw->ec->saved.h = ih;
1683 cw->ec->saved.y = cw->ec->client.y - zone->y;
1684 reject = cw->ec->changes.need_unmaximize = 1;
1687 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1689 if (cw->ec->client.w != iw)
1691 cw->ec->saved.w = iw;
1692 cw->ec->saved.x = cw->ec->client.x - zone->x;
1693 reject = cw->ec->changes.need_unmaximize = 1;
1702 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1704 /* do nothing until client idler loops */
1705 if ((cw->ec->w != w) || (cw->ec->h != h))
1707 e_client_size_set(cw->ec, w, h);
1708 cw->ec->changes.size = 1;
1713 if (e_client_pending_geometry_has(cw->ec))
1715 /* do nothing while waiting paired commit serial*/
1719 e_client_size_set(cw->ec, w, h);
1721 cw->ec->client.w = iw;
1722 cw->ec->client.h = ih;
1723 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1725 /* The size of non-compositing window can be changed, so there is a
1726 * need to check that cw is H/W composited if cw is not redirected.
1727 * And of course we have to change size of evas object of H/W composited cw,
1728 * otherwise cw can't receive input events even if it is shown on the screen.
1730 Eina_Bool redirected = cw->redirected;
1732 redirected = e_comp_is_on_overlay(cw->ec);
1734 if ((!cw->ec->input_only) && (redirected) &&
1735 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1736 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1737 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1738 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1741 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1742 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1744 prev_w = cw->w, prev_h = cw->h;
1745 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1746 /* check shading and clamp to pixmap size for regular clients */
1747 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1748 (((w - fw != pw) || (h - fh != ph))))
1750 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1751 evas_object_smart_callback_call(obj, "client_resize", NULL);
1753 if (cw->frame_object || cw->ec->input_only)
1754 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1757 if ((cw->w == w) && (cw->h == h))
1759 /* going to be a noop resize which won't trigger smart resize */
1760 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1761 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1763 evas_object_resize(obj, w, h);
1767 evas_object_smart_callback_call(obj, "client_resize", NULL);
1770 if ((!cw->frame_object) && (!cw->ec->input_only))
1772 /* "just do it" for overrides */
1773 evas_object_resize(obj, w, h);
1775 if (!cw->ec->override)
1777 /* shape probably changed for non-overrides */
1782 /* this fixes positioning jiggles when using a resize mode
1783 * which also changes the client's position
1786 if (cw->frame_object)
1787 x = cw->x, y = cw->y;
1789 x = cw->ec->x, y = cw->ec->y;
1790 switch (cw->ec->resize_mode)
1792 case E_POINTER_RESIZE_BL:
1793 case E_POINTER_RESIZE_L:
1794 evas_object_move(obj, x + prev_w - cw->w, y);
1796 case E_POINTER_RESIZE_TL:
1797 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1799 case E_POINTER_RESIZE_T:
1800 case E_POINTER_RESIZE_TR:
1801 evas_object_move(obj, x, y + prev_h - cw->h);
1810 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1812 #ifdef REFACTOR_DESK_AREA
1813 E_Comp_Object *cw = data;
1814 E_Comp_Object_Data_Set_Layer layer_set_data;
1816 layer_set_data.cw = cw;
1817 layer_set_data.layer = layer;
1819 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1823 e_comp_render_queue();
1824 _e_comp_object_transform_obj_stack_update(obj);
1828 E_Comp_Object *cw = data;
1829 E_Comp_Wl_Client_Data *child_cdata;
1830 unsigned int l = e_comp_canvas_layer_map(layer);
1833 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1835 /* doing a compositor effect, follow directions */
1836 _e_comp_object_layer_set(obj, layer);
1837 if (layer == cw->ec->layer) //trying to put layer back
1841 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1842 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1843 if (cw->layer != l) goto layer_set;
1847 e_comp_render_queue();
1849 ec = e_client_above_get(cw->ec);
1850 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1851 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1852 ec = e_client_above_get(ec);
1853 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1855 ec = e_client_below_get(cw->ec);
1856 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1857 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1858 ec = e_client_below_get(ec);
1859 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1861 evas_object_stack_above(obj, ec->frame);
1866 if (ec && (cw->ec->parent == ec))
1868 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1869 evas_object_stack_above(obj, ec->frame);
1871 evas_object_stack_below(obj, ec->frame);
1874 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1880 if (cw->layer == l) return;
1881 if (e_comp_canvas_client_layer_map(layer) == 9999)
1882 return; //invalid layer for clients not doing comp effects
1883 if (cw->ec->fullscreen)
1885 cw->ec->saved.layer = layer;
1888 oldraise = e_config->transient.raise;
1890 /* clamp to valid client layer */
1891 layer = e_comp_canvas_client_layer_map_nearest(layer);
1892 cw->ec->layer = layer;
1893 if (e_config->transient.layer)
1896 Eina_List *list = eina_list_clone(cw->ec->transients);
1898 /* We need to set raise to one, else the child wont
1899 * follow to the new layer. It should be like this,
1900 * even if the user usually doesn't want to raise
1903 e_config->transient.raise = 1;
1904 EINA_LIST_FREE(list, child)
1906 child_cdata = e_client_cdata_get(child);
1907 if (child_cdata && !child_cdata->mapped)
1909 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1912 e_client_layer_set(child, layer);
1916 e_config->transient.raise = oldraise;
1918 _e_comp_object_layers_remove(cw);
1919 cw->layer = e_comp_canvas_layer_map(layer);
1920 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1921 //if (cw->ec->new_client)
1922 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1923 _e_comp_object_layer_set(obj, layer);
1924 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1925 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1926 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1928 /* can't stack a client above its own layer marker */
1929 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1931 if (!cw->visible) return;
1932 e_comp_render_queue();
1933 _e_comp_object_transform_obj_stack_update(obj);
1937 #ifdef REFACTOR_DESK_AREA
1939 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1942 #ifdef REFACTOR_DESK_AREA
1944 _e_comp_object_raise(Evas_Object *obj)
1947 _e_comp_object_raise(Evas_Object *obj)
1950 evas_object_raise(obj);
1952 if (evas_object_smart_smart_get(obj))
1954 E_Client *ec = e_comp_object_client_get(obj);
1956 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1960 #ifdef REFACTOR_DESK_AREA
1962 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1965 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1968 evas_object_lower(obj);
1970 if (evas_object_smart_smart_get(obj))
1972 E_Client *ec = e_comp_object_client_get(obj);
1975 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1976 #ifdef REFACTOR_DESK_AREA
1977 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1979 wl_signal_emit_mutable(&cw->events.lower, NULL);
1985 #ifdef REFACTOR_DESK_AREA
1987 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1990 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1993 evas_object_stack_above(obj, target);
1995 if (evas_object_smart_smart_get(obj))
1997 E_Client *ec = e_comp_object_client_get(obj);
1999 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2003 #ifdef REFACTOR_DESK_AREA
2005 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2008 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2011 evas_object_stack_below(obj, target);
2013 if (evas_object_smart_smart_get(obj))
2015 E_Client *ec = e_comp_object_client_get(obj);
2017 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2021 #ifdef REFACTOR_DESK_AREA
2023 e_comp_object_layer_set(Evas_Object *obj, short layer)
2026 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2029 evas_object_layer_set(obj, layer);
2031 if (evas_object_smart_smart_get(obj))
2033 E_Client *ec = e_comp_object_client_get(obj);
2035 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2039 #ifdef REFACTOR_DESK_AREA
2042 _e_comp_object_is_pending(E_Client *ec)
2046 if (!ec) return EINA_FALSE;
2048 topmost = e_comp_wl_topmost_parent_get(ec);
2050 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2054 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2056 E_Comp_Object *cw2 = NULL;
2059 Evas_Object *o = stack;
2060 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2062 /* We should consider topmost's layer_pending for subsurface */
2063 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2065 if (_e_comp_object_is_pending(cw->ec))
2066 e_comp_object_layer_update(cw->smart_obj,
2067 raising? stack : NULL,
2068 raising? NULL : stack);
2070 /* obey compositor effects! */
2071 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2072 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2073 stack_cb(cw->smart_obj, stack);
2074 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2075 evas_object_data_del(cw->smart_obj, "client_restack");
2079 cw2 = evas_object_data_get(o, "comp_obj");
2081 /* assume someone knew what they were doing during client init */
2082 if (cw->ec->new_client)
2083 layer = cw->ec->layer;
2084 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2085 layer = cw2->ec->layer;
2087 layer = evas_object_layer_get(stack);
2088 ecstack = e_client_below_get(cw->ec);
2089 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2091 evas_object_layer_set(cw->smart_obj, layer);
2092 /* we got our layer wrangled, return now! */
2093 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2096 /* check if we're stacking below another client */
2099 /* check for non-client layer object */
2100 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2102 /* find an existing client to use for layering
2103 * by walking up the object stack
2105 * this is guaranteed to be pretty quick since we'll either:
2106 * - run out of client layers
2107 * - find a stacking client
2109 o = evas_object_above_get(o);
2110 if ((!o) || (o == cw->smart_obj)) break;
2111 if (evas_object_layer_get(o) != layer)
2113 /* reached the top client layer somehow
2114 * use top client object
2116 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2119 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2120 * return here since the top client layer window
2125 ec = e_client_top_get();
2130 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2133 if (cw2 && cw->layer != cw2->layer)
2136 /* remove existing layers */
2137 _e_comp_object_layers_remove(cw);
2140 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2141 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2142 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2143 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2144 else //if no stacking objects found, either raise or lower
2145 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2148 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2150 /* find new object for stacking if cw2 is on state of layer_pending */
2151 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2153 E_Client *new_stack = NULL, *current_ec = NULL;
2154 current_ec = cw2->ec;
2157 while ((new_stack = e_client_below_get(current_ec)))
2159 current_ec = new_stack;
2160 if (new_stack == cw->ec) continue;
2161 if (new_stack->layer != cw2->ec->layer) break;
2162 if (!_e_comp_object_is_pending(new_stack)) break;
2164 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2165 stack = new_stack->frame;
2168 /* stack it above layer object */
2170 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2171 stack = e_comp->layers[below_layer].obj;
2176 while ((new_stack = e_client_above_get(current_ec)))
2178 current_ec = new_stack;
2179 if (new_stack == cw->ec) continue;
2180 if (new_stack->layer != cw2->ec->layer) break;
2181 if (!_e_comp_object_is_pending(new_stack)) break;
2183 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2184 stack = new_stack->frame;
2186 stack = e_comp->layers[cw2->layer].obj;
2190 /* set restack if stacking has changed */
2191 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2192 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2193 stack_cb(cw->smart_obj, stack);
2194 if (e_comp->layers[cw->layer].obj)
2195 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2197 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2199 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2200 evas_object_data_del(cw->smart_obj, "client_restack");
2201 if (!cw->visible) return;
2202 e_comp_render_queue();
2207 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2209 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2211 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2213 #ifdef REFACTOR_DESK_AREA
2214 E_Comp_Object *cw = data;
2215 E_Comp_Object_Data_Stack_Above stack_above_data;
2217 stack_above_data.cw = cw;
2218 stack_above_data.above_obj = above;
2220 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2222 if (evas_object_below_get(obj) == above)
2224 e_comp_object_layer_update(obj, above, NULL);
2228 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2230 _e_comp_object_transform_obj_stack_update(obj);
2231 _e_comp_object_transform_obj_stack_update(above);
2238 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2240 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2242 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2244 #ifdef REFACTOR_DESK_AREA
2245 E_Comp_Object *cw = data;
2246 E_Comp_Object_Data_Stack_Below stack_below_data;
2248 stack_below_data.cw = cw;
2249 stack_below_data.below_obj = below;
2251 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2254 e_comp_render_queue();
2256 if (evas_object_above_get(obj) == below)
2258 e_comp_object_layer_update(obj, NULL, below);
2262 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2264 if (evas_object_smart_smart_get(obj))
2265 _e_comp_object_transform_obj_stack_update(obj);
2266 if (evas_object_smart_smart_get(below))
2267 _e_comp_object_transform_obj_stack_update(below);
2274 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2276 E_Comp_Object *cw = data;
2278 #ifdef REFACTOR_DESK_AREA
2283 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2285 #ifdef REFACTOR_DESK_AREA
2286 wl_signal_emit_mutable(&cw->events.lower, cw);
2288 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2290 if (cw->ec->layer_pending)
2291 e_comp_object_layer_update(obj, NULL, obj);
2293 _e_comp_object_lower(cw, obj);
2296 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2297 o = evas_object_below_get(obj);
2298 _e_comp_object_layers_remove(cw);
2299 /* prepend to client list since this client should be the first item now */
2300 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2301 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2302 evas_object_data_set(obj, "client_restack", (void*)1);
2303 _e_comp_object_lower(cw, obj);
2304 evas_object_data_del(obj, "client_restack");
2305 if (!cw->visible) goto end;
2306 e_comp_render_queue();
2307 _e_comp_object_transform_obj_stack_update(obj);
2315 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2317 E_Comp_Object *cw = data;
2318 #ifdef REFACTOR_DESK_AREA
2324 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2326 #ifdef REFACTOR_DESK_AREA
2327 wl_signal_emit_mutable(&cw->events.raise, cw);
2329 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2331 if (cw->ec->layer_pending)
2333 int obj_layer = evas_object_layer_get(obj);
2334 if (cw->ec->layer != obj_layer)
2335 e_comp_object_layer_update(obj, NULL, NULL);
2338 _e_comp_object_raise(obj);
2341 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2342 o = evas_object_above_get(obj);
2343 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2345 /* still stack below override below the layer marker */
2346 for (op = o = e_comp->layers[cw->layer].obj;
2347 o && o != e_comp->layers[cw->layer - 1].obj;
2348 op = o, o = evas_object_below_get(o))
2350 if (evas_object_smart_smart_get(o))
2354 ec = e_comp_object_client_get(o);
2355 if (ec && (!ec->override)) break;
2358 _e_comp_object_stack_below(obj, op);
2359 e_client_focus_defer_set(cw->ec);
2361 if (!cw->visible) goto end;
2362 e_comp_render_queue();
2363 _e_comp_object_transform_obj_stack_update(obj);
2371 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2373 E_Comp_Object *cw = data;
2375 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2376 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2378 ELOGF("COMP", "Hide. intercepted", cw->ec);
2383 if (cw->ec->launching == EINA_TRUE)
2385 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2386 cw->ec->launching = EINA_FALSE;
2391 /* hidden flag = just do it */
2392 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2393 evas_object_hide(obj);
2395 wl_signal_emit_mutable(&cw->events.hide, NULL);
2400 if (cw->ec->input_only)
2402 /* input_only = who cares */
2403 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2404 evas_object_hide(obj);
2406 wl_signal_emit_mutable(&cw->events.hide, NULL);
2410 /* already hidden or currently animating */
2411 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2413 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2417 /* don't try hiding during shutdown */
2418 cw->defer_hide |= stopping;
2419 if (!cw->defer_hide)
2421 if ((!cw->ec->iconic) && (!cw->ec->override))
2422 /* unset delete requested so the client doesn't break */
2423 cw->ec->delete_requested = 0;
2424 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2426 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2427 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2430 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2433 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2435 _e_comp_object_animating_begin(cw);
2436 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2438 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2439 cw->defer_hide = !!cw->animating;
2441 e_comp_object_effect_set(obj, NULL);
2444 if (cw->animating) return;
2445 /* if we have no animations running, go ahead and hide */
2447 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2448 evas_object_hide(obj);
2450 wl_signal_emit_mutable(&cw->events.hide, NULL);
2454 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2456 E_Client *ec = cw->ec;
2459 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2461 if (ec->show_pending.count > 0)
2463 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2464 ec->show_pending.running = EINA_TRUE;
2468 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2469 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2471 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2476 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,
2477 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2478 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2481 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2484 if (ec->iconic && cw->animating)
2486 /* triggered during iconify animation */
2487 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2490 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2493 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2494 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2496 evas_object_move(cw->smart_obj, ec->x, ec->y);
2497 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2498 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2500 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2501 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2504 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2505 evas_object_show(cw->smart_obj);
2508 e_client_focus_defer_set(ec);
2512 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2516 pw = ec->client.w, ph = ec->client.h;
2518 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2520 ec->changes.visible = !ec->hidden;
2523 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2527 cw->updates = eina_tiler_new(pw, ph);
2530 ec->changes.visible = !ec->hidden;
2533 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2538 eina_tiler_tile_size_set(cw->updates, 1, 1);
2541 /* ignore until client idler first run */
2542 ec->changes.visible = !ec->hidden;
2545 ELOGF("COMP", "show_helper. return. new_client", ec);
2552 evas_object_move(cw->smart_obj, ec->x, ec->y);
2553 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2554 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2555 evas_object_show(cw->smart_obj);
2558 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2560 /* start_drag not received */
2561 ec->changes.visible = 1;
2564 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2567 /* re-set geometry */
2568 evas_object_move(cw->smart_obj, ec->x, ec->y);
2569 /* force resize in case it hasn't happened yet, or just to update size */
2570 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2571 if ((cw->w < 1) || (cw->h < 1))
2573 /* if resize didn't go through, try again */
2574 ec->visible = ec->changes.visible = 1;
2576 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2579 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2580 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2581 e_pixmap_clear(ec->pixmap);
2583 if (cw->real_hid && w && h)
2586 /* force comp theming in case it didn't happen already */
2587 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2588 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2589 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2592 /* only do the show if show is allowed */
2595 if (ec->internal) //internal clients render when they feel like it
2596 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2598 if (!e_client_is_iconified_by_client(ec)||
2599 e_policy_visibility_client_is_uniconic(ec))
2601 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2602 evas_object_show(cw->smart_obj);
2604 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2605 it is rendered in idle callback without native surface and
2606 compositor shows an empty frame if other objects aren't shown
2607 because job callback of e_comp called at the next loop.
2608 it causes a visual defect when windows are switched.
2612 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2613 e_comp_object_dirty(cw->smart_obj);
2614 e_comp_object_render(cw->smart_obj);
2619 wl_signal_emit_mutable(&cw->events.show, NULL);
2623 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2625 E_Comp_Object *cw = data;
2626 E_Client *ec = cw->ec;
2628 E_Input_Rect_Data *input_rect_data;
2629 E_Input_Rect_Smart_Data *input_rect_sd;
2632 if (ec->ignored) return;
2636 //INF("SHOW2 %p", ec);
2637 _e_comp_intercept_show_helper(cw);
2640 //INF("SHOW %p", ec);
2643 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2644 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2645 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2646 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2650 if ((!cw->obj) && (cw->external_content))
2652 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2656 _e_comp_object_setup(cw);
2659 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2660 cw->obj = evas_object_image_filled_add(e_comp->evas);
2661 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2662 e_util_size_debug_set(cw->obj, 1);
2663 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2664 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2665 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2666 evas_object_name_set(cw->obj, "cw->obj");
2667 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2669 _e_comp_object_alpha_set(cw);
2672 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2675 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2676 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2679 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2682 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2684 if (input_rect_data->obj)
2686 evas_object_geometry_set(input_rect_data->obj,
2687 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2688 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2689 input_rect_data->rect.w, input_rect_data->rect.h);
2696 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2698 _e_comp_intercept_show_helper(cw);
2702 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2704 E_Comp_Object *cw = data;
2708 /* note: this is here as it seems there are enough apps that do not even
2709 * expect us to emulate a look of focus but not actually set x input
2710 * focus as we do - so simply abort any focus set on such windows */
2711 /* be strict about accepting focus hint */
2712 /* be strict about accepting focus hint */
2713 if ((!ec->icccm.accepts_focus) &&
2714 (!ec->icccm.take_focus))
2718 if (e_client_focused_get() == ec)
2719 e_client_focused_set(NULL);
2721 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2722 evas_object_focus_set(obj, focus);
2726 if (focus && ec->lock_focus_out) return;
2727 if (e_object_is_del(E_OBJECT(ec)) && focus)
2728 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2730 /* filter focus setting based on current state */
2735 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2736 evas_object_focus_set(obj, focus);
2739 if ((ec->iconic) && (!ec->deskshow))
2741 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2743 /* don't focus an iconified window. that's silly! */
2744 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2745 e_client_uniconify(ec);
2746 e_client_focus_latest_set(ec);
2760 /* not yet visible, wait till the next time... */
2761 ec->want_focus = !ec->hidden;
2766 e_client_focused_set(ec);
2770 if (e_client_focused_get() == ec)
2771 e_client_focused_set(NULL);
2775 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2777 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2779 evas_object_focus_set(obj, focus);
2783 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2785 E_Comp_Object *cw = data;
2787 if (cw->transparent.set)
2789 cw->transparent.user_r = r;
2790 cw->transparent.user_g = g;
2791 cw->transparent.user_b = b;
2792 cw->transparent.user_a = a;
2794 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2796 cw->transparent.user_r,
2797 cw->transparent.user_g,
2798 cw->transparent.user_b,
2799 cw->transparent.user_a);
2803 evas_object_color_set(obj, r, g, b, a);
2806 ////////////////////////////////////////////////////
2809 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2811 int w, h, ox, oy, ow, oh;
2813 Eina_Bool pass_event_flag = EINA_FALSE;
2814 E_Input_Rect_Data *input_rect_data;
2815 E_Input_Rect_Smart_Data *input_rect_sd;
2817 if (cw->frame_object)
2819 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2820 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2821 /* set a fixed size, force edje calc, check size difference */
2822 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2823 edje_object_message_signal_process(cw->frame_object);
2824 edje_object_calc_force(cw->frame_object);
2825 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2826 cw->client_inset.l = ox;
2827 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2828 cw->client_inset.t = oy;
2829 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2830 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2831 evas_object_resize(cw->frame_object, w, h);
2835 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2838 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2840 if (input_rect_data->obj)
2842 pass_event_flag = EINA_TRUE;
2848 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2849 evas_object_pass_events_set(cw->obj, pass_event_flag);
2853 cw->client_inset.l = 0;
2854 cw->client_inset.r = 0;
2855 cw->client_inset.t = 0;
2856 cw->client_inset.b = 0;
2858 cw->client_inset.calc = !!cw->frame_object;
2862 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2864 E_Comp_Object *cw = data;
2868 /* - get current size
2870 * - readjust for new frame size
2873 w = cw->ec->w, h = cw->ec->h;
2874 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2876 _e_comp_object_frame_recalc(cw);
2878 if (!cw->ec->fullscreen)
2879 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2881 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2882 if (cw->ec->fullscreen)
2884 zone = e_comp_zone_find_by_ec(cw->ec);
2886 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2888 else if (cw->ec->new_client)
2890 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2891 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2892 evas_object_resize(cw->ec->frame, w, h);
2894 else if ((w != cw->ec->w) || (h != cw->ec->h))
2895 evas_object_resize(cw->ec->frame, w, h);
2899 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2901 E_Comp_Object *cw = data;
2903 _e_comp_object_shadow_setup(cw);
2904 if (cw->frame_object)
2906 _e_comp_object_shadow(cw);
2907 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2908 _e_comp_object_frame_recalc(cw);
2909 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2914 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2916 E_Comp_Object *cw = data;
2918 if (_e_comp_object_shadow_setup(cw))
2919 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2920 if (cw->frame_object)
2922 _e_comp_object_shadow(cw);
2923 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2924 _e_comp_object_frame_recalc(cw);
2925 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2930 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2932 E_Comp_Object *cw = data;
2934 if (cw->frame_object)
2936 _e_comp_object_shadow(cw);
2937 e_comp_object_signal_emit(obj, "e,action,unmaximize", "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_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2946 E_Comp_Object *cw = data;
2948 if (_e_comp_object_shadow_setup(cw))
2951 cw->ec->changes.size = 1;
2953 if (cw->frame_object)
2955 _e_comp_object_shadow(cw);
2956 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2957 _e_comp_object_frame_recalc(cw);
2958 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2963 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2965 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2969 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2971 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2975 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2977 E_Comp_Object *cw = data;
2979 if (!cw->ec) return; //NYI
2980 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2984 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2986 E_Comp_Object *cw = data;
2988 if (!cw->ec) return; //NYI
2989 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2993 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2995 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2999 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3001 E_Comp_Object *cw = data;
3003 if (!e_object_is_del(E_OBJECT(cw->ec)))
3004 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3008 _e_comp_input_obj_smart_add(Evas_Object *obj)
3010 E_Input_Rect_Smart_Data *input_rect_sd;
3011 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3013 if (!input_rect_sd) return;
3014 evas_object_smart_data_set(obj, input_rect_sd);
3018 _e_comp_input_obj_smart_del(Evas_Object *obj)
3020 E_Input_Rect_Smart_Data *input_rect_sd;
3021 E_Input_Rect_Data *input_rect_data;
3023 input_rect_sd = evas_object_smart_data_get(obj);
3024 if (!input_rect_sd) return;
3026 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3028 if (input_rect_data->obj)
3030 evas_object_smart_member_del(input_rect_data->obj);
3031 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3033 E_FREE(input_rect_data);
3035 E_FREE(input_rect_sd);
3039 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3041 E_Input_Rect_Smart_Data *input_rect_sd;
3042 E_Input_Rect_Data *input_rect_data;
3046 input_rect_sd = evas_object_smart_data_get(obj);
3047 if (!input_rect_sd) return;
3049 cw = input_rect_sd->cw;
3050 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3052 if (input_rect_data->obj)
3054 evas_object_geometry_set(input_rect_data->obj,
3055 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3056 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3057 input_rect_data->rect.w, input_rect_data->rect.h);
3063 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3065 E_Input_Rect_Smart_Data *input_rect_sd;
3066 E_Input_Rect_Data *input_rect_data;
3070 input_rect_sd = evas_object_smart_data_get(obj);
3071 if (!input_rect_sd) return;
3073 cw = input_rect_sd->cw;
3074 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3076 if (input_rect_data->obj)
3078 evas_object_geometry_set(input_rect_data->obj,
3079 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3080 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3081 input_rect_data->rect.w, input_rect_data->rect.h);
3087 _e_comp_input_obj_smart_show(Evas_Object *obj)
3089 E_Input_Rect_Smart_Data *input_rect_sd;
3090 E_Input_Rect_Data *input_rect_data;
3093 input_rect_sd = evas_object_smart_data_get(obj);
3094 if (!input_rect_sd) return;
3096 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3098 if (input_rect_data->obj)
3100 evas_object_show(input_rect_data->obj);
3106 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3108 E_Input_Rect_Smart_Data *input_rect_sd;
3109 E_Input_Rect_Data *input_rect_data;
3112 input_rect_sd = evas_object_smart_data_get(obj);
3113 if (!input_rect_sd) return;
3115 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3117 if (input_rect_data->obj)
3119 evas_object_hide(input_rect_data->obj);
3125 _e_comp_input_obj_smart_init(void)
3127 if (_e_comp_input_obj_smart) return;
3129 static const Evas_Smart_Class sc =
3131 INPUT_OBJ_SMART_NAME,
3132 EVAS_SMART_CLASS_VERSION,
3133 _e_comp_input_obj_smart_add,
3134 _e_comp_input_obj_smart_del,
3135 _e_comp_input_obj_smart_move,
3136 _e_comp_input_obj_smart_resize,
3137 _e_comp_input_obj_smart_show,
3138 _e_comp_input_obj_smart_hide,
3151 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3157 _e_comp_smart_add(Evas_Object *obj)
3161 cw = E_NEW(E_Comp_Object, 1);
3162 EINA_SAFETY_ON_NULL_RETURN(cw);
3164 wl_signal_init(&cw->events.lower);
3165 #ifdef REFACTOR_DESK_AREA
3166 wl_signal_init(&cw->events.lower_done);
3167 wl_signal_init(&cw->events.raise);
3169 wl_signal_init(&cw->events.show);
3170 wl_signal_init(&cw->events.hide);
3171 #ifdef REFACTOR_DESK_AREA
3172 wl_signal_init(&cw->events.set_layer);
3173 wl_signal_init(&cw->events.stack_above);
3174 wl_signal_init(&cw->events.stack_below);
3177 cw->smart_obj = obj;
3178 cw->x = cw->y = cw->w = cw->h = -1;
3179 evas_object_smart_data_set(obj, cw);
3180 cw->opacity = 255.0;
3181 cw->external_content = 0;
3182 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3183 cw->transform_bg_color.r = 0;
3184 cw->transform_bg_color.g = 0;
3185 cw->transform_bg_color.b = 0;
3186 cw->transform_bg_color.a = 255;
3187 evas_object_data_set(obj, "comp_obj", cw);
3188 evas_object_move(obj, -1, -1);
3189 /* intercept ALL the callbacks! */
3190 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3191 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3192 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3193 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3194 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3195 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3196 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3197 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3198 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3199 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3200 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3202 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3203 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3204 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3205 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3207 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3208 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3210 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3211 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3213 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3215 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3216 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3220 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3223 evas_object_color_set(cw->clip, r, g, b, a);
3224 evas_object_smart_callback_call(obj, "color_set", NULL);
3229 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3232 evas_object_clip_set(cw->clip, clip);
3236 _e_comp_smart_clip_unset(Evas_Object *obj)
3239 evas_object_clip_unset(cw->clip);
3243 _e_comp_smart_hide(Evas_Object *obj)
3245 TRACE_DS_BEGIN(COMP:SMART HIDE);
3250 evas_object_hide(cw->clip);
3251 if (cw->input_obj) evas_object_hide(cw->input_obj);
3252 evas_object_hide(cw->effect_obj);
3253 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3254 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3255 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3262 /* unset native surface if current displaying buffer was destroied */
3263 if (!cw->buffer_destroy_listener.notify)
3265 Evas_Native_Surface *ns;
3266 ns = evas_object_image_native_surface_get(cw->obj);
3267 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3268 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3271 if (!cw->ec->input_only)
3273 edje_object_freeze(cw->effect_obj);
3274 edje_object_freeze(cw->shobj);
3275 edje_object_play_set(cw->shobj, 0);
3276 if (cw->frame_object)
3277 edje_object_play_set(cw->frame_object, 0);
3280 e_comp_render_queue(); //force nocomp recheck
3286 _e_comp_smart_show(Evas_Object *obj)
3294 if ((cw->w < 0) || (cw->h < 0))
3295 CRI("ACK! ec:%p", cw->ec);
3297 TRACE_DS_BEGIN(COMP:SMART SHOW);
3299 e_comp_object_map_update(obj);
3301 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3302 evas_object_show(tmp->frame);
3304 evas_object_show(cw->clip);
3305 if (cw->input_obj) evas_object_show(cw->input_obj);
3306 if (!cw->ec->input_only)
3308 edje_object_thaw(cw->effect_obj);
3309 edje_object_thaw(cw->shobj);
3310 edje_object_play_set(cw->shobj, 1);
3311 if (cw->frame_object)
3312 edje_object_play_set(cw->frame_object, 1);
3314 evas_object_show(cw->effect_obj);
3315 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3316 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3317 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3318 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3319 e_comp_render_queue();
3320 if (cw->ec->input_only)
3325 if (cw->ec->iconic && (!cw->ec->new_client))
3327 if (e_client_is_iconified_by_client(cw->ec))
3329 ELOGF("COMP", "Set launching flag..", cw->ec);
3330 cw->ec->launching = EINA_TRUE;
3333 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3335 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3338 ELOGF("COMP", "Set launching flag..", cw->ec);
3339 cw->ec->launching = EINA_TRUE;
3341 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3342 _e_comp_object_animating_begin(cw);
3343 if (!_e_comp_object_effect_visibility_start(cw, 1))
3349 /* ensure some random effect doesn't lock the client offscreen */
3353 e_comp_object_effect_set(obj, NULL);
3356 _e_comp_object_dim_update(cw);
3362 _e_comp_smart_del(Evas_Object *obj)
3368 if (cw->buffer_destroy_listener.notify)
3370 wl_list_remove(&cw->buffer_destroy_listener.link);
3371 cw->buffer_destroy_listener.notify = NULL;
3374 if (cw->tbm_surface)
3376 tbm_surface_internal_unref(cw->tbm_surface);
3377 cw->tbm_surface = NULL;
3380 if (cw->render_update_lock.buffer_ref.buffer)
3382 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3383 cw->ec, cw->render_update_lock.lock);
3384 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3387 e_comp_object_render_update_del(cw->smart_obj);
3388 E_FREE_FUNC(cw->updates, eina_tiler_free);
3389 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3396 EINA_LIST_FREE(cw->obj_mirror, o)
3398 evas_object_image_data_set(o, NULL);
3399 evas_object_freeze_events_set(o, 1);
3400 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3404 #ifdef REFACTOR_DESK_AREA
3406 _e_comp_object_layers_remove(cw);
3408 l = evas_object_data_get(obj, "comp_object-to_del");
3409 E_FREE_LIST(l, evas_object_del);
3410 _e_comp_object_mouse_event_callback_unset(cw);
3411 evas_object_del(cw->clip);
3412 evas_object_del(cw->obj);
3413 evas_object_del(cw->shobj);
3414 evas_object_del(cw->effect_obj);
3415 evas_object_del(cw->frame_object);
3416 evas_object_del(cw->input_obj);
3417 evas_object_del(cw->mask.obj);
3418 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3419 evas_object_del(cw->transform_bg_obj);
3420 evas_object_del(cw->transform_tranp_obj);
3421 evas_object_del(cw->default_input_obj);
3422 eina_stringshare_del(cw->frame_theme);
3423 eina_stringshare_del(cw->frame_name);
3427 e_comp->animating--;
3429 e_object_unref(E_OBJECT(cw->ec));
3431 cw->ec->frame = NULL;
3436 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3440 cw->x = x, cw->y = y;
3441 evas_object_move(cw->effect_obj, x, y);
3442 evas_object_move(cw->default_input_obj, x, y);
3443 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3445 e_comp_object_map_update(obj);
3449 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3451 Eina_Bool first = EINA_FALSE;
3456 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3458 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3460 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3462 if (cw->w != w || cw->h != h)
3463 e_comp_object_map_update(obj);
3465 first = ((cw->w < 1) || (cw->h < 1));
3466 cw->w = w, cw->h = h;
3470 if (cw->frame_object)
3471 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3474 /* verify pixmap:object size */
3475 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3477 if ((ww != pw) || (hh != ph))
3478 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3480 evas_object_resize(cw->effect_obj, tw, th);
3481 evas_object_resize(cw->default_input_obj, w, h);
3483 evas_object_resize(cw->input_obj, w, h);
3485 evas_object_resize(cw->mask.obj, w, h);
3486 /* resize render update tiler */
3489 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3490 cw->updates_full = 0;
3491 if (cw->updates) eina_tiler_clear(cw->updates);
3495 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3496 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3504 e_comp_render_queue();
3510 _e_comp_smart_init(void)
3512 if (_e_comp_smart) return;
3514 static const Evas_Smart_Class sc =
3517 EVAS_SMART_CLASS_VERSION,
3521 _e_comp_smart_resize,
3524 _e_comp_smart_color_set,
3525 _e_comp_smart_clip_set,
3526 _e_comp_smart_clip_unset,
3536 _e_comp_smart = evas_smart_class_new(&sc);
3541 e_comp_object_init(void)
3543 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3544 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3545 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3546 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3550 e_comp_object_shutdown(void)
3556 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3558 API_ENTRY EINA_FALSE;
3559 return !!cw->force_visible;
3561 /////////////////////////////////////////////////////////
3564 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3567 Eina_Bool comp_object;
3569 comp_object = !!evas_object_data_get(obj, "comp_object");
3574 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3576 e_comp_render_queue();
3578 l = evas_object_data_get(obj, "comp_object-to_del");
3579 E_FREE_LIST(l, evas_object_del);
3583 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3585 if (e_comp_util_object_is_above_nocomp(obj) &&
3586 (!evas_object_data_get(obj, "comp_override")))
3588 evas_object_data_set(obj, "comp_override", (void*)1);
3589 e_comp_override_add();
3594 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3596 Eina_Bool ref = EINA_TRUE;
3597 if (evas_object_visible_get(obj))
3601 d = evas_object_data_del(obj, "comp_hiding");
3603 /* currently trying to hide */
3606 /* already visible */
3610 evas_object_show(obj);
3613 evas_object_ref(obj);
3614 evas_object_data_set(obj, "comp_ref", (void*)1);
3616 edje_object_signal_emit(obj, "e,state,visible", "e");
3617 evas_object_data_set(obj, "comp_showing", (void*)1);
3618 if (e_comp_util_object_is_above_nocomp(obj))
3620 evas_object_data_set(obj, "comp_override", (void*)1);
3621 e_comp_override_add();
3626 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3628 if (!evas_object_visible_get(obj)) return;
3629 /* already hiding */
3630 if (evas_object_data_get(obj, "comp_hiding")) return;
3631 if (!evas_object_data_del(obj, "comp_showing"))
3633 evas_object_ref(obj);
3634 evas_object_data_set(obj, "comp_ref", (void*)1);
3636 edje_object_signal_emit(obj, "e,state,hidden", "e");
3637 evas_object_data_set(obj, "comp_hiding", (void*)1);
3639 if (evas_object_data_del(obj, "comp_override"))
3640 e_comp_override_timed_pop();
3644 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3646 if (!e_util_strcmp(emission, "e,action,hide,done"))
3648 if (!evas_object_data_del(obj, "comp_hiding")) return;
3649 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3650 evas_object_hide(obj);
3651 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3654 evas_object_data_del(obj, "comp_showing");
3655 if (evas_object_data_del(obj, "comp_ref"))
3656 evas_object_unref(obj);
3660 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3666 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3670 E_API E_Comp_Object_Hook *
3671 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3673 E_Comp_Object_Hook *ch;
3675 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3676 ch = E_NEW(E_Comp_Object_Hook, 1);
3677 if (!ch) return NULL;
3678 ch->hookpoint = hookpoint;
3680 ch->data = (void*)data;
3681 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3686 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3689 if (_e_comp_object_hooks_walking == 0)
3691 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3695 _e_comp_object_hooks_delete++;
3698 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3699 E_API E_Comp_Object_Intercept_Hook *
3700 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3702 E_Comp_Object_Intercept_Hook *ch;
3704 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3705 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3706 if (!ch) return NULL;
3707 ch->hookpoint = hookpoint;
3709 ch->data = (void*)data;
3710 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3715 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3718 if (_e_comp_object_intercept_hooks_walking == 0)
3720 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3724 _e_comp_object_intercept_hooks_delete++;
3729 e_comp_object_util_add(Evas_Object *obj)
3733 E_Comp_Config *conf = e_comp_config_get();
3734 Eina_Bool skip = EINA_FALSE;
3740 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3742 name = evas_object_name_get(obj);
3743 vis = evas_object_visible_get(obj);
3744 o = edje_object_add(e_comp->evas);
3745 evas_object_data_set(o, "comp_object", (void*)1);
3747 skip = (!strncmp(name, "noshadow", 8));
3749 evas_object_data_set(o, "comp_object_skip", (void*)1);
3751 if (conf->shadow_style)
3753 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3754 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3757 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3758 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3759 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3761 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3763 evas_object_geometry_get(obj, &x, &y, &w, &h);
3764 evas_object_geometry_set(o, x, y, w, h);
3765 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3767 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3769 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3770 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3771 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3772 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3773 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3774 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3776 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3778 edje_object_part_swallow(o, "e.swallow.content", obj);
3780 _e_comp_object_event_add(o);
3783 evas_object_show(o);
3788 /* utility functions for deleting objects when their "owner" is deleted */
3790 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3795 EINA_SAFETY_ON_NULL_RETURN(to_del);
3796 l = evas_object_data_get(obj, "comp_object-to_del");
3797 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3798 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3799 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3803 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3808 EINA_SAFETY_ON_NULL_RETURN(to_del);
3809 l = evas_object_data_get(obj, "comp_object-to_del");
3811 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3814 /////////////////////////////////////////////////////////
3816 EINTERN Evas_Object *
3817 e_comp_object_client_add(E_Client *ec)
3822 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3823 if (ec->frame) return NULL;
3824 _e_comp_smart_init();
3825 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3826 cw = evas_object_smart_data_get(o);
3827 if (!cw) return NULL;
3828 evas_object_data_set(o, "E_Client", ec);
3831 evas_object_data_set(o, "comp_object", (void*)1);
3833 _e_comp_object_event_add(o);
3838 /* utility functions for getting client inset */
3840 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3843 if (!cw->client_inset.calc)
3849 if (ax) *ax = x - cw->client_inset.l;
3850 if (ay) *ay = y - cw->client_inset.t;
3854 e_comp_object_frame_xy_unadjust(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_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3871 if (!cw->client_inset.calc)
3877 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3878 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3882 e_comp_object_frame_wh_unadjust(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_client_get(Evas_Object *obj)
3901 /* FIXME: remove this when eo is used */
3902 o = evas_object_data_get(obj, "comp_smart_obj");
3904 return e_comp_object_client_get(o);
3905 return cw ? cw->ec : NULL;
3909 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3912 if (cw->frame_extends)
3913 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3918 if (w) *w = cw->ec->w;
3919 if (h) *h = cw->ec->h;
3924 e_comp_object_util_zone_get(Evas_Object *obj)
3926 E_Zone *zone = NULL;
3930 zone = e_comp_zone_find_by_ec(cw->ec);
3935 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3936 zone = e_comp_zone_xy_get(x, y);
3942 e_comp_object_util_center(Evas_Object *obj)
3944 int x, y, w, h, ow, oh;
3949 zone = e_comp_object_util_zone_get(obj);
3950 EINA_SAFETY_ON_NULL_RETURN(zone);
3951 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3952 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3953 ow = cw->ec->w, oh = cw->ec->h;
3955 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3956 x = x + (w - ow) / 2;
3957 y = y + (h - oh) / 2;
3958 evas_object_move(obj, x, y);
3962 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3964 int x, y, w, h, ow, oh;
3967 EINA_SAFETY_ON_NULL_RETURN(on);
3968 evas_object_geometry_get(on, &x, &y, &w, &h);
3969 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3970 ow = cw->ec->w, oh = cw->ec->h;
3972 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3973 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3977 e_comp_object_util_fullscreen(Evas_Object *obj)
3982 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3985 evas_object_move(obj, 0, 0);
3986 evas_object_resize(obj, e_comp->w, e_comp->h);
3991 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3999 ow = cw->w, oh = cw->h;
4001 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4002 zone = e_comp_object_util_zone_get(obj);
4003 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4004 if (x) *x = zx + (zw - ow) / 2;
4005 if (y) *y = zy + (zh - oh) / 2;
4009 e_comp_object_input_objs_del(Evas_Object *obj)
4012 E_Input_Rect_Data *input_rect_data;
4013 E_Input_Rect_Smart_Data *input_rect_sd;
4018 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4019 if (!input_rect_sd) return;
4021 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4023 if (input_rect_data->obj)
4025 evas_object_smart_member_del(input_rect_data->obj);
4026 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4028 E_FREE(input_rect_data);
4033 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4036 E_Input_Rect_Data *input_rect_data = NULL;
4037 E_Input_Rect_Smart_Data *input_rect_sd;
4038 int client_w, client_h;
4040 if (cw->ec->client.w)
4041 client_w = cw->ec->client.w;
4043 client_w = cw->ec->w;
4045 if (cw->ec->client.h)
4046 client_h = cw->ec->client.h;
4048 client_h = cw->ec->h;
4050 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4054 _e_comp_input_obj_smart_init();
4055 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4056 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4057 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4060 input_rect_sd->cw = cw;
4063 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4066 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4067 if (input_rect_data)
4069 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4070 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4074 if ((input_rect_data) &&
4075 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4077 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4078 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4079 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4080 evas_object_clip_set(input_rect_data->obj, cw->clip);
4081 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4082 evas_object_geometry_set(input_rect_data->obj,
4083 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4084 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4085 evas_object_pass_events_set(cw->default_input_obj, 1);
4086 evas_object_pass_events_set(cw->obj, 1);
4089 evas_object_show(input_rect_data->obj);
4090 evas_object_show(cw->input_obj);
4095 evas_object_smart_member_del(cw->input_obj);
4096 E_FREE_FUNC(cw->input_obj, evas_object_del);
4097 evas_object_pass_events_set(cw->default_input_obj, 0);
4098 evas_object_pass_events_set(cw->obj, 0);
4103 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4106 E_Input_Rect_Smart_Data *input_rect_sd;
4107 E_Input_Rect_Data *input_rect_data;
4110 if (!cw->input_obj) return;
4112 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4115 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4117 *list = eina_list_append(*list, &input_rect_data->rect);
4123 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4126 if (l) *l = cw->client_inset.l;
4127 if (r) *r = cw->client_inset.r;
4128 if (t) *t = cw->client_inset.t;
4129 if (b) *b = cw->client_inset.b;
4132 /* set geometry for CSD */
4134 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4140 if (cw->frame_object)
4141 CRI("ACK! ec:%p", cw->ec);
4142 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4143 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4144 calc = cw->client_inset.calc;
4145 cw->client_inset.calc = l || r || t || b;
4146 eina_stringshare_replace(&cw->frame_theme, "borderless");
4147 if (cw->client_inset.calc)
4149 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4150 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4151 e_client_size_set(cw->ec, tw, th);
4153 else if (cw->ec->maximized || cw->ec->fullscreen)
4155 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4156 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4158 if (!cw->ec->new_client)
4160 if (calc && cw->client_inset.calc)
4162 tx = cw->ec->x - (l - cw->client_inset.l);
4163 ty = cw->ec->y - (t - cw->client_inset.t);
4164 e_client_pos_set(cw->ec, tx, ty);
4166 cw->ec->changes.pos = cw->ec->changes.size = 1;
4169 cw->client_inset.l = l;
4170 cw->client_inset.r = r;
4171 cw->client_inset.t = t;
4172 cw->client_inset.b = b;
4176 e_comp_object_frame_allowed(Evas_Object *obj)
4178 API_ENTRY EINA_FALSE;
4179 return (cw->frame_object || (!cw->client_inset.calc));
4183 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4185 API_ENTRY EINA_FALSE;
4186 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4187 eina_stringshare_replace(&cw->frame_name, name);
4188 if (cw->frame_object)
4189 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4194 e_comp_object_frame_exists(Evas_Object *obj)
4196 API_ENTRY EINA_FALSE;
4197 return !!cw->frame_object;
4201 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4203 Evas_Object *o, *pbg;
4206 Eina_Stringshare *theme;
4208 API_ENTRY EINA_FALSE;
4210 if (!e_util_strcmp(cw->frame_theme, name))
4211 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4212 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4213 return _e_comp_object_shadow_setup(cw);
4214 pbg = cw->frame_object;
4215 theme = eina_stringshare_add(name);
4217 if (cw->frame_object)
4221 w = cw->ec->w, h = cw->ec->h;
4222 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4223 if ((cw->ec->w != w) || (cw->ec->h != h))
4225 cw->ec->changes.size = 1;
4228 E_FREE_FUNC(cw->frame_object, evas_object_del);
4229 if (!name) goto reshadow;
4231 o = edje_object_add(e_comp->evas);
4232 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4233 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4234 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4236 cw->frame_object = NULL;
4238 eina_stringshare_del(cw->frame_theme);
4239 cw->frame_theme = theme;
4244 if (theme != e_config->theme_default_border_style)
4246 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4247 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4251 ok = e_theme_edje_object_set(o, "base/theme/border",
4252 "e/widgets/border/default/border");
4253 if (ok && (theme == e_config->theme_default_border_style))
4255 /* Reset default border style to default */
4256 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4257 e_config_save_queue();
4264 cw->frame_object = o;
4265 eina_stringshare_del(cw->frame_theme);
4266 cw->frame_theme = theme;
4267 evas_object_name_set(o, "cw->frame_object");
4270 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4274 cw->ec->changes.icon = 1;
4280 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4285 _e_comp_object_shadow_setup(cw);
4288 int old_x, old_y, new_x = 0, new_y = 0;
4290 old_x = cw->x, old_y = cw->y;
4292 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4294 new_x = cw->ec->x, new_y = cw->ec->y;
4295 else if (cw->ec->placed || (!cw->ec->new_client))
4297 /* if no previous frame:
4298 * - reapply client_inset
4303 if (cw->ec->changes.size)
4311 zone = e_comp_zone_find_by_ec(cw->ec);
4314 x = cw->ec->client.x, y = cw->ec->client.y;
4315 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4316 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4318 new_x = x, new_y = y;
4321 if (old_x != new_x || old_y != new_y)
4323 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4324 cw->y = cw->x = -99999;
4325 evas_object_move(obj, new_x, new_y);
4329 if (cw->ec->maximized)
4331 cw->ec->changes.need_maximize = 1;
4334 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4335 if (cw->frame_object)
4337 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4340 cw->frame_extends = 0;
4341 evas_object_del(pbg);
4346 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4348 E_Comp_Object_Mover *prov;
4351 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4352 edje_object_signal_emit(cw->shobj, sig, src);
4353 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4354 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4355 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4357 /* start with highest priority callback first */
4358 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4360 if (!e_util_glob_match(sig, prov->sig)) continue;
4361 if (prov->func(prov->data, obj, sig)) break;
4366 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4368 /* FIXME: at some point I guess this should use eo to inherit
4369 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4370 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4373 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4377 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4380 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4384 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4387 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4391 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4394 Eina_Rectangle rect;
4397 if (cw->ec->input_only || (!cw->updates)) return;
4398 if (cw->nocomp) return;
4399 rect.x = x, rect.y = y;
4400 rect.w = w, rect.h = h;
4401 evas_object_smart_callback_call(obj, "damage", &rect);
4403 if (e_comp_is_on_overlay(cw->ec))
4405 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4406 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4407 * E module attempts to block screen update due to the particular policy.
4409 if (e_pixmap_resource_get(cw->ec->pixmap))
4410 cw->hwc_need_update = EINA_TRUE;
4413 /* ignore overdraw */
4414 if (cw->updates_full)
4416 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4417 e_comp_object_render_update_add(obj);
4419 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4420 evas_object_show(cw->smart_obj);
4424 /* clip rect to client surface */
4425 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4426 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4427 /* if rect is the total size of the client after clip, clear the updates
4428 * since this is guaranteed to be the whole region anyway
4430 eina_tiler_area_size_get(cw->updates, &tw, &th);
4431 if ((w > tw) || (h > th))
4433 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4434 eina_tiler_clear(cw->updates);
4435 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4437 tw = cw->ec->client.w, th = cw->ec->client.h;
4439 if ((!x) && (!y) && (w == tw) && (h == th))
4441 eina_tiler_clear(cw->updates);
4442 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4443 cw->updates_full = 1;
4444 cw->update_count = 0;
4447 if (cw->update_count > UPDATE_MAX)
4449 /* this is going to get really dumb, so just update the whole thing */
4450 eina_tiler_clear(cw->updates);
4451 cw->update_count = cw->updates_full = 1;
4452 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4453 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4457 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4458 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4460 cw->updates_exist = 1;
4461 e_comp_object_render_update_add(obj);
4463 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4464 evas_object_show(cw->smart_obj);
4468 e_comp_object_damage_exists(Evas_Object *obj)
4470 API_ENTRY EINA_FALSE;
4471 return cw->updates_exist;
4475 e_comp_object_render_update_add(Evas_Object *obj)
4479 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4480 if (cw->render_update_lock.lock) return;
4481 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4485 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4487 e_comp_render_queue();
4491 e_comp_object_render_update_del(Evas_Object *obj)
4495 if (cw->ec->input_only || (!cw->updates)) return;
4496 if (!cw->update) return;
4498 /* this gets called during comp animating to clear the update flag */
4499 if (e_comp->grabbed) return;
4500 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4501 if (!e_comp->updates)
4503 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4504 if (e_comp->render_animator)
4505 ecore_animator_freeze(e_comp->render_animator);
4510 e_comp_object_shape_apply(Evas_Object *obj)
4514 unsigned int i, *pix, *p;
4518 if (!cw->ec) return; //NYI
4519 if (cw->external_content) return;
4522 if ((cw->ec->shape_rects_num >= 1) &&
4523 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4528 ERR("BUGGER: shape with native surface? cw=%p", cw);
4531 evas_object_image_size_get(cw->obj, &w, &h);
4532 if ((w < 1) || (h < 1)) return;
4535 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4536 _e_comp_object_alpha_set(cw);
4537 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4538 evas_object_image_alpha_set(o, 1);
4540 p = pix = evas_object_image_data_get(cw->obj, 1);
4543 evas_object_image_data_set(cw->obj, pix);
4548 unsigned char *spix, *sp;
4550 spix = calloc(w * h, sizeof(unsigned char));
4552 for (i = 0; i < cw->ec->shape_rects_num; i++)
4556 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4557 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4558 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4559 sp = spix + (w * ry) + rx;
4560 for (py = 0; py < rh; py++)
4562 for (px = 0; px < rw; px++)
4570 for (py = 0; py < h; py++)
4572 for (px = 0; px < w; px++)
4574 unsigned int mask, imask;
4576 mask = ((unsigned int)(*sp)) << 24;
4578 imask |= imask >> 8;
4579 imask |= imask >> 8;
4580 *p = mask | (*p & imask);
4581 //if (*sp) *p = 0xff000000 | *p;
4582 //else *p = 0x00000000;
4591 for (py = 0; py < h; py++)
4593 for (px = 0; px < w; px++)
4597 evas_object_image_data_set(cw->obj, pix);
4598 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4599 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4601 evas_object_image_data_set(o, pix);
4602 evas_object_image_data_update_add(o, 0, 0, w, h);
4604 // don't need to fix alpha chanel as blending
4605 // should be totally off here regardless of
4606 // alpha channel content
4610 _e_comp_object_clear(E_Comp_Object *cw)
4615 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4617 if (cw->render_update_lock.lock) return;
4620 e_pixmap_clear(cw->ec->pixmap);
4622 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4623 evas_object_image_size_set(cw->obj, 1, 1);
4624 evas_object_image_data_set(cw->obj, NULL);
4625 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4627 evas_object_image_size_set(o, 1, 1);
4628 evas_object_image_data_set(o, NULL);
4631 e_comp_object_render_update_del(cw->smart_obj);
4635 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4639 API_ENTRY EINA_FALSE;
4641 if (cw->transparent.set == set)
4646 evas_object_color_get(obj, &r, &g, &b, &a);
4647 evas_object_color_set(obj, 0, 0, 0, 0);
4649 cw->transparent.user_r = r;
4650 cw->transparent.user_g = g;
4651 cw->transparent.user_b = b;
4652 cw->transparent.user_a = a;
4654 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4656 cw->transparent.user_r,
4657 cw->transparent.user_g,
4658 cw->transparent.user_b,
4659 cw->transparent.user_a);
4661 cw->transparent.set = EINA_TRUE;
4665 cw->transparent.set = EINA_FALSE;
4667 evas_object_color_set(obj,
4668 cw->transparent.user_r,
4669 cw->transparent.user_g,
4670 cw->transparent.user_b,
4671 cw->transparent.user_a);
4673 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4675 cw->transparent.user_r,
4676 cw->transparent.user_g,
4677 cw->transparent.user_b,
4678 cw->transparent.user_a);
4684 /* helper function to simplify toggling of redirection for display servers which support it */
4686 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4691 if (cw->redirected == set) return;
4692 cw->redirected = set;
4693 if (cw->external_content) return;
4695 e_comp_object_map_update(obj);
4699 if (cw->updates_exist)
4700 e_comp_object_render_update_add(obj);
4702 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4704 _e_comp_object_transparent_set(obj, EINA_FALSE);
4705 evas_object_smart_callback_call(obj, "redirected", NULL);
4709 _e_comp_object_clear(cw);
4710 _e_comp_object_transparent_set(obj, EINA_TRUE);
4711 evas_object_smart_callback_call(obj, "unredirected", NULL);
4716 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4719 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4721 if (cw->buffer_destroy_listener.notify)
4723 cw->buffer_destroy_listener.notify = NULL;
4724 wl_list_remove(&cw->buffer_destroy_listener.link);
4727 if (e_object_is_del(E_OBJECT(cw->ec)))
4729 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4734 /* if it's current displaying buffer, do not remove its content */
4735 if (!evas_object_visible_get(cw->ec->frame))
4736 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4741 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4746 if (cw->buffer_destroy_listener.notify)
4748 wl_list_remove(&cw->buffer_destroy_listener.link);
4749 cw->buffer_destroy_listener.notify = NULL;
4752 if (cw->tbm_surface)
4754 tbm_surface_internal_unref(cw->tbm_surface);
4755 cw->tbm_surface = NULL;
4760 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4762 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4763 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4765 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4767 tbm_surface_internal_ref(ns->data.tbm.buffer);
4768 cw->tbm_surface = ns->data.tbm.buffer;
4772 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4773 evas_object_image_native_surface_set(cw->obj, ns);
4777 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4779 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4780 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4781 evas_object_image_native_surface_set(o, ns);
4788 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4790 Evas_Native_Surface ns;
4793 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4794 if (cw->ec->input_only) return;
4795 if (cw->external_content) return;
4796 if (cw->render_update_lock.lock) return;
4799 memset(&ns, 0, sizeof(Evas_Native_Surface));
4803 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4804 set = (!cw->ec->shaped);
4806 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4810 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4814 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4817 if (cw->ec->input_only) return;
4820 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4821 _e_comp_object_alpha_set(cw);
4823 e_comp_object_native_surface_set(obj, cw->native);
4824 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4828 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4834 if (cw->blanked == set) return;
4836 _e_comp_object_alpha_set(cw);
4839 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4840 evas_object_image_data_set(cw->obj, NULL);
4844 e_comp_object_native_surface_set(obj, 1);
4845 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4849 _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)
4854 if (!_damage_trace) return;
4858 if (!evas_object_visible_get(cw->obj)) return;
4860 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4862 o = evas_object_rectangle_add(e_comp->evas);
4863 evas_object_layer_set(o, E_LAYER_MAX);
4864 evas_object_name_set(o, "damage_trace");
4865 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4866 evas_object_resize(o, dmg_w, dmg_h);
4867 evas_object_color_set(o, 0, 128, 0, 128);
4868 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4869 evas_object_pass_events_set(o, EINA_TRUE);
4870 evas_object_show(o);
4872 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4874 dmg_w, dmg_h, dmg_x, dmg_y,
4875 origin->w, origin->h, origin->x, origin->y);
4877 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4880 /* mark an object as dirty and setup damages */
4882 e_comp_object_dirty(Evas_Object *obj)
4885 Eina_Rectangle *rect;
4889 Eina_Bool dirty, visible;
4893 if (cw->external_content) return;
4894 if (!cw->redirected) return;
4895 if (cw->render_update_lock.lock)
4897 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4900 /* only actually dirty if pixmap is available */
4901 if (!e_pixmap_resource_get(cw->ec->pixmap))
4903 // e_pixmap_size_get returns last attached buffer size
4904 // eventhough it is destroyed
4905 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4908 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4909 visible = cw->visible;
4910 if (!dirty) w = h = 1;
4911 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4913 evas_object_image_data_set(cw->obj, NULL);
4914 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4915 evas_object_image_size_set(cw->obj, tw, th);
4916 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4917 if (cw->pending_updates)
4918 eina_tiler_area_size_set(cw->pending_updates, w, h);
4919 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4921 evas_object_image_pixels_dirty_set(o, dirty);
4923 evas_object_image_data_set(o, NULL);
4924 evas_object_image_size_set(o, tw, th);
4925 visible |= evas_object_visible_get(o);
4929 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4933 e_comp_object_native_surface_set(obj, 1);
4935 m = _e_comp_object_map_damage_transform_get(cw->ec);
4936 it = eina_tiler_iterator_new(cw->updates);
4937 EINA_ITERATOR_FOREACH(it, rect)
4939 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4940 * of evas engine and doesn't convert damage according to evas_map.
4941 * so damage of evas_object_image use surface coordinate.
4945 int damage_x, damage_y, damage_w, damage_h;
4947 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4948 &damage_x, &damage_y, &damage_w, &damage_h);
4949 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4950 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4954 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4955 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4958 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4959 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4960 if (cw->pending_updates)
4961 eina_tiler_rect_add(cw->pending_updates, rect);
4963 eina_iterator_free(it);
4964 if (m) e_map_free(m);
4965 if (cw->pending_updates)
4966 eina_tiler_clear(cw->updates);
4969 cw->pending_updates = cw->updates;
4970 cw->updates = eina_tiler_new(w, h);
4971 eina_tiler_tile_size_set(cw->updates, 1, 1);
4973 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4974 evas_object_smart_callback_call(obj, "dirty", NULL);
4975 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4976 /* force render if main object is hidden but mirrors are visible */
4977 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4978 e_comp_object_render(obj);
4982 e_comp_object_render(Evas_Object *obj)
4989 API_ENTRY EINA_FALSE;
4991 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4992 if (cw->ec->input_only) return EINA_TRUE;
4993 if (cw->external_content) return EINA_TRUE;
4994 if (cw->native) return EINA_FALSE;
4995 /* if comp object is not redirected state, comp object should not be set by newly committed data
4996 because image size of comp object is 1x1 and it should not be shown on canvas */
4997 if (!cw->redirected) return EINA_TRUE;
4998 if (cw->render_update_lock.lock)
5000 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5003 e_comp_object_render_update_del(obj);
5004 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5006 if (!cw->pending_updates)
5008 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5009 evas_object_image_data_set(cw->obj, NULL);
5010 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5011 evas_object_image_data_set(o, NULL);
5015 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5017 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5019 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5022 e_pixmap_image_refresh(cw->ec->pixmap);
5023 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5026 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5027 e_pixmap_image_data_ref(cw->ec->pixmap);
5029 /* set pixel data */
5030 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5031 _e_comp_object_alpha_set(cw);
5032 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5034 evas_object_image_data_set(o, pix);
5035 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5036 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5039 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5041 e_comp_client_post_update_add(cw->ec);
5046 /* create a duplicate of an evas object */
5048 e_comp_object_util_mirror_add(Evas_Object *obj)
5052 unsigned int *pix = NULL;
5053 Eina_Bool argb = EINA_FALSE;
5058 cw = evas_object_data_get(obj, "comp_mirror");
5061 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5062 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5063 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5064 evas_object_image_alpha_set(o, 1);
5065 evas_object_image_source_set(o, obj);
5068 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5069 if (cw->external_content)
5071 ERR("%p of client %p is external content.", obj, cw->ec);
5074 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5075 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5076 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5077 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5078 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5079 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5080 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5081 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5082 evas_object_data_set(o, "comp_mirror", cw);
5084 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5085 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5087 evas_object_image_size_set(o, tw, th);
5090 pix = evas_object_image_data_get(cw->obj, 0);
5096 evas_object_image_native_surface_set(o, cw->ns);
5099 Evas_Native_Surface ns;
5100 memset(&ns, 0, sizeof(Evas_Native_Surface));
5101 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5102 evas_object_image_native_surface_set(o, &ns);
5107 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5108 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5110 (e_pixmap_image_exists(cw->ec->pixmap)))
5111 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5113 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5120 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5121 evas_object_image_pixels_dirty_set(o, dirty);
5122 evas_object_image_data_set(o, pix);
5123 evas_object_image_data_set(cw->obj, pix);
5125 evas_object_image_data_update_add(o, 0, 0, tw, th);
5130 //////////////////////////////////////////////////////
5133 e_comp_object_effect_allowed_get(Evas_Object *obj)
5135 API_ENTRY EINA_FALSE;
5137 if (!cw->shobj) return EINA_FALSE;
5138 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5139 return !e_comp_config_get()->match.disable_borders;
5142 /* setup an api effect for a client */
5144 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5147 Eina_Stringshare *grp;
5148 E_Comp_Config *config;
5149 Eina_Bool loaded = EINA_FALSE;
5151 API_ENTRY EINA_FALSE;
5152 if (!cw->shobj) return EINA_FALSE; //input window
5154 if (!effect) effect = "none";
5155 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5157 config = e_comp_config_get();
5158 if ((config) && (config->effect_file))
5160 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5162 cw->effect_set = EINA_TRUE;
5169 edje_object_file_get(cw->effect_obj, NULL, &grp);
5170 cw->effect_set = !eina_streq(effect, "none");
5171 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5172 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5174 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5175 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5176 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5178 if (cw->effect_running)
5180 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5183 cw->effect_set = EINA_FALSE;
5184 return cw->effect_set;
5188 if (cw->effect_running)
5190 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5193 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5194 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5195 if (cw->effect_clip)
5197 evas_object_clip_unset(cw->clip);
5198 cw->effect_clip = 0;
5200 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5202 _e_comp_object_dim_update(cw);
5204 return cw->effect_set;
5207 /* set params for embryo scripts in effect */
5209 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5211 Edje_Message_Int_Set *msg;
5215 EINA_SAFETY_ON_NULL_RETURN(params);
5216 EINA_SAFETY_ON_FALSE_RETURN(count);
5217 if (!cw->effect_set) return;
5219 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5220 msg->count = (int)count;
5221 for (x = 0; x < count; x++)
5222 msg->val[x] = params[x];
5223 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5224 edje_object_message_signal_process(cw->effect_obj);
5228 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5230 Edje_Signal_Cb end_cb;
5232 E_Comp_Object *cw = data;
5234 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5235 cw->effect_running = 0;
5236 if (!_e_comp_object_animating_end(cw)) return;
5238 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5240 evas_object_data_del(cw->smart_obj, "effect_running");
5241 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5242 e_comp_visibility_calculation_set(EINA_TRUE);
5245 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5246 if (!end_cb) return;
5247 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5248 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5249 end_cb(end_data, cw->smart_obj, emission, source);
5252 /* clip effect to client's zone */
5254 e_comp_object_effect_clip(Evas_Object *obj)
5258 zone = e_comp_zone_find_by_ec(cw->ec);
5260 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5261 if (!cw->effect_clip_able) return;
5262 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5263 cw->effect_clip = 1;
5266 /* unclip effect from client's zone */
5268 e_comp_object_effect_unclip(Evas_Object *obj)
5271 if (!cw->effect_clip) return;
5272 evas_object_clip_unset(cw->smart_obj);
5273 cw->effect_clip = 0;
5276 /* start effect, running end_cb after */
5278 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5280 API_ENTRY EINA_FALSE;
5281 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5282 if (!cw->effect_set) return EINA_FALSE;
5284 if (cw->effect_running)
5286 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5289 e_comp_object_effect_clip(obj);
5290 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5292 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5293 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5294 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5295 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5297 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5298 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5300 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5301 _e_comp_object_animating_begin(cw);
5302 cw->effect_running = 1;
5306 /* stop a currently-running effect immediately */
5308 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5311 Edje_Signal_Cb end_cb_before = NULL;
5312 void *end_data_before = NULL;
5313 API_ENTRY EINA_FALSE;
5315 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5316 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5318 if (end_cb_before != end_cb) return EINA_TRUE;
5319 e_comp_object_effect_unclip(obj);
5320 if (cw->effect_clip)
5322 evas_object_clip_unset(cw->effect_obj);
5323 cw->effect_clip = 0;
5325 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5326 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5328 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5330 evas_object_data_del(cw->smart_obj, "effect_running");
5331 e_comp_visibility_calculation_set(EINA_TRUE);
5334 cw->effect_running = 0;
5335 ret = _e_comp_object_animating_end(cw);
5337 if ((ret) && (end_cb_before))
5339 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5340 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5347 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5349 return a->pri - b->pri;
5352 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5353 E_API E_Comp_Object_Mover *
5354 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5356 E_Comp_Object_Mover *prov;
5358 prov = E_NEW(E_Comp_Object_Mover, 1);
5359 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5360 prov->func = provider;
5361 prov->data = (void*)data;
5364 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5365 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5370 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5372 EINA_SAFETY_ON_NULL_RETURN(prov);
5373 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5378 e_comp_object_effect_object_get(Evas_Object *obj)
5382 return cw->effect_obj;
5386 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5388 API_ENTRY EINA_FALSE;
5389 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5390 if (!cw->effect_set) return EINA_FALSE;
5397 ////////////////////////////////////
5400 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5402 if (e_comp->autoclose.obj)
5404 e_comp_ungrab_input(0, 1);
5405 if (e_comp->autoclose.del_cb)
5406 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5407 else if (!already_del)
5409 evas_object_hide(e_comp->autoclose.obj);
5410 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5412 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5414 e_comp->autoclose.obj = NULL;
5415 e_comp->autoclose.data = NULL;
5416 e_comp->autoclose.del_cb = NULL;
5417 e_comp->autoclose.key_cb = NULL;
5418 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5422 _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)
5424 _e_comp_object_autoclose_cleanup(0);
5428 _e_comp_object_autoclose_setup(Evas_Object *obj)
5430 if (!e_comp->autoclose.rect)
5432 /* create rect just below autoclose object to catch mouse events */
5433 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5434 evas_object_move(e_comp->autoclose.rect, 0, 0);
5435 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5436 evas_object_show(e_comp->autoclose.rect);
5437 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5438 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5439 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5440 e_comp_grab_input(0, 1);
5442 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5443 evas_object_focus_set(obj, 1);
5447 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5449 _e_comp_object_autoclose_setup(obj);
5450 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5454 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5456 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5457 _e_comp_object_autoclose_cleanup(1);
5458 if (e_client_focused_get()) return;
5460 E_Zone *zone = e_zone_current_get();
5463 e_zone_focus_reset(zone);
5467 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5471 if (e_comp->autoclose.obj)
5473 if (e_comp->autoclose.obj == obj) return;
5474 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5475 e_comp->autoclose.obj = obj;
5476 e_comp->autoclose.del_cb = del_cb;
5477 e_comp->autoclose.key_cb = cb;
5478 e_comp->autoclose.data = (void*)data;
5479 if (evas_object_visible_get(obj))
5480 _e_comp_object_autoclose_setup(obj);
5482 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5483 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5486 e_comp->autoclose.obj = obj;
5487 e_comp->autoclose.del_cb = del_cb;
5488 e_comp->autoclose.key_cb = cb;
5489 e_comp->autoclose.data = (void*)data;
5490 if (evas_object_visible_get(obj))
5491 _e_comp_object_autoclose_setup(obj);
5493 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5494 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5498 e_comp_object_is_animating(Evas_Object *obj)
5502 return cw->animating;
5506 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5510 if ((cw->external_content) &&
5511 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5513 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5514 "But current external content is %d object for %p.",
5515 cw->content_type, cw->ec);
5519 cw->user_alpha_set = EINA_TRUE;
5520 cw->user_alpha = alpha;
5522 if (!cw->obj) return;
5524 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5526 evas_object_image_alpha_set(cw->obj, alpha);
5528 if ((!cw->native) && (!cw->external_content))
5529 evas_object_image_data_set(cw->obj, NULL);
5533 e_comp_object_alpha_get(Evas_Object *obj)
5535 API_ENTRY EINA_FALSE;
5537 return evas_object_image_alpha_get(cw->obj);
5541 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5543 Eina_Bool mask_set = EINA_FALSE;
5547 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5548 if (cw->ec->input_only) return;
5555 o = evas_object_rectangle_add(e_comp->evas);
5556 evas_object_color_set(o, 0, 0, 0, 0);
5557 evas_object_clip_set(o, cw->clip);
5558 evas_object_smart_member_add(o, obj);
5559 evas_object_move(o, 0, 0);
5560 evas_object_resize(o, cw->w, cw->h);
5561 /* save render op value to restore when clear a mask.
5563 * NOTE: DO NOT change the render op on ec->frame while mask object
5564 * is set. it will overwrite the changed op value. */
5565 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5566 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5567 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5568 if (cw->visible) evas_object_show(o);
5571 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5572 ELOGF("COMP", " |mask_obj", cw->ec);
5573 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5580 evas_object_smart_member_del(cw->mask.obj);
5581 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5583 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5584 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5590 e_comp_object_mask_has(Evas_Object *obj)
5592 API_ENTRY EINA_FALSE;
5594 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5598 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5603 if ((cw->external_content) &&
5604 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5606 WRN("Can set up size to ONLY evas \"image\" object. "
5607 "But current external content is %d object for %p.",
5608 cw->content_type, cw->ec);
5612 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5614 evas_object_image_size_set(cw->obj, tw, th);
5618 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5620 Eina_Bool transform_set = EINA_FALSE;
5622 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5623 if (cw->ec->input_only) return;
5625 transform_set = !!set;
5629 if (!cw->transform_bg_obj)
5631 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5632 evas_object_move(o, 0, 0);
5633 evas_object_resize(o, 1, 1);
5634 if (cw->transform_bg_color.a >= 255)
5635 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5637 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5638 evas_object_color_set(o,
5639 cw->transform_bg_color.r,
5640 cw->transform_bg_color.g,
5641 cw->transform_bg_color.b,
5642 cw->transform_bg_color.a);
5643 if (cw->visible) evas_object_show(o);
5645 cw->transform_bg_obj = o;
5646 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5648 _e_comp_object_transform_obj_stack_update(obj);
5652 if (cw->transform_bg_obj)
5654 evas_object_smart_member_del(cw->transform_bg_obj);
5655 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5661 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5665 cw->transform_bg_color.r = r;
5666 cw->transform_bg_color.g = g;
5667 cw->transform_bg_color.b = b;
5668 cw->transform_bg_color.a = a;
5670 if (cw->transform_bg_obj)
5672 evas_object_color_set(cw->transform_bg_obj,
5673 cw->transform_bg_color.r,
5674 cw->transform_bg_color.g,
5675 cw->transform_bg_color.b,
5676 cw->transform_bg_color.a);
5681 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5684 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5685 if (cw->ec->input_only) return;
5686 if (!cw->transform_bg_obj) return;
5688 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5692 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5695 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5696 if (cw->ec->input_only) return;
5697 if (!cw->transform_bg_obj) return;
5699 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5703 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5705 Eina_Bool transform_set = EINA_FALSE;
5707 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5708 if (cw->ec->input_only) return;
5710 transform_set = !!set;
5714 if (!cw->transform_tranp_obj)
5716 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5717 evas_object_move(o, 0, 0);
5718 evas_object_resize(o, 1, 1);
5719 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5720 evas_object_color_set(o, 0, 0, 0, 0);
5721 if (cw->visible) evas_object_show(o);
5723 cw->transform_tranp_obj = o;
5724 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5725 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5726 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5728 _e_comp_object_transform_obj_stack_update(obj);
5732 if (cw->transform_tranp_obj)
5734 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5735 evas_object_smart_member_del(cw->transform_tranp_obj);
5736 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5742 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5745 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5746 if (cw->ec->input_only) return;
5747 if (!cw->transform_tranp_obj) return;
5749 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5753 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5756 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5757 if (cw->ec->input_only) return;
5758 if (!cw->transform_tranp_obj) return;
5760 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5763 #ifdef REFACTOR_DESK_AREA
5766 e_comp_object_layer_update(Evas_Object *obj,
5767 Evas_Object *above, Evas_Object *below)
5769 E_Comp_Object *cw2 = NULL;
5770 Evas_Object *o = NULL;
5775 if (cw->ec->layer_block) return;
5776 if ((above) && (below))
5778 ERR("Invalid layer update request! cw=%p", cw);
5786 layer = evas_object_layer_get(o);
5787 cw2 = evas_object_data_get(o, "comp_obj");
5790 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5792 o = evas_object_above_get(o);
5793 if ((!o) || (o == cw->smart_obj)) break;
5794 if (evas_object_layer_get(o) != layer)
5796 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5801 ec = e_client_top_get();
5802 if (ec) o = ec->frame;
5805 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5809 _e_comp_object_layers_remove(cw);
5812 if (cw2->layer > cw->layer)
5813 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5814 else if (cw2->layer == cw->layer)
5817 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5819 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5821 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5824 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5827 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5832 e_comp_object_layer_get(Evas_Object *obj)
5839 e_comp_object_content_set(Evas_Object *obj,
5840 Evas_Object *content,
5841 E_Comp_Object_Content_Type type)
5843 API_ENTRY EINA_FALSE;
5845 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5846 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5847 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5851 ERR("Can't set e.swallow.content to requested content. "
5852 "Previous comp object should not be changed at all.");
5856 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5858 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5859 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5861 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5862 type, content, cw->ec, cw->ec->pixmap);
5866 cw->external_content = EINA_TRUE;
5869 cw->content_type = type;
5870 e_util_size_debug_set(cw->obj, 1);
5871 evas_object_name_set(cw->obj, "cw->obj");
5872 _e_comp_object_alpha_set(cw);
5875 _e_comp_object_shadow_setup(cw);
5881 e_comp_object_content_unset(Evas_Object *obj)
5883 API_ENTRY EINA_FALSE;
5885 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5886 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5888 if (!cw->obj && !cw->ec->visible)
5890 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5894 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5896 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5902 if (cw->frame_object)
5903 edje_object_part_unswallow(cw->frame_object, cw->obj);
5905 edje_object_part_unswallow(cw->shobj, cw->obj);
5907 evas_object_del(cw->obj);
5908 evas_object_hide(cw->obj);
5912 cw->external_content = EINA_FALSE;
5913 if (cw->ec->is_cursor)
5916 DBG("%p is cursor surface..", cw->ec);
5917 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5919 evas_object_resize(cw->ec->frame, pw, ph);
5920 evas_object_hide(cw->ec->frame);
5925 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5926 cw->obj = evas_object_image_filled_add(e_comp->evas);
5927 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5928 e_util_size_debug_set(cw->obj, 1);
5929 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5930 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5931 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5932 evas_object_name_set(cw->obj, "cw->obj");
5933 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5934 _e_comp_object_alpha_set(cw);
5937 _e_comp_object_shadow_setup(cw);
5942 _e_comp_intercept_show_helper(cw);
5946 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5947 e_comp_object_dirty(cw->smart_obj);
5948 e_comp_object_render(cw->smart_obj);
5949 e_comp_object_render_update_add(obj);
5954 EINTERN Evas_Object *
5955 e_comp_object_content_get(Evas_Object *obj)
5959 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5961 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5963 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5970 E_API E_Comp_Object_Content_Type
5971 e_comp_object_content_type_get(Evas_Object *obj)
5973 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5975 return cw->content_type;
5979 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5982 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5983 E_Comp_Config *conf = e_comp_config_get();
5984 if (cw->ec->input_only) return;
5985 if (!conf->dim_rect_enable) return;
5987 cw->dim.mask_set = mask_set;
5993 if (!cw->dim.enable) return;
5994 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5998 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6000 Eina_Bool mask_set = EINA_FALSE;
6004 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6005 E_Comp_Config *conf = e_comp_config_get();
6006 if (cw->ec->input_only) return;
6007 if (!conf->dim_rect_enable) return;
6013 if (cw->dim.mask_obj)
6015 evas_object_smart_member_del(cw->dim.mask_obj);
6016 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6019 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);
6020 o = evas_object_rectangle_add(e_comp->evas);
6021 evas_object_color_set(o, 0, 0, 0, 0);
6022 evas_object_smart_member_add(o, obj);
6023 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6024 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6026 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6027 if (cw->visible) evas_object_show(o);
6029 cw->dim.mask_obj = o;
6030 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6032 evas_object_layer_set(cw->dim.mask_obj, 9998);
6036 if (cw->dim.mask_obj)
6038 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6039 evas_object_smart_member_del(cw->dim.mask_obj);
6040 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6046 e_comp_object_dim_client_set(E_Client *ec)
6048 E_Comp_Config *conf = e_comp_config_get();
6050 if (!conf->dim_rect_enable) return ;
6051 if (dim_client == ec) return;
6053 Eina_Bool prev_dim = EINA_FALSE;
6054 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6056 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6057 prev_dim = EINA_TRUE;
6059 if (prev_dim && dim_client->visible && ec)
6061 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6062 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6066 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6067 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6073 e_comp_object_dim_client_get(void)
6075 E_Comp_Config *conf = e_comp_config_get();
6077 if (!conf->dim_rect_enable ) return NULL;
6083 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6086 char emit[32] = "\0";
6087 E_Comp_Config *conf = e_comp_config_get();
6090 if (!conf->dim_rect_enable) return;
6091 if (!cw->effect_obj) return;
6092 if (enable == cw->dim.enable) return;
6094 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6095 if (noeffect || !conf->dim_rect_effect)
6097 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6101 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6104 cw->dim.enable = enable;
6106 if (cw->dim.mask_set && !enable)
6108 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6109 edje_object_signal_emit(cw->effect_obj, emit, "e");
6111 else if (cw->dim.mask_set && enable)
6113 edje_object_signal_emit(cw->effect_obj, emit, "e");
6114 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6118 edje_object_signal_emit(cw->effect_obj, emit, "e");
6123 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6125 API_ENTRY EINA_FALSE;
6126 E_Comp_Config *conf = e_comp_config_get();
6128 if (!ec) return EINA_FALSE;
6129 if (!conf->dim_rect_enable) return EINA_FALSE;
6131 if (cw->dim.enable) return EINA_TRUE;
6137 _e_comp_object_dim_update(E_Comp_Object *cw)
6139 E_Comp_Config *conf = e_comp_config_get();
6142 if (!conf->dim_rect_enable) return;
6143 if (!cw->effect_obj) return;
6146 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6147 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6149 if (cw->dim.mask_set)
6151 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6157 e_comp_object_clear(Evas_Object *obj)
6161 _e_comp_object_clear(cw);
6165 e_comp_object_hwc_update_exists(Evas_Object *obj)
6167 API_ENTRY EINA_FALSE;
6168 return cw->hwc_need_update;
6173 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6176 cw->hwc_need_update = set;
6180 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6182 API_ENTRY EINA_FALSE;
6183 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6187 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6190 if (cw->indicator.obj != indicator)
6191 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6192 cw->indicator.obj = indicator;
6193 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6197 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6200 if (cw->indicator.obj != indicator) return;
6201 cw->indicator.obj = NULL;
6202 edje_object_part_unswallow(cw->shobj, indicator);
6206 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6209 Edje_Message_Int_Set *msg;
6211 if (!cw->indicator.obj) return;
6213 cw->indicator.w = w;
6214 cw->indicator.h = h;
6216 if (!cw->shobj) return;
6218 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6222 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6223 edje_object_message_signal_process(cw->shobj);
6226 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6228 e_comp_object_map_update(Evas_Object *obj)
6231 E_Client *ec = cw->ec;
6232 E_Comp_Wl_Client_Data *cdata;
6234 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6237 int l, remain = sizeof buffer;
6240 if (e_object_is_del(E_OBJECT(ec))) return;
6241 cdata = e_client_cdata_get(ec);
6244 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6245 * when new buffer is attached.
6247 if (!cdata->buffer_ref.buffer) return;
6249 if ((!cw->redirected) ||
6250 (e_client_video_hw_composition_check(ec)) ||
6251 (!e_comp_wl_output_buffer_transform_get(ec) &&
6252 cdata->scaler.buffer_viewport.buffer.scale == 1))
6254 if (evas_object_map_enable_get(cw->effect_obj))
6256 ELOGF("TRANSFORM", "map: disable", cw->ec);
6257 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6258 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6259 evas_object_resize(cw->effect_obj, tw, th);
6266 EINA_SAFETY_ON_NULL_RETURN(map);
6268 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6274 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6276 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6277 e_map_point_image_uv_set(map, 0, x, y);
6278 l = snprintf(p, remain, "%d,%d", x, y);
6279 p += l, remain -= l;
6281 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6282 e_map_point_image_uv_set(map, 1, x, y);
6283 l = snprintf(p, remain, " %d,%d", x, y);
6284 p += l, remain -= l;
6286 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6287 e_map_point_image_uv_set(map, 2, x, y);
6288 l = snprintf(p, remain, " %d,%d", x, y);
6289 p += l, remain -= l;
6291 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6292 e_map_point_image_uv_set(map, 3, x, y);
6293 l = snprintf(p, remain, " %d,%d", x, y);
6294 p += l, remain -= l;
6296 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6298 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6300 e_comp_object_map_set(cw->effect_obj, map);
6301 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6305 /* if there's screen rotation with comp mode, then ec->effect_obj and
6306 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6308 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6309 evas_object_resize(cw->effect_obj, tw, th);
6313 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6315 API_ENTRY EINA_FALSE;
6317 cw->render_trace = set;
6323 e_comp_object_native_usable_get(Evas_Object *obj)
6325 API_ENTRY EINA_FALSE;
6326 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6328 if (cw->ec->input_only) return EINA_FALSE;
6329 if (cw->external_content) return EINA_FALSE;
6330 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6332 /* just return true value, if it is normal case */
6333 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6336 Evas_Native_Surface *ns;
6337 ns = evas_object_image_native_surface_get(cw->obj);
6339 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6342 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6350 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6352 API_ENTRY EINA_FALSE;
6353 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6354 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6355 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6359 case E_COMP_IMAGE_FILTER_BLUR:
6360 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6362 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6363 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6365 case E_COMP_IMAGE_FILTER_INVERSE:
6366 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6368 case E_COMP_IMAGE_FILTER_NONE:
6370 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6374 cw->image_filter = filter;
6379 EINTERN E_Comp_Image_Filter
6380 e_comp_object_image_filter_get(Evas_Object *obj)
6382 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6383 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6384 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6385 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6387 return cw->image_filter;
6391 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6395 if (!_damage_trace) return;
6397 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6398 evas_object_del(obj);
6400 _damage_trace_post_objs = NULL;
6404 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6406 if (!_damage_trace) return;
6408 _damage_trace_post_objs = _damage_trace_objs;
6409 _damage_trace_objs = NULL;
6413 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6415 if (_damage_trace == onoff) return;
6419 evas_event_callback_add(e_comp->evas,
6420 EVAS_CALLBACK_RENDER_PRE,
6421 _e_comp_object_damage_trace_render_pre_cb,
6424 evas_event_callback_add(e_comp->evas,
6425 EVAS_CALLBACK_RENDER_POST,
6426 _e_comp_object_damage_trace_render_post_cb,
6433 EINA_LIST_FREE(_damage_trace_objs, obj)
6434 evas_object_del(obj);
6436 _damage_trace_objs = NULL;
6438 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6439 evas_object_del(obj);
6441 _damage_trace_post_objs = NULL;
6443 evas_event_callback_del(e_comp->evas,
6444 EVAS_CALLBACK_RENDER_PRE,
6445 _e_comp_object_damage_trace_render_pre_cb);
6447 evas_event_callback_del(e_comp->evas,
6448 EVAS_CALLBACK_RENDER_POST,
6449 _e_comp_object_damage_trace_render_post_cb);
6452 _damage_trace = onoff;
6456 e_comp_object_redirected_get(Evas_Object *obj)
6458 API_ENTRY EINA_FALSE;
6459 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6461 return cw->redirected;
6465 e_comp_object_color_visible_get(Evas_Object *obj)
6467 API_ENTRY EINA_FALSE;
6470 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6472 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6476 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6480 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6484 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6492 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6494 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6496 return e_map_set_to_comp_object(em, obj);
6500 e_comp_object_map_get(const Evas_Object *obj)
6502 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6504 return e_map_get_from_comp_object(obj);
6508 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6510 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6512 evas_object_map_enable_set(obj, enable);
6518 e_comp_object_render_update_lock(Evas_Object *obj)
6520 E_Comp_Wl_Buffer *buffer;
6521 struct wayland_tbm_client_queue *cqueue;
6523 API_ENTRY EINA_FALSE;
6525 if (cw->render_update_lock.lock == 0)
6527 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6529 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6530 if ((buffer) && (buffer->resource))
6532 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6534 wayland_tbm_server_client_queue_flush(cqueue);
6537 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6538 e_comp_object_render_update_del(obj);
6540 ELOGF("COMP", "Render update lock enabled", cw->ec);
6543 cw->render_update_lock.lock++;
6549 e_comp_object_render_update_unlock(Evas_Object *obj)
6553 if (cw->render_update_lock.lock == 0)
6556 cw->render_update_lock.lock--;
6558 if (cw->render_update_lock.lock == 0)
6561 if (cw->render_update_lock.pending_move_set)
6563 evas_object_move(obj,
6564 cw->render_update_lock.pending_move_x,
6565 cw->render_update_lock.pending_move_y);
6566 cw->render_update_lock.pending_move_x = 0;
6567 cw->render_update_lock.pending_move_y = 0;
6568 cw->render_update_lock.pending_move_set = EINA_FALSE;
6571 if (cw->render_update_lock.pending_resize_set)
6573 evas_object_resize(obj,
6574 cw->render_update_lock.pending_resize_w,
6575 cw->render_update_lock.pending_resize_h);
6576 cw->render_update_lock.pending_resize_w = 0;
6577 cw->render_update_lock.pending_resize_h = 0;
6578 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6581 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6583 if ((cw->ec->exp_iconify.buffer_flush) &&
6584 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6585 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6586 e_comp_object_clear(obj);
6588 e_comp_object_render_update_add(obj);
6590 ELOGF("COMP", "Render update lock disabled", cw->ec);
6595 e_comp_object_render_update_lock_get(Evas_Object *obj)
6597 API_ENTRY EINA_FALSE;
6599 if (cw->render_update_lock.lock > 0)
6606 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6610 if (cw->transparent.set)
6612 if (r) *r = cw->transparent.user_r;
6613 if (g) *g = cw->transparent.user_g;
6614 if (b) *b = cw->transparent.user_b;
6615 if (a) *a = cw->transparent.user_a;
6619 evas_object_color_get(obj, r, g, b, a);
6624 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6628 evas_object_render_op_set(cw->obj, op);
6631 EINTERN Evas_Render_Op
6632 e_comp_object_render_op_get(Evas_Object *obj)
6634 API_ENTRY EVAS_RENDER_BLEND;
6636 return evas_object_render_op_get(cw->obj);
6640 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6643 wl_signal_add(&cw->events.lower, listener);
6646 #ifdef REFACTOR_DESK_AREA
6648 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6651 wl_signal_add(&cw->events.lower_done, listener);
6655 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6658 wl_signal_add(&cw->events.raise, listener);
6663 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6666 wl_signal_add(&cw->events.show, listener);
6670 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6673 wl_signal_add(&cw->events.hide, listener);
6676 #ifdef REFACTOR_DESK_AREA
6678 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6681 wl_signal_add(&cw->events.set_layer, listener);
6685 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6688 wl_signal_add(&cw->events.stack_above, listener);
6692 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6695 wl_signal_add(&cw->events.stack_below, listener);