5 = keys that return objects =
6 - E_Client: the client associated with the object (E_Client*)
7 - comp_smart_obj: cw->smart_obj (Evas_Object*)
8 - comp_obj: cw (E_Comp_Object*)
10 = keys that are bool flags =
11 - client_restack: client needs a protocol-level restack
12 - comp_override: object is triggering a nocomp override to force compositing
13 - comp_ref: object has a ref from visibility animations
14 - comp_showing: object is currently running its show animation
15 - comp_hiding: object is currently running its hiding animation
16 - comp_object: object is a compositor-created object
17 - comp_object_skip: object has a name which prohibits theme shadows
18 - comp_object-to_del: list of objects which will be deleted when this object is deleted
19 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
20 - effect_running: object is animating by external module
23 #define UPDATE_MAX 512 // same as evas
24 #define FAILURE_MAX 2 // seems reasonable
25 #define SMART_NAME "e_comp_object"
26 #define INPUT_OBJ_SMART_NAME "input_object"
28 /* for non-util functions */
29 #define API_ENTRY E_Comp_Object *cw; \
30 cw = evas_object_smart_data_get(obj); \
31 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
33 /* for util functions (obj may or may not be E_Comp_Object */
34 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
37 CRI("YOU PASSED NULL! ARGH!"); \
40 cw = evas_object_smart_data_get(obj); \
41 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
43 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
45 /* enable for lots of client size info in console output */
47 # define e_util_size_debug_set(x, y)
50 /* enable along with display-specific damage INF calls to enable render tracing
54 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
56 #define RENDER_DEBUG(...)
59 typedef struct _E_Comp_Object
63 int x, y, w, h; // geometry
67 E_Comp_Object_Frame client_inset;
69 Eina_Stringshare *frame_theme;
70 Eina_Stringshare *frame_name;
71 Eina_Stringshare *visibility_effect; //effect when toggling visibility
73 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
75 Evas_Object *smart_obj; // smart object
76 Evas_Object *clip; // clipper over effect object
77 Evas_Object *input_obj; // input smart object
78 Evas_Object *obj; // composite object
79 Evas_Object *frame_object; // for client frames
80 Evas_Object *shobj; // shadow object
81 Evas_Object *effect_obj; // effects object
82 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
87 Evas_Object *transform_tranp_obj;// transform transp rect obj
88 Evas_Object *default_input_obj; // default input object
89 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
90 Eina_List *obj_mirror; // extra mirror objects
91 Eina_Tiler *updates; //render update regions
92 Eina_Tiler *pending_updates; //render update regions which are about to render
94 Evas_Native_Surface *ns; //for custom gl rendering
96 struct wl_listener buffer_destroy_listener;
98 unsigned int update_count; // how many updates have happened to this obj
100 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
102 unsigned int animating; // it's busy animating
103 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
104 unsigned int force_visible; //number of visible obj_mirror objects
105 Eina_Bool delete_pending : 1; // delete pending
106 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
107 Eina_Bool showing : 1; // object is currently in "show" animation
108 Eina_Bool hiding : 1; // object is currently in "hide" animation
109 Eina_Bool visible : 1; // is visible
111 Eina_Bool shaped : 1; // is shaped
112 Eina_Bool update : 1; // has updates to fetch
113 Eina_Bool redirected : 1; // has updates to fetch
114 Eina_Bool native : 1; // native
116 Eina_Bool nocomp : 1; // nocomp applied
117 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
118 Eina_Bool real_hid : 1; // last hide was a real window unmap
120 Eina_Bool effect_set : 1; //effect_obj has a valid group
121 Eina_Bool effect_running : 1; //effect_obj is playing an animation
122 Eina_Bool effect_clip : 1; //effect_obj is clipped
123 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
125 Eina_Bool updates_exist : 1;
126 Eina_Bool updates_full : 1; // entire object will be updated
128 Eina_Bool force_move : 1;
129 Eina_Bool frame_extends : 1; //frame may extend beyond object size
130 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
131 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
132 Eina_Bool user_alpha_set : 1;
133 Eina_Bool user_alpha : 1;
137 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
138 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
145 } indicator; //indicator object for internal client
149 Evas_Object *mask_obj;
152 int mask_x, mask_y, mask_w, mask_h;
155 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
157 tbm_surface_h tbm_surface;
158 E_Comp_Image_Filter image_filter;
159 Eina_Bool set_mouse_callbacks;
164 E_Comp_Wl_Buffer_Ref buffer_ref;
165 Eina_Bool pending_move_set;
166 int pending_move_x, pending_move_y;
167 Eina_Bool pending_resize_set;
168 int pending_resize_w, pending_resize_h;
169 } render_update_lock;
182 struct wl_signal lower;
183 struct wl_signal show;
184 struct wl_signal hide;
188 typedef struct _E_Input_Rect_Data
194 typedef struct _E_Input_Rect_Smart_Data
196 Eina_List *input_rect_data_list;
198 } E_Input_Rect_Smart_Data;
200 struct E_Comp_Object_Mover
203 E_Comp_Object_Mover_Cb func;
209 static Eina_Inlist *_e_comp_object_movers = NULL;
210 static Evas_Smart *_e_comp_smart = NULL;
211 static Evas_Smart *_e_comp_input_obj_smart = NULL;
213 static int _e_comp_object_hooks_delete = 0;
214 static int _e_comp_object_hooks_walking = 0;
216 static Eina_Inlist *_e_comp_object_hooks[] =
218 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
219 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
220 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
221 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
222 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
223 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
225 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
228 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
229 static int _e_comp_object_intercept_hooks_delete = 0;
230 static int _e_comp_object_intercept_hooks_walking = 0;
232 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
234 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
235 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
239 static Eina_Bool _damage_trace = EINA_FALSE;
240 static Eina_List *_damage_trace_objs = NULL;
241 static Eina_List *_damage_trace_post_objs = NULL;
243 /* sekrit functionzzz */
244 EINTERN void e_client_focused_set(E_Client *ec);
246 /* emitted every time a new noteworthy comp object is added */
247 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
249 /* ecore event define */
250 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
251 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
252 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
254 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
255 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
256 static void _e_comp_object_dim_update(E_Comp_Object *cw);
257 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
258 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
260 static E_Client *dim_client = NULL;
263 _e_comp_object_hooks_clean(void)
266 E_Comp_Object_Hook *ch;
269 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
270 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
272 if (!ch->delete_me) continue;
273 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
279 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
281 E_Comp_Object_Hook *ch;
282 Eina_Bool ret = EINA_TRUE;
284 if (e_object_is_del(E_OBJECT(ec)))
286 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
287 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
288 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
289 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
290 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
299 e_object_ref(E_OBJECT(ec));
300 _e_comp_object_hooks_walking++;
301 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
303 if (ch->delete_me) continue;
304 if (!(ch->func(ch->data, ec)))
310 _e_comp_object_hooks_walking--;
311 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
312 _e_comp_object_hooks_clean();
314 e_object_unref(E_OBJECT(ec));
319 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
321 _e_comp_object_intercept_hooks_clean(void)
324 E_Comp_Object_Intercept_Hook *ch;
327 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
328 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
330 if (!ch->delete_me) continue;
331 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
337 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
339 E_Comp_Object_Intercept_Hook *ch;
340 Eina_Bool ret = EINA_TRUE;
342 if (e_object_is_del(E_OBJECT(ec))) return ret;
343 e_object_ref(E_OBJECT(ec));
344 _e_comp_object_intercept_hooks_walking++;
345 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
347 if (ch->delete_me) continue;
348 if (!(ch->func(ch->data, ec)))
354 _e_comp_object_intercept_hooks_walking--;
355 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
356 _e_comp_object_intercept_hooks_clean();
358 e_object_unref(E_OBJECT(ec));
365 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
367 E_Event_Comp_Object *ev = event;
370 ec = evas_object_data_get(ev->comp_object, "E_Client");
374 e_object_unref(E_OBJECT(ec));
376 evas_object_unref(ev->comp_object);
381 _e_comp_object_event_add(Evas_Object *obj)
383 E_Event_Comp_Object *ev;
386 if (stopping) return;
387 ev = E_NEW(E_Event_Comp_Object, 1);
388 EINA_SAFETY_ON_NULL_RETURN(ev);
390 evas_object_ref(obj);
391 ev->comp_object = obj;
392 ec = evas_object_data_get(ev->comp_object, "E_Client");
396 e_object_ref(E_OBJECT(ec));
398 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
402 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
404 E_Event_Comp_Object *ev = event;
407 ec = evas_object_data_get(ev->comp_object, "E_Client");
411 e_object_unref(E_OBJECT(ec));
413 evas_object_unref(ev->comp_object);
418 _e_comp_object_event_simple(Evas_Object *obj, int type)
420 E_Event_Comp_Object *ev;
423 ev = E_NEW(E_Event_Comp_Object, 1);
426 evas_object_ref(obj);
427 ev->comp_object = obj;
428 ec = evas_object_data_get(ev->comp_object, "E_Client");
432 e_object_ref(E_OBJECT(ec));
434 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
436 /////////////////////////////////////
439 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
441 E_Comp_Object *cw = data;
443 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
447 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
452 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
455 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
456 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
460 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
462 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
469 /////////////////////////////////////
472 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
477 if (cw->ec->input_only) return;
479 layer = evas_object_layer_get(obj);
481 if (cw->transform_bg_obj)
483 if (layer != evas_object_layer_get(cw->transform_bg_obj))
485 evas_object_layer_set(cw->transform_bg_obj, layer);
488 evas_object_stack_below(cw->transform_bg_obj, obj);
491 if (cw->transform_tranp_obj)
493 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
495 evas_object_layer_set(cw->transform_tranp_obj, layer);
498 evas_object_stack_below(cw->transform_tranp_obj, obj);
503 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
510 if (!map) return NULL;
512 e_map_util_points_populate_from_object_full(map, obj, 0);
513 e_map_util_points_color_set(map, 255, 255, 255, 255);
515 for (i = 0 ; i < 4 ; ++i)
520 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
521 e_map_point_coord_set(map, i, x, y, 1.0);
528 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
537 e_comp_object_map_set(obj, map);
538 e_comp_object_map_enable_set(obj, EINA_TRUE);
545 evas_object_map_enable_set(obj, EINA_FALSE);
550 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
561 e_comp_object_map_set(obj, map);
562 e_comp_object_map_enable_set(obj, EINA_TRUE);
569 evas_object_map_enable_set(obj, EINA_FALSE);
572 /////////////////////////////////////
574 static inline Eina_Bool
575 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
577 if (num > 1) return EINA_TRUE;
578 if ((rects[0].x == 0) && (rects[0].y == 0) &&
579 ((int)rects[0].w == w) && ((int)rects[0].h == h))
584 /////////////////////////////////////
586 /* add a client to the layer-client list */
588 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
590 g_rec_mutex_lock(&e_comp->ec_list_mutex);
593 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));
595 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));
596 if ((!above) && (!below))
599 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
600 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
601 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
603 e_comp->layers[cw->layer].clients_count++;
605 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
609 _e_comp_object_layers_remove(E_Comp_Object *cw)
611 g_rec_mutex_lock(&e_comp->ec_list_mutex);
613 if (cw->ec && e_comp->layers[cw->layer].clients)
615 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
616 e_comp->layers[cw->layer].clients_count--;
619 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
622 /////////////////////////////////////
624 _e_comp_object_alpha_set(E_Comp_Object *cw)
626 Eina_Bool alpha = cw->ec->argb;
628 if ((cw->external_content) &&
629 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
634 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
635 if (cw->user_alpha_set) alpha = cw->user_alpha;
637 evas_object_image_alpha_set(cw->obj, alpha);
641 _e_comp_object_shadow(E_Comp_Object *cw)
643 if (e_client_util_shadow_state_get(cw->ec))
644 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
646 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
647 if (cw->frame_object)
648 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
649 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
652 /* convert from the surface coordinates to the buffer coordinates */
654 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
656 E_Comp_Wl_Buffer_Viewport *vp;
657 E_Comp_Wl_Client_Data *cdata;
661 cdata = e_client_cdata_get(ec);
663 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
670 vp = &cdata->scaler.buffer_viewport;
671 transform = e_comp_wl_output_buffer_transform_get(ec);
673 e_pixmap_size_get(ec->pixmap, &bw, &bh);
675 /* for subsurface, it should be swap 90 and 270 */
676 if (e_comp_wl_subsurface_check(ec))
679 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
680 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
681 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
682 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
688 case WL_OUTPUT_TRANSFORM_NORMAL:
689 default: tx = sx, ty = sy; break;
690 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
691 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
692 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
693 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
694 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
695 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
696 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
699 tx *= vp->buffer.scale;
700 ty *= vp->buffer.scale;
707 _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)
715 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
716 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
723 if (dw) *dw = MAX(x1, x2) - mx;
724 if (dh) *dh = MAX(y1, y2) - my;
728 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
729 int *dx, int *dy, int *dw, int *dh)
731 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
732 E_Util_Transform_Rect_Vertex sv, dv;
736 e_pixmap_size_get(ec->pixmap, &bw, &bh);
738 sv = e_util_transform_rect_to_vertices(&rect);
740 for (i = 0; i < 4; i++)
742 double x = 0.0, y = 0.0;
744 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
746 /* if evas decide coordinate is outside of map, it returns (0, 0)
747 in this case, full damage is added.
749 if ((i != 0) && (x == 0.0) && (y == 0.0))
752 dv.vertices[i].vertex[0] = x;
753 dv.vertices[i].vertex[1] = y;
754 dv.vertices[i].vertex[2] = 1.0;
755 dv.vertices[i].vertex[3] = 1.0;
758 rect = e_util_transform_vertices_to_rect(&dv);
760 if (dx) *dx = rect.x;
761 if (dy) *dy = rect.y;
762 if (dw) *dw = rect.w;
763 if (dh) *dh = rect.h;
777 _e_comp_object_map_damage_transform_get(E_Client *ec)
784 if (!e_client_transform_core_enable_get(ec))
787 m = e_client_map_get(ec);
791 e_pixmap_size_get(ec->pixmap, &bw, &bh);
792 if ((bw == 0) || (bh == 0))
805 e_map_point_coord_set(m2, 0, 0, 0, 0);
806 e_map_point_coord_set(m2, 1, bw, 0, 0);
807 e_map_point_coord_set(m2, 2, bw, bh, 0);
808 e_map_point_coord_set(m2, 3, 0, bh, 0);
810 for (i = 0; i < 4; i++)
814 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
815 e_map_point_image_uv_set(m2, i, map_x, map_y);
822 /////////////////////////////////////
824 /* handle evas mouse-in events on client object */
826 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
828 Evas_Event_Mouse_In *ev = event_info;
829 E_Comp_Object *cw = data;
831 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
834 /* handle evas mouse-out events on client object */
836 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
838 Evas_Event_Mouse_Out *ev = event_info;
839 E_Comp_Object *cw = data;
841 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
844 /* handle evas mouse wheel events on client object */
846 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
848 Evas_Event_Mouse_Wheel *ev = event_info;
849 E_Comp_Object *cw = data;
850 E_Binding_Event_Wheel ev2;
853 if (e_client_action_get()) return;
854 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
855 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
858 /* handle evas mouse down events on client object */
860 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
862 Evas_Event_Mouse_Down *ev = event_info;
863 E_Comp_Object *cw = data;
864 E_Binding_Event_Mouse_Button ev2;
867 if (e_client_action_get()) return;
868 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
869 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
872 /* handle evas mouse up events on client object */
874 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
876 Evas_Event_Mouse_Up *ev = event_info;
877 E_Comp_Object *cw = data;
878 E_Binding_Event_Mouse_Button ev2;
881 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
882 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
883 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
886 /* handle evas mouse movement events on client object */
888 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
890 Evas_Event_Mouse_Move *ev = event_info;
891 E_Comp_Object *cw = data;
894 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
895 e_client_mouse_move(cw->ec, &ev->cur.output);
897 /////////////////////////////////////
899 /* helper function for checking compositor themes based on user-defined matches */
901 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
903 if (((m->title) && (!ec->netwm.name)) ||
904 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
906 #if defined(__cplusplus) || defined(c_plusplus)
907 if (((m->clas) && (!ec->icccm.cpp_class)) ||
908 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
911 if (((m->clas) && (!ec->icccm.class)) ||
912 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
916 if (((m->role) && (!ec->icccm.window_role)) ||
917 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
923 if ((int)ec->netwm.type != m->primary_type)
926 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
929 if (m->borderless != 0)
933 if (e_client_util_borderless(ec))
935 if (!(((m->borderless == -1) && (!borderless)) ||
936 ((m->borderless == 1) && (borderless))))
943 if (((ec->icccm.transient_for != 0) ||
946 if (!(((m->dialog == -1) && (!dialog)) ||
947 ((m->dialog == 1) && (dialog))))
950 if (m->accepts_focus != 0)
952 int accepts_focus = 0;
954 if (ec->icccm.accepts_focus)
956 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
957 ((m->accepts_focus == 1) && (accepts_focus))))
966 if (!(((m->vkbd == -1) && (!vkbd)) ||
967 ((m->vkbd == 1) && (vkbd))))
972 if (!(((m->argb == -1) && (!ec->argb)) ||
973 ((m->argb == 1) && (ec->argb))))
976 if (m->fullscreen != 0)
978 int fullscreen = ec->fullscreen;
980 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
981 ((m->fullscreen == 1) && (fullscreen))))
986 if (!(m->modal == -1))
992 /* function for setting up a client's compositor frame theme (cw->shobj) */
994 _e_comp_object_shadow_setup(E_Comp_Object *cw)
998 Eina_List *list = NULL, *l;
999 E_Input_Rect_Data *input_rect_data;
1000 E_Input_Rect_Smart_Data *input_rect_sd;
1002 Eina_Stringshare *reshadow_group = NULL;
1003 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1004 Eina_Stringshare *name, *title;
1005 E_Comp_Config *conf = e_comp_config_get();
1007 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1008 /* match correct client type */
1009 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1010 name = cw->ec->icccm.name;
1011 title = cw->ec->icccm.title;
1012 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1013 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1015 /* skipping here is mostly a hack for systray because I hate it */
1018 EINA_LIST_FOREACH(list, l, m)
1020 if (((m->name) && (!name)) ||
1021 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1023 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1027 no_shadow = m->no_shadow;
1028 if (m->shadow_style)
1030 /* fast effects are just themes with "/fast" appended and shorter effect times */
1033 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1034 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1036 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1038 /* default to non-fast style if fast not available */
1041 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1042 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1044 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1046 if (ok && m->visibility_effect)
1047 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1054 if (skip || (cw->ec->e.state.video))
1056 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1058 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1061 if (conf->shadow_style)
1065 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1066 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1068 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1082 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1084 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1088 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1090 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1095 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1100 if (cw->ec->override)
1102 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1103 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1105 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1106 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1112 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1113 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1116 _e_comp_object_shadow(cw);
1119 if (focus || cw->ec->focused || cw->ec->override)
1120 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1122 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1123 if (urgent || cw->ec->urgent)
1124 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1126 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1128 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1130 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1131 /* visibility must always be enabled for re_manage clients to prevent
1132 * pop-in animations every time the user sees a persistent client again;
1133 * applying visibility for iconic clients prevents the client from getting
1136 if (cw->visible || cw->ec->re_manage)
1137 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1139 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1141 /* breaks animation counter */
1142 if (cw->frame_object)
1144 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1145 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1146 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1147 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1153 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1157 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1160 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1162 if (input_rect_data->obj)
1164 pass_event_flag = EINA_TRUE;
1170 if (cw->indicator.obj)
1172 Evas_Object *indicator;
1173 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1174 if (indicator != cw->indicator.obj)
1176 edje_object_part_unswallow(cw->shobj, indicator);
1177 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1178 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1182 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1183 evas_object_pass_events_set(cw->obj, pass_event_flag);
1188 /////////////////////////////////////////////
1191 _e_comp_object_animating_begin(E_Comp_Object *cw)
1194 if (cw->animating == 1)
1196 e_comp->animating++;
1198 e_object_ref(E_OBJECT(cw->ec));
1203 _e_comp_object_animating_end(E_Comp_Object *cw)
1212 if (cw->ec->launching)
1214 if (!cw->ec->extra_animating)
1216 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1217 cw->ec->launching = EINA_FALSE;
1218 if (cw->ec->first_mapped)
1220 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1221 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1224 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1228 e_comp->animating--;
1229 cw->showing = cw->hiding = 0;
1231 if (e_comp->animating == 0)
1232 e_comp_visibility_calculation_set(EINA_TRUE);
1233 /* remove ref from animation start, account for possibility of deletion from unref */
1234 return !!e_object_unref(E_OBJECT(cw->ec));
1240 /* handle the end of a compositor animation */
1242 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1244 E_Comp_Object *cw = data;
1246 /* visible clients which have never been sized are a bug */
1247 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1248 CRI("ACK! ec:%p", cw->ec);
1249 if (!_e_comp_object_animating_end(cw)) return;
1250 if (cw->animating) return;
1251 /* hide only after animation finishes to guarantee a full run of the animation */
1252 if (!cw->defer_hide) return;
1253 if ((!strcmp(emission, "e,action,hide,done")) ||
1254 (!strcmp(emission, "e,action,done")) ||
1255 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1257 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1258 evas_object_hide(cw->smart_obj);
1262 /* run a visibility compositor effect if available, return false if object is dead */
1264 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1270 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1271 if (!cw->effect_running)
1272 _e_comp_object_animating_begin(cw);
1273 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1274 return _e_comp_object_animating_end(cw);
1275 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1276 return _e_comp_object_animating_end(cw);
1278 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1281 zone = e_comp_zone_find_by_ec(cw->ec);
1283 zw = zone->w, zh = zone->h;
1288 zone = e_comp_object_util_zone_get(cw->smart_obj);
1289 if (!zone) zone = e_zone_current_get();
1296 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1297 cw->w, cw->h, zw, zh, x, y}, 8);
1298 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1299 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1302 /////////////////////////////////////////////
1304 /* create necessary objects for clients that e manages */
1306 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1308 if (cw->set_mouse_callbacks) return;
1309 if (!cw->smart_obj) return;
1311 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1312 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1313 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1314 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1315 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1316 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1318 cw->set_mouse_callbacks = EINA_TRUE;
1322 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1324 if (!cw->set_mouse_callbacks) return;
1325 if (!cw->smart_obj) return;
1327 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1328 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1329 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1330 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1331 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1332 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1334 cw->set_mouse_callbacks = EINA_FALSE;
1338 _e_comp_object_setup(E_Comp_Object *cw)
1340 cw->clip = evas_object_rectangle_add(e_comp->evas);
1341 evas_object_move(cw->clip, -9999, -9999);
1342 evas_object_resize(cw->clip, 999999, 999999);
1343 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1344 cw->effect_obj = edje_object_add(e_comp->evas);
1345 evas_object_move(cw->effect_obj, cw->x, cw->y);
1346 evas_object_clip_set(cw->effect_obj, cw->clip);
1347 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1348 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1349 cw->shobj = edje_object_add(e_comp->evas);
1350 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1351 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1352 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1354 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1355 if (cw->ec->override)
1357 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1358 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1359 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1361 else if (!cw->ec->input_only)
1363 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1364 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1365 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1367 cw->real_hid = !cw->ec->input_only;
1368 if (!cw->ec->input_only)
1370 e_util_size_debug_set(cw->effect_obj, 1);
1371 _e_comp_object_mouse_event_callback_set(cw);
1374 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1375 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1376 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1377 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1378 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1379 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1381 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1384 /////////////////////////////////////////////
1386 /* for fast path evas rendering; only called during render */
1388 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1390 E_Comp_Object *cw = data;
1391 E_Client *ec = cw->ec;
1393 int bx, by, bxx, byy;
1395 if (e_object_is_del(E_OBJECT(ec))) return;
1396 if (cw->external_content) return;
1397 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1398 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1401 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1402 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1404 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1406 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1407 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1411 bx = by = bxx = byy = 0;
1412 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1415 Edje_Message_Int_Set *msg;
1416 Edje_Message_Int msg2;
1417 Eina_Bool id = (bx || by || bxx || byy);
1419 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1425 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1427 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1431 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1432 e_comp_client_post_update_add(cw->ec);
1434 else if (e_comp_object_render(ec->frame))
1436 /* apply shape mask if necessary */
1437 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1438 e_comp_object_shape_apply(ec->frame);
1439 ec->shape_changed = 0;
1441 /* shaped clients get precise mouse events to handle transparent pixels */
1442 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1444 /* queue another render if client is still dirty; cannot refresh here. */
1445 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1446 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1448 if (cw->render_trace)
1450 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1456 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1458 E_Comp_Object *cw = data;
1459 E_Client *ec = cw->ec;
1461 if (e_object_is_del(E_OBJECT(ec))) return;
1462 if (cw->external_content) return;
1463 if (!e_comp->hwc) return;
1465 e_comp_client_render_list_add(cw->ec);
1467 if (!ec->hwc_window) return;
1469 e_hwc_windows_rendered_window_add(ec->hwc_window);
1472 /////////////////////////////////////////////
1475 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1477 E_Comp_Object *cw = data;
1480 if (cw->render_update_lock.lock)
1482 cw->render_update_lock.pending_move_x = x;
1483 cw->render_update_lock.pending_move_y = y;
1484 cw->render_update_lock.pending_move_set = EINA_TRUE;
1488 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1489 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1490 (cw->external_content))
1492 /* delay to move until the external content is unset */
1493 cw->ec->changes.pos = 1;
1498 if (cw->ec->move_after_resize)
1500 if ((x != cw->ec->x) || (y != cw->ec->y))
1502 if (!cw->ec->is_cursor)
1503 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1504 e_client_pos_set(cw->ec, x, y);
1505 cw->ec->changes.pos = 1;
1511 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1512 (cw->ec->manage_resize.resize_obj))
1514 e_client_pos_set(cw->ec, x, y);
1515 cw->ec->client.x = x + cw->client_inset.l;
1516 cw->ec->client.y = y + cw->client_inset.t;
1517 e_policy_visibility_client_defer_move(cw->ec);
1521 /* if frame_object does not exist, client_inset indicates CSD.
1522 * this means that ec->client matches cw->x/y, the opposite
1525 fx = (!cw->frame_object) * cw->client_inset.l;
1526 fy = (!cw->frame_object) * cw->client_inset.t;
1527 if ((cw->x == x + fx) && (cw->y == y + fy))
1529 if ((cw->ec->x != x) || (cw->ec->y != y))
1531 /* handle case where client tries to move to position and back very quickly */
1532 e_client_pos_set(cw->ec, x, y);
1533 cw->ec->client.x = x + cw->client_inset.l;
1534 cw->ec->client.y = y + cw->client_inset.t;
1538 if (!cw->ec->maximize_override)
1540 /* prevent moving in some directions while directionally maximized */
1541 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1543 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1546 ix = x + cw->client_inset.l;
1547 iy = y + cw->client_inset.t;
1548 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1549 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1550 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1552 /* prevent moving at all if move isn't allowed in current maximize state */
1553 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1554 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1557 zone = e_comp_zone_find_by_ec(cw->ec);
1560 cw->ec->changes.need_unmaximize = 1;
1561 cw->ec->saved.x = ix - zone->x;
1562 cw->ec->saved.y = iy - zone->y;
1563 cw->ec->saved.w = cw->ec->client.w;
1564 cw->ec->saved.h = cw->ec->client.h;
1568 /* only update during resize if triggered by resize */
1569 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1570 /* delay to move while surface waits paired commit serial*/
1571 if (e_client_pending_geometry_has(cw->ec))
1573 /* do nothing while waiting paired commit serial*/
1577 e_client_pos_set(cw->ec, x, y);
1578 if (cw->ec->new_client)
1580 /* don't actually do anything until first client idler loop */
1581 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1582 cw->ec->changes.pos = 1;
1587 /* only update xy position of client to avoid invalid
1588 * first damage region if it is not a new_client. */
1589 cw->ec->client.x = ix;
1590 cw->ec->client.y = iy;
1593 if (!cw->frame_object)
1595 evas_object_move(obj, x, y);
1600 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1602 E_Comp_Object *cw = data;
1603 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1606 if (cw->render_update_lock.lock)
1608 cw->render_update_lock.pending_resize_w = w;
1609 cw->render_update_lock.pending_resize_h = h;
1610 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1614 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1616 e_client_size_set(cw->ec, w, h);
1617 evas_object_resize(obj, w, h);
1621 /* if frame_object does not exist, client_inset indicates CSD.
1622 * this means that ec->client matches cw->w/h, the opposite
1625 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1626 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1627 if ((cw->w == w + fw) && (cw->h == h + fh))
1629 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1630 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1631 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1633 /* handle case where client tries to resize itself and back very quickly */
1634 e_client_size_set(cw->ec, w, h);
1635 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1636 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1637 evas_object_smart_callback_call(obj, "client_resize", NULL);
1641 /* guarantee that fullscreen is fullscreen */
1642 zone = e_comp_zone_find_by_ec(cw->ec);
1644 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1646 if (!e_client_transform_core_enable_get(cw->ec))
1649 /* calculate client size */
1650 iw = w - cw->client_inset.l - cw->client_inset.r;
1651 ih = h - cw->client_inset.t - cw->client_inset.b;
1652 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1654 /* prevent resizing while maximized depending on direction and config */
1655 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1657 Eina_Bool reject = EINA_FALSE;
1658 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1660 if (cw->ec->client.h != ih)
1662 cw->ec->saved.h = ih;
1663 cw->ec->saved.y = cw->ec->client.y - zone->y;
1664 reject = cw->ec->changes.need_unmaximize = 1;
1667 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1669 if (cw->ec->client.w != iw)
1671 cw->ec->saved.w = iw;
1672 cw->ec->saved.x = cw->ec->client.x - zone->x;
1673 reject = cw->ec->changes.need_unmaximize = 1;
1682 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1684 /* do nothing until client idler loops */
1685 if ((cw->ec->w != w) || (cw->ec->h != h))
1687 e_client_size_set(cw->ec, w, h);
1688 cw->ec->changes.size = 1;
1693 if (e_client_pending_geometry_has(cw->ec))
1695 /* do nothing while waiting paired commit serial*/
1699 e_client_size_set(cw->ec, w, h);
1701 cw->ec->client.w = iw;
1702 cw->ec->client.h = ih;
1703 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1705 /* The size of non-compositing window can be changed, so there is a
1706 * need to check that cw is H/W composited if cw is not redirected.
1707 * And of course we have to change size of evas object of H/W composited cw,
1708 * otherwise cw can't receive input events even if it is shown on the screen.
1710 Eina_Bool redirected = cw->redirected;
1712 redirected = e_comp_is_on_overlay(cw->ec);
1714 if ((!cw->ec->input_only) && (redirected) &&
1715 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1716 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1717 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1718 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1721 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1722 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1724 prev_w = cw->w, prev_h = cw->h;
1725 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1726 /* check shading and clamp to pixmap size for regular clients */
1727 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1728 (((w - fw != pw) || (h - fh != ph))))
1730 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1731 evas_object_smart_callback_call(obj, "client_resize", NULL);
1733 if (cw->frame_object || cw->ec->input_only)
1734 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1737 if ((cw->w == w) && (cw->h == h))
1739 /* going to be a noop resize which won't trigger smart resize */
1740 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1741 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1743 evas_object_resize(obj, w, h);
1747 evas_object_smart_callback_call(obj, "client_resize", NULL);
1750 if ((!cw->frame_object) && (!cw->ec->input_only))
1752 /* "just do it" for overrides */
1753 evas_object_resize(obj, w, h);
1755 if (!cw->ec->override)
1757 /* shape probably changed for non-overrides */
1758 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1759 cw->ec->need_shape_export |= cw->ec->shaped;
1760 if (cw->ec->shaped || cw->ec->shaped_input)
1764 /* this fixes positioning jiggles when using a resize mode
1765 * which also changes the client's position
1768 if (cw->frame_object)
1769 x = cw->x, y = cw->y;
1771 x = cw->ec->x, y = cw->ec->y;
1772 switch (cw->ec->resize_mode)
1774 case E_POINTER_RESIZE_BL:
1775 case E_POINTER_RESIZE_L:
1776 evas_object_move(obj, x + prev_w - cw->w, y);
1778 case E_POINTER_RESIZE_TL:
1779 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1781 case E_POINTER_RESIZE_T:
1782 case E_POINTER_RESIZE_TR:
1783 evas_object_move(obj, x, y + prev_h - cw->h);
1792 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1794 E_Comp_Object *cw = data;
1795 E_Comp_Wl_Client_Data *child_cdata;
1796 unsigned int l = e_comp_canvas_layer_map(layer);
1799 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1801 /* doing a compositor effect, follow directions */
1802 _e_comp_object_layer_set(obj, layer);
1803 if (layer == cw->ec->layer) //trying to put layer back
1807 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1808 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1809 if (cw->layer != l) goto layer_set;
1813 e_comp_render_queue();
1815 ec = e_client_above_get(cw->ec);
1816 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1817 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1818 ec = e_client_above_get(ec);
1819 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1821 ec = e_client_below_get(cw->ec);
1822 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1823 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1824 ec = e_client_below_get(ec);
1825 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1827 evas_object_stack_above(obj, ec->frame);
1832 if (ec && (cw->ec->parent == ec))
1834 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1835 evas_object_stack_above(obj, ec->frame);
1837 evas_object_stack_below(obj, ec->frame);
1840 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1846 if (cw->layer == l) return;
1847 if (e_comp_canvas_client_layer_map(layer) == 9999)
1848 return; //invalid layer for clients not doing comp effects
1849 if (cw->ec->fullscreen)
1851 cw->ec->saved.layer = layer;
1854 oldraise = e_config->transient.raise;
1856 /* clamp to valid client layer */
1857 layer = e_comp_canvas_client_layer_map_nearest(layer);
1858 cw->ec->layer = layer;
1859 if (e_config->transient.layer)
1862 Eina_List *list = eina_list_clone(cw->ec->transients);
1864 /* We need to set raise to one, else the child wont
1865 * follow to the new layer. It should be like this,
1866 * even if the user usually doesn't want to raise
1869 e_config->transient.raise = 1;
1870 EINA_LIST_FREE(list, child)
1872 child_cdata = e_client_cdata_get(child);
1873 if (child_cdata && !child_cdata->mapped)
1875 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1878 e_client_layer_set(child, layer);
1882 e_config->transient.raise = oldraise;
1884 _e_comp_object_layers_remove(cw);
1885 cw->layer = e_comp_canvas_layer_map(layer);
1886 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1887 //if (cw->ec->new_client)
1888 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1889 _e_comp_object_layer_set(obj, layer);
1890 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1891 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1892 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1894 /* can't stack a client above its own layer marker */
1895 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1897 if (!cw->visible) return;
1898 e_comp_render_queue();
1899 _e_comp_object_transform_obj_stack_update(obj);
1902 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1905 _e_comp_object_raise(Evas_Object *obj)
1907 evas_object_raise(obj);
1909 if (evas_object_smart_smart_get(obj))
1911 E_Client *ec = e_comp_object_client_get(obj);
1913 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1918 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1920 evas_object_lower(obj);
1922 if (evas_object_smart_smart_get(obj))
1924 E_Client *ec = e_comp_object_client_get(obj);
1927 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1928 wl_signal_emit_mutable(&cw->events.lower, NULL);
1934 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1936 evas_object_stack_above(obj, target);
1938 if (evas_object_smart_smart_get(obj))
1940 E_Client *ec = e_comp_object_client_get(obj);
1942 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1947 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1949 evas_object_stack_below(obj, target);
1951 if (evas_object_smart_smart_get(obj))
1953 E_Client *ec = e_comp_object_client_get(obj);
1955 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1960 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1962 evas_object_layer_set(obj, layer);
1964 if (evas_object_smart_smart_get(obj))
1966 E_Client *ec = e_comp_object_client_get(obj);
1968 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1973 _e_comp_object_is_pending(E_Client *ec)
1977 if (!ec) return EINA_FALSE;
1979 topmost = e_comp_wl_topmost_parent_get(ec);
1981 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1985 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1987 E_Comp_Object *cw2 = NULL;
1990 Evas_Object *o = stack;
1991 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1993 /* We should consider topmost's layer_pending for subsurface */
1994 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1996 if (_e_comp_object_is_pending(cw->ec))
1997 e_comp_object_layer_update(cw->smart_obj,
1998 raising? stack : NULL,
1999 raising? NULL : stack);
2001 /* obey compositor effects! */
2002 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2003 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2004 stack_cb(cw->smart_obj, stack);
2005 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2006 evas_object_data_del(cw->smart_obj, "client_restack");
2010 cw2 = evas_object_data_get(o, "comp_obj");
2012 /* assume someone knew what they were doing during client init */
2013 if (cw->ec->new_client)
2014 layer = cw->ec->layer;
2015 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2016 layer = cw2->ec->layer;
2018 layer = evas_object_layer_get(stack);
2019 ecstack = e_client_below_get(cw->ec);
2020 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2022 evas_object_layer_set(cw->smart_obj, layer);
2023 /* we got our layer wrangled, return now! */
2024 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2027 /* check if we're stacking below another client */
2030 /* check for non-client layer object */
2031 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2033 /* find an existing client to use for layering
2034 * by walking up the object stack
2036 * this is guaranteed to be pretty quick since we'll either:
2037 * - run out of client layers
2038 * - find a stacking client
2040 o = evas_object_above_get(o);
2041 if ((!o) || (o == cw->smart_obj)) break;
2042 if (evas_object_layer_get(o) != layer)
2044 /* reached the top client layer somehow
2045 * use top client object
2047 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2050 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2051 * return here since the top client layer window
2056 ec = e_client_top_get();
2061 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2064 if (cw2 && cw->layer != cw2->layer)
2067 /* remove existing layers */
2068 _e_comp_object_layers_remove(cw);
2071 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2072 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2073 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2074 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2075 else //if no stacking objects found, either raise or lower
2076 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2079 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2081 /* find new object for stacking if cw2 is on state of layer_pending */
2082 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2084 E_Client *new_stack = NULL, *current_ec = NULL;
2085 current_ec = cw2->ec;
2088 while ((new_stack = e_client_below_get(current_ec)))
2090 current_ec = new_stack;
2091 if (new_stack == cw->ec) continue;
2092 if (new_stack->layer != cw2->ec->layer) break;
2093 if (!_e_comp_object_is_pending(new_stack)) break;
2095 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2096 stack = new_stack->frame;
2099 /* stack it above layer object */
2101 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2102 stack = e_comp->layers[below_layer].obj;
2107 while ((new_stack = e_client_above_get(current_ec)))
2109 current_ec = new_stack;
2110 if (new_stack == cw->ec) continue;
2111 if (new_stack->layer != cw2->ec->layer) break;
2112 if (!_e_comp_object_is_pending(new_stack)) break;
2114 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2115 stack = new_stack->frame;
2117 stack = e_comp->layers[cw2->layer].obj;
2121 /* set restack if stacking has changed */
2122 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2123 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2124 stack_cb(cw->smart_obj, stack);
2125 if (e_comp->layers[cw->layer].obj)
2126 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2128 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2130 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2131 evas_object_data_del(cw->smart_obj, "client_restack");
2132 if (!cw->visible) return;
2133 e_comp_render_queue();
2137 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2139 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2141 if (evas_object_below_get(obj) == above)
2143 e_comp_object_layer_update(obj, above, NULL);
2147 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2148 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2149 _e_comp_object_transform_obj_stack_update(obj);
2150 _e_comp_object_transform_obj_stack_update(above);
2155 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2157 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2158 if (evas_object_above_get(obj) == below)
2160 e_comp_object_layer_update(obj, NULL, below);
2164 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2165 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2166 if (evas_object_smart_smart_get(obj))
2167 _e_comp_object_transform_obj_stack_update(obj);
2168 if (evas_object_smart_smart_get(below))
2169 _e_comp_object_transform_obj_stack_update(below);
2174 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2176 E_Comp_Object *cw = data;
2179 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2181 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2183 if (cw->ec->layer_pending)
2184 e_comp_object_layer_update(obj, NULL, obj);
2186 _e_comp_object_lower(cw, obj);
2189 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2190 o = evas_object_below_get(obj);
2191 _e_comp_object_layers_remove(cw);
2192 /* prepend to client list since this client should be the first item now */
2193 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2194 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2195 evas_object_data_set(obj, "client_restack", (void*)1);
2196 _e_comp_object_lower(cw, obj);
2197 evas_object_data_del(obj, "client_restack");
2198 if (!cw->visible) goto end;
2199 e_comp_render_queue();
2200 _e_comp_object_transform_obj_stack_update(obj);
2207 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2209 E_Comp_Object *cw = data;
2213 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2215 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2217 if (cw->ec->layer_pending)
2219 int obj_layer = evas_object_layer_get(obj);
2220 if (cw->ec->layer != obj_layer)
2221 e_comp_object_layer_update(obj, NULL, NULL);
2224 _e_comp_object_raise(obj);
2227 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2228 o = evas_object_above_get(obj);
2229 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2231 /* still stack below override below the layer marker */
2232 for (op = o = e_comp->layers[cw->layer].obj;
2233 o && o != e_comp->layers[cw->layer - 1].obj;
2234 op = o, o = evas_object_below_get(o))
2236 if (evas_object_smart_smart_get(o))
2240 ec = e_comp_object_client_get(o);
2241 if (ec && (!ec->override)) break;
2244 _e_comp_object_stack_below(obj, op);
2245 e_client_focus_defer_set(cw->ec);
2247 if (!cw->visible) goto end;
2248 e_comp_render_queue();
2249 _e_comp_object_transform_obj_stack_update(obj);
2256 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2258 E_Comp_Object *cw = data;
2260 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2261 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2263 ELOGF("COMP", "Hide. intercepted", cw->ec);
2268 if (cw->ec->launching == EINA_TRUE)
2270 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2271 cw->ec->launching = EINA_FALSE;
2276 /* hidden flag = just do it */
2277 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2278 evas_object_hide(obj);
2280 wl_signal_emit_mutable(&cw->events.hide, NULL);
2285 if (cw->ec->input_only)
2287 /* input_only = who cares */
2288 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2289 evas_object_hide(obj);
2291 wl_signal_emit_mutable(&cw->events.hide, NULL);
2295 /* already hidden or currently animating */
2296 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2298 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2302 /* don't try hiding during shutdown */
2303 cw->defer_hide |= stopping;
2304 if (!cw->defer_hide)
2306 if ((!cw->ec->iconic) && (!cw->ec->override))
2307 /* unset delete requested so the client doesn't break */
2308 cw->ec->delete_requested = 0;
2309 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2311 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2312 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2315 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2318 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2320 _e_comp_object_animating_begin(cw);
2321 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2323 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2324 cw->defer_hide = !!cw->animating;
2326 e_comp_object_effect_set(obj, NULL);
2329 if (cw->animating) return;
2330 /* if we have no animations running, go ahead and hide */
2332 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2333 evas_object_hide(obj);
2335 wl_signal_emit_mutable(&cw->events.hide, NULL);
2339 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2341 E_Client *ec = cw->ec;
2344 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2346 if (ec->show_pending.count > 0)
2348 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2349 ec->show_pending.running = EINA_TRUE;
2353 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2354 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2356 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2361 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,
2362 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2363 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2366 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2369 if (ec->iconic && cw->animating)
2371 /* triggered during iconify animation */
2372 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2375 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2378 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2379 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2381 evas_object_move(cw->smart_obj, ec->x, ec->y);
2382 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2383 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2385 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2386 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2389 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2390 evas_object_show(cw->smart_obj);
2393 e_client_focus_defer_set(ec);
2397 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2401 pw = ec->client.w, ph = ec->client.h;
2403 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2405 ec->changes.visible = !ec->hidden;
2408 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2412 cw->updates = eina_tiler_new(pw, ph);
2415 ec->changes.visible = !ec->hidden;
2418 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2423 eina_tiler_tile_size_set(cw->updates, 1, 1);
2426 /* ignore until client idler first run */
2427 ec->changes.visible = !ec->hidden;
2430 ELOGF("COMP", "show_helper. return. new_client", ec);
2437 evas_object_move(cw->smart_obj, ec->x, ec->y);
2438 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2439 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2440 evas_object_show(cw->smart_obj);
2443 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2445 /* start_drag not received */
2446 ec->changes.visible = 1;
2449 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2452 /* re-set geometry */
2453 evas_object_move(cw->smart_obj, ec->x, ec->y);
2454 /* force resize in case it hasn't happened yet, or just to update size */
2455 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2456 if ((cw->w < 1) || (cw->h < 1))
2458 /* if resize didn't go through, try again */
2459 ec->visible = ec->changes.visible = 1;
2461 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2464 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2465 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2466 e_pixmap_clear(ec->pixmap);
2468 if (cw->real_hid && w && h)
2471 /* force comp theming in case it didn't happen already */
2472 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2473 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2474 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2477 /* only do the show if show is allowed */
2480 if (ec->internal) //internal clients render when they feel like it
2481 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2483 if (!e_client_is_iconified_by_client(ec)||
2484 e_policy_visibility_client_is_uniconic(ec))
2486 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2487 evas_object_show(cw->smart_obj);
2489 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2490 it is rendered in idle callback without native surface and
2491 compositor shows an empty frame if other objects aren't shown
2492 because job callback of e_comp called at the next loop.
2493 it causes a visual defect when windows are switched.
2497 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2498 e_comp_object_dirty(cw->smart_obj);
2499 e_comp_object_render(cw->smart_obj);
2504 wl_signal_emit_mutable(&cw->events.show, NULL);
2508 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2510 E_Comp_Object *cw = data;
2511 E_Client *ec = cw->ec;
2513 E_Input_Rect_Data *input_rect_data;
2514 E_Input_Rect_Smart_Data *input_rect_sd;
2517 if (ec->ignored) return;
2521 //INF("SHOW2 %p", ec);
2522 _e_comp_intercept_show_helper(cw);
2525 //INF("SHOW %p", ec);
2528 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2529 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2530 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2531 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2535 if ((!cw->obj) && (cw->external_content))
2537 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2541 _e_comp_object_setup(cw);
2544 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2545 cw->obj = evas_object_image_filled_add(e_comp->evas);
2546 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2547 e_util_size_debug_set(cw->obj, 1);
2548 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2549 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2550 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2551 evas_object_name_set(cw->obj, "cw->obj");
2552 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2554 _e_comp_object_alpha_set(cw);
2557 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2560 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2561 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2564 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2567 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2569 if (input_rect_data->obj)
2571 evas_object_geometry_set(input_rect_data->obj,
2572 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2573 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2574 input_rect_data->rect.w, input_rect_data->rect.h);
2581 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2583 _e_comp_intercept_show_helper(cw);
2587 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2589 E_Comp_Object *cw = data;
2593 /* note: this is here as it seems there are enough apps that do not even
2594 * expect us to emulate a look of focus but not actually set x input
2595 * focus as we do - so simply abort any focus set on such windows */
2596 /* be strict about accepting focus hint */
2597 /* be strict about accepting focus hint */
2598 if ((!ec->icccm.accepts_focus) &&
2599 (!ec->icccm.take_focus))
2603 if (e_client_focused_get() == ec)
2604 e_client_focused_set(NULL);
2606 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2607 evas_object_focus_set(obj, focus);
2611 if (focus && ec->lock_focus_out) return;
2612 if (e_object_is_del(E_OBJECT(ec)) && focus)
2613 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2615 /* filter focus setting based on current state */
2620 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2621 evas_object_focus_set(obj, focus);
2624 if ((ec->iconic) && (!ec->deskshow))
2626 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2628 /* don't focus an iconified window. that's silly! */
2629 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2630 e_client_uniconify(ec);
2631 e_client_focus_latest_set(ec);
2645 /* not yet visible, wait till the next time... */
2646 ec->want_focus = !ec->hidden;
2651 e_client_focused_set(ec);
2655 if (e_client_focused_get() == ec)
2656 e_client_focused_set(NULL);
2660 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2662 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2664 evas_object_focus_set(obj, focus);
2668 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2670 E_Comp_Object *cw = data;
2672 if (cw->transparent.set)
2674 cw->transparent.user_r = r;
2675 cw->transparent.user_g = g;
2676 cw->transparent.user_b = b;
2677 cw->transparent.user_a = a;
2679 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2681 cw->transparent.user_r,
2682 cw->transparent.user_g,
2683 cw->transparent.user_b,
2684 cw->transparent.user_a);
2688 evas_object_color_set(obj, r, g, b, a);
2691 ////////////////////////////////////////////////////
2694 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2696 int w, h, ox, oy, ow, oh;
2698 Eina_Bool pass_event_flag = EINA_FALSE;
2699 E_Input_Rect_Data *input_rect_data;
2700 E_Input_Rect_Smart_Data *input_rect_sd;
2702 if (cw->frame_object)
2704 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2705 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2706 /* set a fixed size, force edje calc, check size difference */
2707 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2708 edje_object_message_signal_process(cw->frame_object);
2709 edje_object_calc_force(cw->frame_object);
2710 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2711 cw->client_inset.l = ox;
2712 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2713 cw->client_inset.t = oy;
2714 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2715 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2716 evas_object_resize(cw->frame_object, w, h);
2720 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2723 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2725 if (input_rect_data->obj)
2727 pass_event_flag = EINA_TRUE;
2733 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2734 evas_object_pass_events_set(cw->obj, pass_event_flag);
2738 cw->client_inset.l = 0;
2739 cw->client_inset.r = 0;
2740 cw->client_inset.t = 0;
2741 cw->client_inset.b = 0;
2743 cw->client_inset.calc = !!cw->frame_object;
2747 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2749 E_Comp_Object *cw = data;
2753 /* - get current size
2755 * - readjust for new frame size
2758 w = cw->ec->w, h = cw->ec->h;
2759 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2761 _e_comp_object_frame_recalc(cw);
2763 if (!cw->ec->fullscreen)
2764 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2766 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2767 if (cw->ec->fullscreen)
2769 zone = e_comp_zone_find_by_ec(cw->ec);
2771 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2773 else if (cw->ec->new_client)
2775 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2776 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2777 evas_object_resize(cw->ec->frame, w, h);
2779 else if ((w != cw->ec->w) || (h != cw->ec->h))
2780 evas_object_resize(cw->ec->frame, w, h);
2784 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2786 E_Comp_Object *cw = data;
2788 _e_comp_object_shadow_setup(cw);
2789 if (cw->frame_object)
2791 _e_comp_object_shadow(cw);
2792 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2793 _e_comp_object_frame_recalc(cw);
2794 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2799 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2801 E_Comp_Object *cw = data;
2803 if (_e_comp_object_shadow_setup(cw))
2804 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2805 if (cw->frame_object)
2807 _e_comp_object_shadow(cw);
2808 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2809 _e_comp_object_frame_recalc(cw);
2810 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2815 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2817 E_Comp_Object *cw = data;
2819 if (cw->frame_object)
2821 _e_comp_object_shadow(cw);
2822 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2823 _e_comp_object_frame_recalc(cw);
2824 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2829 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2831 E_Comp_Object *cw = data;
2833 if (_e_comp_object_shadow_setup(cw))
2836 cw->ec->changes.size = 1;
2838 if (cw->frame_object)
2840 _e_comp_object_shadow(cw);
2841 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2842 _e_comp_object_frame_recalc(cw);
2843 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2848 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2850 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2854 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2856 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2860 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2862 E_Comp_Object *cw = data;
2864 if (!cw->ec) return; //NYI
2865 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2869 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2871 E_Comp_Object *cw = data;
2873 if (!cw->ec) return; //NYI
2874 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2878 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2880 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2884 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2886 E_Comp_Object *cw = data;
2888 if (!e_object_is_del(E_OBJECT(cw->ec)))
2889 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2893 _e_comp_input_obj_smart_add(Evas_Object *obj)
2895 E_Input_Rect_Smart_Data *input_rect_sd;
2896 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2898 if (!input_rect_sd) return;
2899 evas_object_smart_data_set(obj, input_rect_sd);
2903 _e_comp_input_obj_smart_del(Evas_Object *obj)
2905 E_Input_Rect_Smart_Data *input_rect_sd;
2906 E_Input_Rect_Data *input_rect_data;
2908 input_rect_sd = evas_object_smart_data_get(obj);
2909 if (!input_rect_sd) return;
2911 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2913 if (input_rect_data->obj)
2915 evas_object_smart_member_del(input_rect_data->obj);
2916 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2918 E_FREE(input_rect_data);
2920 E_FREE(input_rect_sd);
2924 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2926 E_Input_Rect_Smart_Data *input_rect_sd;
2927 E_Input_Rect_Data *input_rect_data;
2931 input_rect_sd = evas_object_smart_data_get(obj);
2932 if (!input_rect_sd) return;
2934 cw = input_rect_sd->cw;
2935 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2937 if (input_rect_data->obj)
2939 evas_object_geometry_set(input_rect_data->obj,
2940 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2941 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2942 input_rect_data->rect.w, input_rect_data->rect.h);
2948 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2950 E_Input_Rect_Smart_Data *input_rect_sd;
2951 E_Input_Rect_Data *input_rect_data;
2955 input_rect_sd = evas_object_smart_data_get(obj);
2956 if (!input_rect_sd) return;
2958 cw = input_rect_sd->cw;
2959 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2961 if (input_rect_data->obj)
2963 evas_object_geometry_set(input_rect_data->obj,
2964 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2965 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2966 input_rect_data->rect.w, input_rect_data->rect.h);
2972 _e_comp_input_obj_smart_show(Evas_Object *obj)
2974 E_Input_Rect_Smart_Data *input_rect_sd;
2975 E_Input_Rect_Data *input_rect_data;
2978 input_rect_sd = evas_object_smart_data_get(obj);
2979 if (!input_rect_sd) return;
2981 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2983 if (input_rect_data->obj)
2985 evas_object_show(input_rect_data->obj);
2991 _e_comp_input_obj_smart_hide(Evas_Object *obj)
2993 E_Input_Rect_Smart_Data *input_rect_sd;
2994 E_Input_Rect_Data *input_rect_data;
2997 input_rect_sd = evas_object_smart_data_get(obj);
2998 if (!input_rect_sd) return;
3000 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3002 if (input_rect_data->obj)
3004 evas_object_hide(input_rect_data->obj);
3010 _e_comp_input_obj_smart_init(void)
3012 if (_e_comp_input_obj_smart) return;
3014 static const Evas_Smart_Class sc =
3016 INPUT_OBJ_SMART_NAME,
3017 EVAS_SMART_CLASS_VERSION,
3018 _e_comp_input_obj_smart_add,
3019 _e_comp_input_obj_smart_del,
3020 _e_comp_input_obj_smart_move,
3021 _e_comp_input_obj_smart_resize,
3022 _e_comp_input_obj_smart_show,
3023 _e_comp_input_obj_smart_hide,
3036 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3042 _e_comp_smart_add(Evas_Object *obj)
3046 cw = E_NEW(E_Comp_Object, 1);
3047 EINA_SAFETY_ON_NULL_RETURN(cw);
3049 wl_signal_init(&cw->events.lower);
3050 wl_signal_init(&cw->events.show);
3051 wl_signal_init(&cw->events.hide);
3053 cw->smart_obj = obj;
3054 cw->x = cw->y = cw->w = cw->h = -1;
3055 evas_object_smart_data_set(obj, cw);
3056 cw->opacity = 255.0;
3057 cw->external_content = 0;
3058 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3059 cw->transform_bg_color.r = 0;
3060 cw->transform_bg_color.g = 0;
3061 cw->transform_bg_color.b = 0;
3062 cw->transform_bg_color.a = 255;
3063 evas_object_data_set(obj, "comp_obj", cw);
3064 evas_object_move(obj, -1, -1);
3065 /* intercept ALL the callbacks! */
3066 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3067 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3068 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3069 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3070 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3071 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3072 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3073 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3074 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3075 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3076 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3078 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3079 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3080 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3081 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3083 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3084 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3086 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3087 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3089 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3091 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3092 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3096 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3099 evas_object_color_set(cw->clip, r, g, b, a);
3100 evas_object_smart_callback_call(obj, "color_set", NULL);
3105 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3108 evas_object_clip_set(cw->clip, clip);
3112 _e_comp_smart_clip_unset(Evas_Object *obj)
3115 evas_object_clip_unset(cw->clip);
3119 _e_comp_smart_hide(Evas_Object *obj)
3121 TRACE_DS_BEGIN(COMP:SMART HIDE);
3126 evas_object_hide(cw->clip);
3127 if (cw->input_obj) evas_object_hide(cw->input_obj);
3128 evas_object_hide(cw->effect_obj);
3129 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3130 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3131 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3138 /* unset native surface if current displaying buffer was destroied */
3139 if (!cw->buffer_destroy_listener.notify)
3141 Evas_Native_Surface *ns;
3142 ns = evas_object_image_native_surface_get(cw->obj);
3143 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3144 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3147 if (!cw->ec->input_only)
3149 edje_object_freeze(cw->effect_obj);
3150 edje_object_freeze(cw->shobj);
3151 edje_object_play_set(cw->shobj, 0);
3152 if (cw->frame_object)
3153 edje_object_play_set(cw->frame_object, 0);
3156 e_comp_render_queue(); //force nocomp recheck
3162 _e_comp_smart_show(Evas_Object *obj)
3170 if ((cw->w < 0) || (cw->h < 0))
3171 CRI("ACK! ec:%p", cw->ec);
3173 TRACE_DS_BEGIN(COMP:SMART SHOW);
3175 e_comp_object_map_update(obj);
3177 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3178 evas_object_show(tmp->frame);
3180 evas_object_show(cw->clip);
3181 if (cw->input_obj) evas_object_show(cw->input_obj);
3182 if (!cw->ec->input_only)
3184 edje_object_thaw(cw->effect_obj);
3185 edje_object_thaw(cw->shobj);
3186 edje_object_play_set(cw->shobj, 1);
3187 if (cw->frame_object)
3188 edje_object_play_set(cw->frame_object, 1);
3190 evas_object_show(cw->effect_obj);
3191 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3192 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3193 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3194 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3195 e_comp_render_queue();
3196 if (cw->ec->input_only)
3201 if (cw->ec->iconic && (!cw->ec->new_client))
3203 if (e_client_is_iconified_by_client(cw->ec))
3205 ELOGF("COMP", "Set launching flag..", cw->ec);
3206 cw->ec->launching = EINA_TRUE;
3209 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3211 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3214 ELOGF("COMP", "Set launching flag..", cw->ec);
3215 cw->ec->launching = EINA_TRUE;
3217 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3218 _e_comp_object_animating_begin(cw);
3219 if (!_e_comp_object_effect_visibility_start(cw, 1))
3225 /* ensure some random effect doesn't lock the client offscreen */
3229 e_comp_object_effect_set(obj, NULL);
3232 _e_comp_object_dim_update(cw);
3238 _e_comp_smart_del(Evas_Object *obj)
3244 if (cw->buffer_destroy_listener.notify)
3246 wl_list_remove(&cw->buffer_destroy_listener.link);
3247 cw->buffer_destroy_listener.notify = NULL;
3250 if (cw->tbm_surface)
3252 tbm_surface_internal_unref(cw->tbm_surface);
3253 cw->tbm_surface = NULL;
3256 if (cw->render_update_lock.buffer_ref.buffer)
3258 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3259 cw->ec, cw->render_update_lock.lock);
3260 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3263 e_comp_object_render_update_del(cw->smart_obj);
3264 E_FREE_FUNC(cw->updates, eina_tiler_free);
3265 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3272 EINA_LIST_FREE(cw->obj_mirror, o)
3274 evas_object_image_data_set(o, NULL);
3275 evas_object_freeze_events_set(o, 1);
3276 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3280 _e_comp_object_layers_remove(cw);
3281 l = evas_object_data_get(obj, "comp_object-to_del");
3282 E_FREE_LIST(l, evas_object_del);
3283 _e_comp_object_mouse_event_callback_unset(cw);
3284 evas_object_del(cw->clip);
3285 evas_object_del(cw->obj);
3286 evas_object_del(cw->shobj);
3287 evas_object_del(cw->effect_obj);
3288 evas_object_del(cw->frame_object);
3289 evas_object_del(cw->input_obj);
3290 evas_object_del(cw->mask.obj);
3291 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3292 evas_object_del(cw->transform_bg_obj);
3293 evas_object_del(cw->transform_tranp_obj);
3294 evas_object_del(cw->default_input_obj);
3295 eina_stringshare_del(cw->frame_theme);
3296 eina_stringshare_del(cw->frame_name);
3300 e_comp->animating--;
3302 e_object_unref(E_OBJECT(cw->ec));
3304 cw->ec->frame = NULL;
3309 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3313 cw->x = x, cw->y = y;
3314 evas_object_move(cw->effect_obj, x, y);
3315 evas_object_move(cw->default_input_obj, x, y);
3316 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3318 e_comp_object_map_update(obj);
3322 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3324 Eina_Bool first = EINA_FALSE;
3329 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3331 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3333 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3335 if (cw->w != w || cw->h != h)
3336 e_comp_object_map_update(obj);
3338 first = ((cw->w < 1) || (cw->h < 1));
3339 cw->w = w, cw->h = h;
3343 if (cw->frame_object)
3344 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3347 /* verify pixmap:object size */
3348 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3350 if ((ww != pw) || (hh != ph))
3351 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3353 evas_object_resize(cw->effect_obj, tw, th);
3354 evas_object_resize(cw->default_input_obj, w, h);
3356 evas_object_resize(cw->input_obj, w, h);
3358 evas_object_resize(cw->mask.obj, w, h);
3359 /* resize render update tiler */
3362 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3363 cw->updates_full = 0;
3364 if (cw->updates) eina_tiler_clear(cw->updates);
3368 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3369 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3377 e_comp_render_queue();
3383 _e_comp_smart_init(void)
3385 if (_e_comp_smart) return;
3387 static const Evas_Smart_Class sc =
3390 EVAS_SMART_CLASS_VERSION,
3394 _e_comp_smart_resize,
3397 _e_comp_smart_color_set,
3398 _e_comp_smart_clip_set,
3399 _e_comp_smart_clip_unset,
3409 _e_comp_smart = evas_smart_class_new(&sc);
3414 e_comp_object_init(void)
3416 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3417 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3418 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3419 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3423 e_comp_object_shutdown(void)
3429 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3431 API_ENTRY EINA_FALSE;
3432 return !!cw->force_visible;
3434 /////////////////////////////////////////////////////////
3437 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3440 Eina_Bool comp_object;
3442 comp_object = !!evas_object_data_get(obj, "comp_object");
3447 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3449 e_comp_render_queue();
3451 l = evas_object_data_get(obj, "comp_object-to_del");
3452 E_FREE_LIST(l, evas_object_del);
3456 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3458 if (e_comp_util_object_is_above_nocomp(obj) &&
3459 (!evas_object_data_get(obj, "comp_override")))
3461 evas_object_data_set(obj, "comp_override", (void*)1);
3462 e_comp_override_add();
3467 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3469 Eina_Bool ref = EINA_TRUE;
3470 if (evas_object_visible_get(obj))
3474 d = evas_object_data_del(obj, "comp_hiding");
3476 /* currently trying to hide */
3479 /* already visible */
3483 evas_object_show(obj);
3486 evas_object_ref(obj);
3487 evas_object_data_set(obj, "comp_ref", (void*)1);
3489 edje_object_signal_emit(obj, "e,state,visible", "e");
3490 evas_object_data_set(obj, "comp_showing", (void*)1);
3491 if (e_comp_util_object_is_above_nocomp(obj))
3493 evas_object_data_set(obj, "comp_override", (void*)1);
3494 e_comp_override_add();
3499 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3501 if (!evas_object_visible_get(obj)) return;
3502 /* already hiding */
3503 if (evas_object_data_get(obj, "comp_hiding")) return;
3504 if (!evas_object_data_del(obj, "comp_showing"))
3506 evas_object_ref(obj);
3507 evas_object_data_set(obj, "comp_ref", (void*)1);
3509 edje_object_signal_emit(obj, "e,state,hidden", "e");
3510 evas_object_data_set(obj, "comp_hiding", (void*)1);
3512 if (evas_object_data_del(obj, "comp_override"))
3513 e_comp_override_timed_pop();
3517 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3519 if (!e_util_strcmp(emission, "e,action,hide,done"))
3521 if (!evas_object_data_del(obj, "comp_hiding")) return;
3522 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3523 evas_object_hide(obj);
3524 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3527 evas_object_data_del(obj, "comp_showing");
3528 if (evas_object_data_del(obj, "comp_ref"))
3529 evas_object_unref(obj);
3533 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3539 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3543 E_API E_Comp_Object_Hook *
3544 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3546 E_Comp_Object_Hook *ch;
3548 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3549 ch = E_NEW(E_Comp_Object_Hook, 1);
3550 if (!ch) return NULL;
3551 ch->hookpoint = hookpoint;
3553 ch->data = (void*)data;
3554 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3559 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3562 if (_e_comp_object_hooks_walking == 0)
3564 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3568 _e_comp_object_hooks_delete++;
3571 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3572 E_API E_Comp_Object_Intercept_Hook *
3573 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3575 E_Comp_Object_Intercept_Hook *ch;
3577 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3578 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3579 if (!ch) return NULL;
3580 ch->hookpoint = hookpoint;
3582 ch->data = (void*)data;
3583 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3588 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3591 if (_e_comp_object_intercept_hooks_walking == 0)
3593 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3597 _e_comp_object_intercept_hooks_delete++;
3602 e_comp_object_util_add(Evas_Object *obj)
3606 E_Comp_Config *conf = e_comp_config_get();
3607 Eina_Bool skip = EINA_FALSE;
3613 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3615 name = evas_object_name_get(obj);
3616 vis = evas_object_visible_get(obj);
3617 o = edje_object_add(e_comp->evas);
3618 evas_object_data_set(o, "comp_object", (void*)1);
3620 skip = (!strncmp(name, "noshadow", 8));
3622 evas_object_data_set(o, "comp_object_skip", (void*)1);
3624 if (conf->shadow_style)
3626 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3627 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3630 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3631 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3632 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3634 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3636 evas_object_geometry_get(obj, &x, &y, &w, &h);
3637 evas_object_geometry_set(o, x, y, w, h);
3638 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3640 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3642 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3643 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3644 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3645 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3646 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3647 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3649 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3651 edje_object_part_swallow(o, "e.swallow.content", obj);
3653 _e_comp_object_event_add(o);
3656 evas_object_show(o);
3661 /* utility functions for deleting objects when their "owner" is deleted */
3663 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3668 EINA_SAFETY_ON_NULL_RETURN(to_del);
3669 l = evas_object_data_get(obj, "comp_object-to_del");
3670 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3671 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3672 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3676 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3681 EINA_SAFETY_ON_NULL_RETURN(to_del);
3682 l = evas_object_data_get(obj, "comp_object-to_del");
3684 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3687 /////////////////////////////////////////////////////////
3689 EINTERN Evas_Object *
3690 e_comp_object_client_add(E_Client *ec)
3695 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3696 if (ec->frame) return NULL;
3697 _e_comp_smart_init();
3698 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3699 cw = evas_object_smart_data_get(o);
3700 if (!cw) return NULL;
3701 evas_object_data_set(o, "E_Client", ec);
3704 evas_object_data_set(o, "comp_object", (void*)1);
3706 _e_comp_object_event_add(o);
3711 /* utility functions for getting client inset */
3713 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3716 if (!cw->client_inset.calc)
3722 if (ax) *ax = x - cw->client_inset.l;
3723 if (ay) *ay = y - cw->client_inset.t;
3727 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3730 if (!cw->client_inset.calc)
3736 if (ax) *ax = x + cw->client_inset.l;
3737 if (ay) *ay = y + cw->client_inset.t;
3741 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3744 if (!cw->client_inset.calc)
3750 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3751 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3755 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3758 if (!cw->client_inset.calc)
3764 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3765 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3769 e_comp_object_client_get(Evas_Object *obj)
3774 /* FIXME: remove this when eo is used */
3775 o = evas_object_data_get(obj, "comp_smart_obj");
3777 return e_comp_object_client_get(o);
3778 return cw ? cw->ec : NULL;
3782 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3785 if (cw->frame_extends)
3786 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3791 if (w) *w = cw->ec->w;
3792 if (h) *h = cw->ec->h;
3797 e_comp_object_util_zone_get(Evas_Object *obj)
3799 E_Zone *zone = NULL;
3803 zone = e_comp_zone_find_by_ec(cw->ec);
3808 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3809 zone = e_comp_zone_xy_get(x, y);
3815 e_comp_object_util_center(Evas_Object *obj)
3817 int x, y, w, h, ow, oh;
3822 zone = e_comp_object_util_zone_get(obj);
3823 EINA_SAFETY_ON_NULL_RETURN(zone);
3824 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3825 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3826 ow = cw->ec->w, oh = cw->ec->h;
3828 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3829 x = x + (w - ow) / 2;
3830 y = y + (h - oh) / 2;
3831 evas_object_move(obj, x, y);
3835 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3837 int x, y, w, h, ow, oh;
3840 EINA_SAFETY_ON_NULL_RETURN(on);
3841 evas_object_geometry_get(on, &x, &y, &w, &h);
3842 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3843 ow = cw->ec->w, oh = cw->ec->h;
3845 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3846 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3850 e_comp_object_util_fullscreen(Evas_Object *obj)
3855 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3858 evas_object_move(obj, 0, 0);
3859 evas_object_resize(obj, e_comp->w, e_comp->h);
3864 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3872 ow = cw->w, oh = cw->h;
3874 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3875 zone = e_comp_object_util_zone_get(obj);
3876 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3877 if (x) *x = zx + (zw - ow) / 2;
3878 if (y) *y = zy + (zh - oh) / 2;
3882 e_comp_object_input_objs_del(Evas_Object *obj)
3885 E_Input_Rect_Data *input_rect_data;
3886 E_Input_Rect_Smart_Data *input_rect_sd;
3891 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3892 if (!input_rect_sd) return;
3894 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3896 if (input_rect_data->obj)
3898 evas_object_smart_member_del(input_rect_data->obj);
3899 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3901 E_FREE(input_rect_data);
3906 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3909 E_Input_Rect_Data *input_rect_data = NULL;
3910 E_Input_Rect_Smart_Data *input_rect_sd;
3911 int client_w, client_h;
3913 if (cw->ec->client.w)
3914 client_w = cw->ec->client.w;
3916 client_w = cw->ec->w;
3918 if (cw->ec->client.h)
3919 client_h = cw->ec->client.h;
3921 client_h = cw->ec->h;
3923 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3927 _e_comp_input_obj_smart_init();
3928 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3929 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3930 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3933 input_rect_sd->cw = cw;
3936 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3939 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3940 if (input_rect_data)
3942 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3943 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3947 if ((input_rect_data) &&
3948 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3950 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3951 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3952 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3953 evas_object_clip_set(input_rect_data->obj, cw->clip);
3954 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3955 evas_object_geometry_set(input_rect_data->obj,
3956 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3957 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3958 evas_object_pass_events_set(cw->default_input_obj, 1);
3959 evas_object_pass_events_set(cw->obj, 1);
3962 evas_object_show(input_rect_data->obj);
3963 evas_object_show(cw->input_obj);
3968 evas_object_smart_member_del(cw->input_obj);
3969 E_FREE_FUNC(cw->input_obj, evas_object_del);
3970 evas_object_pass_events_set(cw->default_input_obj, 0);
3971 evas_object_pass_events_set(cw->obj, 0);
3976 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
3979 E_Input_Rect_Smart_Data *input_rect_sd;
3980 E_Input_Rect_Data *input_rect_data;
3983 if (!cw->input_obj) return;
3985 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3988 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3990 *list = eina_list_append(*list, &input_rect_data->rect);
3996 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
3999 if (l) *l = cw->client_inset.l;
4000 if (r) *r = cw->client_inset.r;
4001 if (t) *t = cw->client_inset.t;
4002 if (b) *b = cw->client_inset.b;
4005 /* set geometry for CSD */
4007 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4013 if (cw->frame_object)
4014 CRI("ACK! ec:%p", cw->ec);
4015 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4016 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4017 calc = cw->client_inset.calc;
4018 cw->client_inset.calc = l || r || t || b;
4019 eina_stringshare_replace(&cw->frame_theme, "borderless");
4020 if (cw->client_inset.calc)
4022 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4023 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4024 e_client_size_set(cw->ec, tw, th);
4026 else if (cw->ec->maximized || cw->ec->fullscreen)
4028 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4029 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4031 if (!cw->ec->new_client)
4033 if (calc && cw->client_inset.calc)
4035 tx = cw->ec->x - (l - cw->client_inset.l);
4036 ty = cw->ec->y - (t - cw->client_inset.t);
4037 e_client_pos_set(cw->ec, tx, ty);
4039 cw->ec->changes.pos = cw->ec->changes.size = 1;
4042 cw->client_inset.l = l;
4043 cw->client_inset.r = r;
4044 cw->client_inset.t = t;
4045 cw->client_inset.b = b;
4049 e_comp_object_frame_allowed(Evas_Object *obj)
4051 API_ENTRY EINA_FALSE;
4052 return (cw->frame_object || (!cw->client_inset.calc));
4056 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4058 API_ENTRY EINA_FALSE;
4059 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4060 eina_stringshare_replace(&cw->frame_name, name);
4061 if (cw->frame_object)
4062 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4067 e_comp_object_frame_exists(Evas_Object *obj)
4069 API_ENTRY EINA_FALSE;
4070 return !!cw->frame_object;
4074 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4076 Evas_Object *o, *pbg;
4079 Eina_Stringshare *theme;
4081 API_ENTRY EINA_FALSE;
4083 if (!e_util_strcmp(cw->frame_theme, name))
4084 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4085 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4086 return _e_comp_object_shadow_setup(cw);
4087 pbg = cw->frame_object;
4088 theme = eina_stringshare_add(name);
4090 if (cw->frame_object)
4094 w = cw->ec->w, h = cw->ec->h;
4095 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4096 if ((cw->ec->w != w) || (cw->ec->h != h))
4098 cw->ec->changes.size = 1;
4101 E_FREE_FUNC(cw->frame_object, evas_object_del);
4102 if (!name) goto reshadow;
4104 o = edje_object_add(e_comp->evas);
4105 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4106 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4107 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4109 cw->frame_object = NULL;
4111 eina_stringshare_del(cw->frame_theme);
4112 cw->frame_theme = theme;
4117 if (theme != e_config->theme_default_border_style)
4119 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4120 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4124 ok = e_theme_edje_object_set(o, "base/theme/border",
4125 "e/widgets/border/default/border");
4126 if (ok && (theme == e_config->theme_default_border_style))
4128 /* Reset default border style to default */
4129 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4130 e_config_save_queue();
4137 cw->frame_object = o;
4138 eina_stringshare_del(cw->frame_theme);
4139 cw->frame_theme = theme;
4140 evas_object_name_set(o, "cw->frame_object");
4143 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4147 cw->ec->changes.icon = 1;
4153 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4158 _e_comp_object_shadow_setup(cw);
4161 int old_x, old_y, new_x = 0, new_y = 0;
4163 old_x = cw->x, old_y = cw->y;
4165 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4167 new_x = cw->ec->x, new_y = cw->ec->y;
4168 else if (cw->ec->placed || (!cw->ec->new_client))
4170 /* if no previous frame:
4171 * - reapply client_inset
4176 if (cw->ec->changes.size)
4184 zone = e_comp_zone_find_by_ec(cw->ec);
4187 x = cw->ec->client.x, y = cw->ec->client.y;
4188 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4189 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4191 new_x = x, new_y = y;
4194 if (old_x != new_x || old_y != new_y)
4196 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4197 cw->y = cw->x = -99999;
4198 evas_object_move(obj, new_x, new_y);
4202 if (cw->ec->maximized)
4204 cw->ec->changes.need_maximize = 1;
4207 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4208 if (cw->frame_object)
4210 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4213 cw->frame_extends = 0;
4214 evas_object_del(pbg);
4219 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4221 E_Comp_Object_Mover *prov;
4224 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4225 edje_object_signal_emit(cw->shobj, sig, src);
4226 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4227 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4228 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4230 /* start with highest priority callback first */
4231 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4233 if (!e_util_glob_match(sig, prov->sig)) continue;
4234 if (prov->func(prov->data, obj, sig)) break;
4239 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4241 /* FIXME: at some point I guess this should use eo to inherit
4242 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4243 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4246 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4250 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4253 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4257 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4260 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4264 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4267 Eina_Rectangle rect;
4270 if (cw->ec->input_only || (!cw->updates)) return;
4271 if (cw->nocomp) return;
4272 rect.x = x, rect.y = y;
4273 rect.w = w, rect.h = h;
4274 evas_object_smart_callback_call(obj, "damage", &rect);
4276 if (e_comp_is_on_overlay(cw->ec))
4278 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4279 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4280 * E module attempts to block screen update due to the particular policy.
4282 if (e_pixmap_resource_get(cw->ec->pixmap))
4283 cw->hwc_need_update = EINA_TRUE;
4286 /* ignore overdraw */
4287 if (cw->updates_full)
4289 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4290 e_comp_object_render_update_add(obj);
4292 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4293 evas_object_show(cw->smart_obj);
4297 /* clip rect to client surface */
4298 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4299 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4300 /* if rect is the total size of the client after clip, clear the updates
4301 * since this is guaranteed to be the whole region anyway
4303 eina_tiler_area_size_get(cw->updates, &tw, &th);
4304 if ((w > tw) || (h > th))
4306 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4307 eina_tiler_clear(cw->updates);
4308 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4310 tw = cw->ec->client.w, th = cw->ec->client.h;
4312 if ((!x) && (!y) && (w == tw) && (h == th))
4314 eina_tiler_clear(cw->updates);
4315 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4316 cw->updates_full = 1;
4317 cw->update_count = 0;
4320 if (cw->update_count > UPDATE_MAX)
4322 /* this is going to get really dumb, so just update the whole thing */
4323 eina_tiler_clear(cw->updates);
4324 cw->update_count = cw->updates_full = 1;
4325 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4326 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4330 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4331 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4333 cw->updates_exist = 1;
4334 e_comp_object_render_update_add(obj);
4336 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4337 evas_object_show(cw->smart_obj);
4341 e_comp_object_damage_exists(Evas_Object *obj)
4343 API_ENTRY EINA_FALSE;
4344 return cw->updates_exist;
4348 e_comp_object_render_update_add(Evas_Object *obj)
4352 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4353 if (cw->render_update_lock.lock) return;
4354 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4358 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4360 e_comp_render_queue();
4364 e_comp_object_render_update_del(Evas_Object *obj)
4368 if (cw->ec->input_only || (!cw->updates)) return;
4369 if (!cw->update) return;
4371 /* this gets called during comp animating to clear the update flag */
4372 if (e_comp->grabbed) return;
4373 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4374 if (!e_comp->updates)
4376 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4377 if (e_comp->render_animator)
4378 ecore_animator_freeze(e_comp->render_animator);
4383 e_comp_object_shape_apply(Evas_Object *obj)
4387 unsigned int i, *pix, *p;
4391 if (!cw->ec) return; //NYI
4392 if (cw->external_content) return;
4395 if ((cw->ec->shape_rects_num >= 1) &&
4396 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4401 ERR("BUGGER: shape with native surface? cw=%p", cw);
4404 evas_object_image_size_get(cw->obj, &w, &h);
4405 if ((w < 1) || (h < 1)) return;
4408 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4409 _e_comp_object_alpha_set(cw);
4410 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4411 evas_object_image_alpha_set(o, 1);
4413 p = pix = evas_object_image_data_get(cw->obj, 1);
4416 evas_object_image_data_set(cw->obj, pix);
4421 unsigned char *spix, *sp;
4423 spix = calloc(w * h, sizeof(unsigned char));
4425 for (i = 0; i < cw->ec->shape_rects_num; i++)
4429 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4430 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4431 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4432 sp = spix + (w * ry) + rx;
4433 for (py = 0; py < rh; py++)
4435 for (px = 0; px < rw; px++)
4443 for (py = 0; py < h; py++)
4445 for (px = 0; px < w; px++)
4447 unsigned int mask, imask;
4449 mask = ((unsigned int)(*sp)) << 24;
4451 imask |= imask >> 8;
4452 imask |= imask >> 8;
4453 *p = mask | (*p & imask);
4454 //if (*sp) *p = 0xff000000 | *p;
4455 //else *p = 0x00000000;
4464 for (py = 0; py < h; py++)
4466 for (px = 0; px < w; px++)
4470 evas_object_image_data_set(cw->obj, pix);
4471 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4472 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4474 evas_object_image_data_set(o, pix);
4475 evas_object_image_data_update_add(o, 0, 0, w, h);
4477 // don't need to fix alpha chanel as blending
4478 // should be totally off here regardless of
4479 // alpha channel content
4483 _e_comp_object_clear(E_Comp_Object *cw)
4488 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4490 if (cw->render_update_lock.lock) return;
4493 e_pixmap_clear(cw->ec->pixmap);
4495 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4496 evas_object_image_size_set(cw->obj, 1, 1);
4497 evas_object_image_data_set(cw->obj, NULL);
4498 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4500 evas_object_image_size_set(o, 1, 1);
4501 evas_object_image_data_set(o, NULL);
4504 e_comp_object_render_update_del(cw->smart_obj);
4508 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4512 API_ENTRY EINA_FALSE;
4514 if (cw->transparent.set == set)
4519 evas_object_color_get(obj, &r, &g, &b, &a);
4520 evas_object_color_set(obj, 0, 0, 0, 0);
4522 cw->transparent.user_r = r;
4523 cw->transparent.user_g = g;
4524 cw->transparent.user_b = b;
4525 cw->transparent.user_a = a;
4527 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4529 cw->transparent.user_r,
4530 cw->transparent.user_g,
4531 cw->transparent.user_b,
4532 cw->transparent.user_a);
4534 cw->transparent.set = EINA_TRUE;
4538 cw->transparent.set = EINA_FALSE;
4540 evas_object_color_set(obj,
4541 cw->transparent.user_r,
4542 cw->transparent.user_g,
4543 cw->transparent.user_b,
4544 cw->transparent.user_a);
4546 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4548 cw->transparent.user_r,
4549 cw->transparent.user_g,
4550 cw->transparent.user_b,
4551 cw->transparent.user_a);
4557 /* helper function to simplify toggling of redirection for display servers which support it */
4559 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4564 if (cw->redirected == set) return;
4565 cw->redirected = set;
4566 if (cw->external_content) return;
4568 e_comp_object_map_update(obj);
4572 if (cw->updates_exist)
4573 e_comp_object_render_update_add(obj);
4575 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4577 _e_comp_object_transparent_set(obj, EINA_FALSE);
4578 evas_object_smart_callback_call(obj, "redirected", NULL);
4582 _e_comp_object_clear(cw);
4583 _e_comp_object_transparent_set(obj, EINA_TRUE);
4584 evas_object_smart_callback_call(obj, "unredirected", NULL);
4589 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4592 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4594 if (cw->buffer_destroy_listener.notify)
4596 cw->buffer_destroy_listener.notify = NULL;
4597 wl_list_remove(&cw->buffer_destroy_listener.link);
4600 if (e_object_is_del(E_OBJECT(cw->ec)))
4602 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4607 /* if it's current displaying buffer, do not remove its content */
4608 if (!evas_object_visible_get(cw->ec->frame))
4609 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4614 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4619 if (cw->buffer_destroy_listener.notify)
4621 wl_list_remove(&cw->buffer_destroy_listener.link);
4622 cw->buffer_destroy_listener.notify = NULL;
4625 if (cw->tbm_surface)
4627 tbm_surface_internal_unref(cw->tbm_surface);
4628 cw->tbm_surface = NULL;
4633 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4635 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4636 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4638 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4640 tbm_surface_internal_ref(ns->data.tbm.buffer);
4641 cw->tbm_surface = ns->data.tbm.buffer;
4645 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4646 evas_object_image_native_surface_set(cw->obj, ns);
4650 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4652 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4653 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4654 evas_object_image_native_surface_set(o, ns);
4661 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4663 Evas_Native_Surface ns;
4666 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4667 if (cw->ec->input_only) return;
4668 if (cw->external_content) return;
4669 if (cw->render_update_lock.lock) return;
4672 memset(&ns, 0, sizeof(Evas_Native_Surface));
4676 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4677 set = (!cw->ec->shaped);
4679 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4683 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4687 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4690 if (cw->ec->input_only) return;
4693 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4694 _e_comp_object_alpha_set(cw);
4696 e_comp_object_native_surface_set(obj, cw->native);
4697 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4701 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4707 if (cw->blanked == set) return;
4709 _e_comp_object_alpha_set(cw);
4712 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4713 evas_object_image_data_set(cw->obj, NULL);
4717 e_comp_object_native_surface_set(obj, 1);
4718 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4722 _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)
4727 if (!_damage_trace) return;
4731 if (!evas_object_visible_get(cw->obj)) return;
4733 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4735 o = evas_object_rectangle_add(e_comp->evas);
4736 evas_object_layer_set(o, E_LAYER_MAX);
4737 evas_object_name_set(o, "damage_trace");
4738 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4739 evas_object_resize(o, dmg_w, dmg_h);
4740 evas_object_color_set(o, 0, 128, 0, 128);
4741 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4742 evas_object_pass_events_set(o, EINA_TRUE);
4743 evas_object_show(o);
4745 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4747 dmg_w, dmg_h, dmg_x, dmg_y,
4748 origin->w, origin->h, origin->x, origin->y);
4750 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4753 /* mark an object as dirty and setup damages */
4755 e_comp_object_dirty(Evas_Object *obj)
4758 Eina_Rectangle *rect;
4762 Eina_Bool dirty, visible;
4766 if (cw->external_content) return;
4767 if (!cw->redirected) return;
4768 if (cw->render_update_lock.lock)
4770 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4773 /* only actually dirty if pixmap is available */
4774 if (!e_pixmap_resource_get(cw->ec->pixmap))
4776 // e_pixmap_size_get returns last attached buffer size
4777 // eventhough it is destroyed
4778 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4781 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4782 visible = cw->visible;
4783 if (!dirty) w = h = 1;
4784 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4786 evas_object_image_data_set(cw->obj, NULL);
4787 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4788 evas_object_image_size_set(cw->obj, tw, th);
4789 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4790 if (cw->pending_updates)
4791 eina_tiler_area_size_set(cw->pending_updates, w, h);
4792 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4794 evas_object_image_pixels_dirty_set(o, dirty);
4796 evas_object_image_data_set(o, NULL);
4797 evas_object_image_size_set(o, tw, th);
4798 visible |= evas_object_visible_get(o);
4802 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4806 e_comp_object_native_surface_set(obj, 1);
4808 m = _e_comp_object_map_damage_transform_get(cw->ec);
4809 it = eina_tiler_iterator_new(cw->updates);
4810 EINA_ITERATOR_FOREACH(it, rect)
4812 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4813 * of evas engine and doesn't convert damage according to evas_map.
4814 * so damage of evas_object_image use surface coordinate.
4818 int damage_x, damage_y, damage_w, damage_h;
4820 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4821 &damage_x, &damage_y, &damage_w, &damage_h);
4822 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4823 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4827 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4828 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4831 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4832 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4833 if (cw->pending_updates)
4834 eina_tiler_rect_add(cw->pending_updates, rect);
4836 eina_iterator_free(it);
4837 if (m) e_map_free(m);
4838 if (cw->pending_updates)
4839 eina_tiler_clear(cw->updates);
4842 cw->pending_updates = cw->updates;
4843 cw->updates = eina_tiler_new(w, h);
4844 eina_tiler_tile_size_set(cw->updates, 1, 1);
4846 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4847 evas_object_smart_callback_call(obj, "dirty", NULL);
4848 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4849 /* force render if main object is hidden but mirrors are visible */
4850 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4851 e_comp_object_render(obj);
4855 e_comp_object_render(Evas_Object *obj)
4862 API_ENTRY EINA_FALSE;
4864 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4865 if (cw->ec->input_only) return EINA_TRUE;
4866 if (cw->external_content) return EINA_TRUE;
4867 if (cw->native) return EINA_FALSE;
4868 /* if comp object is not redirected state, comp object should not be set by newly committed data
4869 because image size of comp object is 1x1 and it should not be shown on canvas */
4870 if (!cw->redirected) return EINA_TRUE;
4871 if (cw->render_update_lock.lock)
4873 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4876 e_comp_object_render_update_del(obj);
4877 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4879 if (!cw->pending_updates)
4881 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4882 evas_object_image_data_set(cw->obj, NULL);
4883 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4884 evas_object_image_data_set(o, NULL);
4888 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4890 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4892 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4895 e_pixmap_image_refresh(cw->ec->pixmap);
4896 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4899 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4900 e_pixmap_image_data_ref(cw->ec->pixmap);
4902 /* set pixel data */
4903 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4904 _e_comp_object_alpha_set(cw);
4905 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4907 evas_object_image_data_set(o, pix);
4908 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4909 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4912 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4914 e_comp_client_post_update_add(cw->ec);
4919 /* create a duplicate of an evas object */
4921 e_comp_object_util_mirror_add(Evas_Object *obj)
4925 unsigned int *pix = NULL;
4926 Eina_Bool argb = EINA_FALSE;
4931 cw = evas_object_data_get(obj, "comp_mirror");
4934 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4935 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4936 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4937 evas_object_image_alpha_set(o, 1);
4938 evas_object_image_source_set(o, obj);
4941 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4942 if (cw->external_content)
4944 ERR("%p of client %p is external content.", obj, cw->ec);
4947 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4948 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4949 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4950 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4951 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4952 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4953 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4954 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4955 evas_object_data_set(o, "comp_mirror", cw);
4957 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4958 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4960 evas_object_image_size_set(o, tw, th);
4963 pix = evas_object_image_data_get(cw->obj, 0);
4969 evas_object_image_native_surface_set(o, cw->ns);
4972 Evas_Native_Surface ns;
4973 memset(&ns, 0, sizeof(Evas_Native_Surface));
4974 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
4975 evas_object_image_native_surface_set(o, &ns);
4980 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
4981 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
4983 (e_pixmap_image_exists(cw->ec->pixmap)))
4984 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4986 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
4993 dirty = evas_object_image_pixels_dirty_get(cw->obj);
4994 evas_object_image_pixels_dirty_set(o, dirty);
4995 evas_object_image_data_set(o, pix);
4996 evas_object_image_data_set(cw->obj, pix);
4998 evas_object_image_data_update_add(o, 0, 0, tw, th);
5003 //////////////////////////////////////////////////////
5006 e_comp_object_effect_allowed_get(Evas_Object *obj)
5008 API_ENTRY EINA_FALSE;
5010 if (!cw->shobj) return EINA_FALSE;
5011 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5012 return !e_comp_config_get()->match.disable_borders;
5015 /* setup an api effect for a client */
5017 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5020 Eina_Stringshare *grp;
5021 E_Comp_Config *config;
5022 Eina_Bool loaded = EINA_FALSE;
5024 API_ENTRY EINA_FALSE;
5025 if (!cw->shobj) return EINA_FALSE; //input window
5027 if (!effect) effect = "none";
5028 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5030 config = e_comp_config_get();
5031 if ((config) && (config->effect_file))
5033 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5035 cw->effect_set = EINA_TRUE;
5042 edje_object_file_get(cw->effect_obj, NULL, &grp);
5043 cw->effect_set = !eina_streq(effect, "none");
5044 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5045 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5047 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5048 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5049 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5051 if (cw->effect_running)
5053 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5056 cw->effect_set = EINA_FALSE;
5057 return cw->effect_set;
5061 if (cw->effect_running)
5063 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5066 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5067 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5068 if (cw->effect_clip)
5070 evas_object_clip_unset(cw->clip);
5071 cw->effect_clip = 0;
5073 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5075 _e_comp_object_dim_update(cw);
5077 return cw->effect_set;
5080 /* set params for embryo scripts in effect */
5082 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5084 Edje_Message_Int_Set *msg;
5088 EINA_SAFETY_ON_NULL_RETURN(params);
5089 EINA_SAFETY_ON_FALSE_RETURN(count);
5090 if (!cw->effect_set) return;
5092 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5093 msg->count = (int)count;
5094 for (x = 0; x < count; x++)
5095 msg->val[x] = params[x];
5096 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5097 edje_object_message_signal_process(cw->effect_obj);
5101 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5103 Edje_Signal_Cb end_cb;
5105 E_Comp_Object *cw = data;
5107 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5108 cw->effect_running = 0;
5109 if (!_e_comp_object_animating_end(cw)) return;
5111 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5113 evas_object_data_del(cw->smart_obj, "effect_running");
5114 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5115 e_comp_visibility_calculation_set(EINA_TRUE);
5118 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5119 if (!end_cb) return;
5120 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5121 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5122 end_cb(end_data, cw->smart_obj, emission, source);
5125 /* clip effect to client's zone */
5127 e_comp_object_effect_clip(Evas_Object *obj)
5131 zone = e_comp_zone_find_by_ec(cw->ec);
5133 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5134 if (!cw->effect_clip_able) return;
5135 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5136 cw->effect_clip = 1;
5139 /* unclip effect from client's zone */
5141 e_comp_object_effect_unclip(Evas_Object *obj)
5144 if (!cw->effect_clip) return;
5145 evas_object_clip_unset(cw->smart_obj);
5146 cw->effect_clip = 0;
5149 /* start effect, running end_cb after */
5151 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5153 API_ENTRY EINA_FALSE;
5154 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5155 if (!cw->effect_set) return EINA_FALSE;
5157 if (cw->effect_running)
5159 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5162 e_comp_object_effect_clip(obj);
5163 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5165 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5166 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5167 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5168 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5170 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5171 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5173 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5174 _e_comp_object_animating_begin(cw);
5175 cw->effect_running = 1;
5179 /* stop a currently-running effect immediately */
5181 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5184 Edje_Signal_Cb end_cb_before = NULL;
5185 void *end_data_before = NULL;
5186 API_ENTRY EINA_FALSE;
5188 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5189 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5191 if (end_cb_before != end_cb) return EINA_TRUE;
5192 e_comp_object_effect_unclip(obj);
5193 if (cw->effect_clip)
5195 evas_object_clip_unset(cw->effect_obj);
5196 cw->effect_clip = 0;
5198 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5199 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5201 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5203 evas_object_data_del(cw->smart_obj, "effect_running");
5204 e_comp_visibility_calculation_set(EINA_TRUE);
5207 cw->effect_running = 0;
5208 ret = _e_comp_object_animating_end(cw);
5210 if ((ret) && (end_cb_before))
5212 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5213 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5220 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5222 return a->pri - b->pri;
5225 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5226 E_API E_Comp_Object_Mover *
5227 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5229 E_Comp_Object_Mover *prov;
5231 prov = E_NEW(E_Comp_Object_Mover, 1);
5232 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5233 prov->func = provider;
5234 prov->data = (void*)data;
5237 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5238 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5243 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5245 EINA_SAFETY_ON_NULL_RETURN(prov);
5246 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5251 e_comp_object_effect_object_get(Evas_Object *obj)
5255 return cw->effect_obj;
5259 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5261 API_ENTRY EINA_FALSE;
5262 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5263 if (!cw->effect_set) return EINA_FALSE;
5270 ////////////////////////////////////
5273 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5275 if (e_comp->autoclose.obj)
5277 e_comp_ungrab_input(0, 1);
5278 if (e_comp->autoclose.del_cb)
5279 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5280 else if (!already_del)
5282 evas_object_hide(e_comp->autoclose.obj);
5283 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5285 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5287 e_comp->autoclose.obj = NULL;
5288 e_comp->autoclose.data = NULL;
5289 e_comp->autoclose.del_cb = NULL;
5290 e_comp->autoclose.key_cb = NULL;
5291 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5295 _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)
5297 _e_comp_object_autoclose_cleanup(0);
5301 _e_comp_object_autoclose_setup(Evas_Object *obj)
5303 if (!e_comp->autoclose.rect)
5305 /* create rect just below autoclose object to catch mouse events */
5306 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5307 evas_object_move(e_comp->autoclose.rect, 0, 0);
5308 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5309 evas_object_show(e_comp->autoclose.rect);
5310 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5311 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5312 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5313 e_comp_grab_input(0, 1);
5315 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5316 evas_object_focus_set(obj, 1);
5320 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5322 _e_comp_object_autoclose_setup(obj);
5323 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5327 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5329 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5330 _e_comp_object_autoclose_cleanup(1);
5331 if (e_client_focused_get()) return;
5333 E_Zone *zone = e_zone_current_get();
5336 e_zone_focus_reset(zone);
5340 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5344 if (e_comp->autoclose.obj)
5346 if (e_comp->autoclose.obj == obj) return;
5347 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5348 e_comp->autoclose.obj = obj;
5349 e_comp->autoclose.del_cb = del_cb;
5350 e_comp->autoclose.key_cb = cb;
5351 e_comp->autoclose.data = (void*)data;
5352 if (evas_object_visible_get(obj))
5353 _e_comp_object_autoclose_setup(obj);
5355 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5356 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5359 e_comp->autoclose.obj = obj;
5360 e_comp->autoclose.del_cb = del_cb;
5361 e_comp->autoclose.key_cb = cb;
5362 e_comp->autoclose.data = (void*)data;
5363 if (evas_object_visible_get(obj))
5364 _e_comp_object_autoclose_setup(obj);
5366 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5367 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5371 e_comp_object_is_animating(Evas_Object *obj)
5375 return cw->animating;
5379 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5383 if ((cw->external_content) &&
5384 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5386 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5387 "But current external content is %d object for %p.",
5388 cw->content_type, cw->ec);
5392 cw->user_alpha_set = EINA_TRUE;
5393 cw->user_alpha = alpha;
5395 if (!cw->obj) return;
5397 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5399 evas_object_image_alpha_set(cw->obj, alpha);
5401 if ((!cw->native) && (!cw->external_content))
5402 evas_object_image_data_set(cw->obj, NULL);
5406 e_comp_object_alpha_get(Evas_Object *obj)
5408 API_ENTRY EINA_FALSE;
5410 return evas_object_image_alpha_get(cw->obj);
5414 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5416 Eina_Bool mask_set = EINA_FALSE;
5420 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5421 if (cw->ec->input_only) return;
5428 o = evas_object_rectangle_add(e_comp->evas);
5429 evas_object_color_set(o, 0, 0, 0, 0);
5430 evas_object_clip_set(o, cw->clip);
5431 evas_object_smart_member_add(o, obj);
5432 evas_object_move(o, 0, 0);
5433 evas_object_resize(o, cw->w, cw->h);
5434 /* save render op value to restore when clear a mask.
5436 * NOTE: DO NOT change the render op on ec->frame while mask object
5437 * is set. it will overwrite the changed op value. */
5438 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5439 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5440 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5441 if (cw->visible) evas_object_show(o);
5444 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5445 ELOGF("COMP", " |mask_obj", cw->ec);
5446 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5453 evas_object_smart_member_del(cw->mask.obj);
5454 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5456 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5457 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5463 e_comp_object_mask_has(Evas_Object *obj)
5465 API_ENTRY EINA_FALSE;
5467 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5471 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5476 if ((cw->external_content) &&
5477 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5479 WRN("Can set up size to ONLY evas \"image\" object. "
5480 "But current external content is %d object for %p.",
5481 cw->content_type, cw->ec);
5485 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5487 evas_object_image_size_set(cw->obj, tw, th);
5491 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5493 Eina_Bool transform_set = EINA_FALSE;
5495 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5496 if (cw->ec->input_only) return;
5498 transform_set = !!set;
5502 if (!cw->transform_bg_obj)
5504 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5505 evas_object_move(o, 0, 0);
5506 evas_object_resize(o, 1, 1);
5507 if (cw->transform_bg_color.a >= 255)
5508 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5510 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5511 evas_object_color_set(o,
5512 cw->transform_bg_color.r,
5513 cw->transform_bg_color.g,
5514 cw->transform_bg_color.b,
5515 cw->transform_bg_color.a);
5516 if (cw->visible) evas_object_show(o);
5518 cw->transform_bg_obj = o;
5519 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5521 _e_comp_object_transform_obj_stack_update(obj);
5525 if (cw->transform_bg_obj)
5527 evas_object_smart_member_del(cw->transform_bg_obj);
5528 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5534 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5538 cw->transform_bg_color.r = r;
5539 cw->transform_bg_color.g = g;
5540 cw->transform_bg_color.b = b;
5541 cw->transform_bg_color.a = a;
5543 if (cw->transform_bg_obj)
5545 evas_object_color_set(cw->transform_bg_obj,
5546 cw->transform_bg_color.r,
5547 cw->transform_bg_color.g,
5548 cw->transform_bg_color.b,
5549 cw->transform_bg_color.a);
5554 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5557 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5558 if (cw->ec->input_only) return;
5559 if (!cw->transform_bg_obj) return;
5561 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5565 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5568 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5569 if (cw->ec->input_only) return;
5570 if (!cw->transform_bg_obj) return;
5572 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5576 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5578 Eina_Bool transform_set = EINA_FALSE;
5580 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5581 if (cw->ec->input_only) return;
5583 transform_set = !!set;
5587 if (!cw->transform_tranp_obj)
5589 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5590 evas_object_move(o, 0, 0);
5591 evas_object_resize(o, 1, 1);
5592 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5593 evas_object_color_set(o, 0, 0, 0, 0);
5594 if (cw->visible) evas_object_show(o);
5596 cw->transform_tranp_obj = o;
5597 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5598 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5599 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5601 _e_comp_object_transform_obj_stack_update(obj);
5605 if (cw->transform_tranp_obj)
5607 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5608 evas_object_smart_member_del(cw->transform_tranp_obj);
5609 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5615 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5618 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5619 if (cw->ec->input_only) return;
5620 if (!cw->transform_tranp_obj) return;
5622 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5626 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5629 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5630 if (cw->ec->input_only) return;
5631 if (!cw->transform_tranp_obj) return;
5633 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5637 e_comp_object_layer_update(Evas_Object *obj,
5638 Evas_Object *above, Evas_Object *below)
5640 E_Comp_Object *cw2 = NULL;
5641 Evas_Object *o = NULL;
5646 if (cw->ec->layer_block) return;
5647 if ((above) && (below))
5649 ERR("Invalid layer update request! cw=%p", cw);
5657 layer = evas_object_layer_get(o);
5658 cw2 = evas_object_data_get(o, "comp_obj");
5661 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5663 o = evas_object_above_get(o);
5664 if ((!o) || (o == cw->smart_obj)) break;
5665 if (evas_object_layer_get(o) != layer)
5667 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5672 ec = e_client_top_get();
5673 if (ec) o = ec->frame;
5676 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5680 _e_comp_object_layers_remove(cw);
5683 if (cw2->layer > cw->layer)
5684 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5685 else if (cw2->layer == cw->layer)
5688 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5690 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5692 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5695 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5698 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5702 e_comp_object_layer_get(Evas_Object *obj)
5709 e_comp_object_content_set(Evas_Object *obj,
5710 Evas_Object *content,
5711 E_Comp_Object_Content_Type type)
5713 API_ENTRY EINA_FALSE;
5715 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5716 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5717 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5721 ERR("Can't set e.swallow.content to requested content. "
5722 "Previous comp object should not be changed at all.");
5726 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5728 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5729 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5731 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5732 type, content, cw->ec, cw->ec->pixmap);
5736 cw->external_content = EINA_TRUE;
5739 cw->content_type = type;
5740 e_util_size_debug_set(cw->obj, 1);
5741 evas_object_name_set(cw->obj, "cw->obj");
5742 _e_comp_object_alpha_set(cw);
5745 _e_comp_object_shadow_setup(cw);
5751 e_comp_object_content_unset(Evas_Object *obj)
5753 API_ENTRY EINA_FALSE;
5755 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5756 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5758 if (!cw->obj && !cw->ec->visible)
5760 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5764 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5766 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5772 if (cw->frame_object)
5773 edje_object_part_unswallow(cw->frame_object, cw->obj);
5775 edje_object_part_unswallow(cw->shobj, cw->obj);
5777 evas_object_del(cw->obj);
5778 evas_object_hide(cw->obj);
5782 cw->external_content = EINA_FALSE;
5783 if (cw->ec->is_cursor)
5786 DBG("%p is cursor surface..", cw->ec);
5787 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5789 evas_object_resize(cw->ec->frame, pw, ph);
5790 evas_object_hide(cw->ec->frame);
5795 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5796 cw->obj = evas_object_image_filled_add(e_comp->evas);
5797 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5798 e_util_size_debug_set(cw->obj, 1);
5799 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5800 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5801 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5802 evas_object_name_set(cw->obj, "cw->obj");
5803 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5804 _e_comp_object_alpha_set(cw);
5807 _e_comp_object_shadow_setup(cw);
5812 _e_comp_intercept_show_helper(cw);
5816 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5817 e_comp_object_dirty(cw->smart_obj);
5818 e_comp_object_render(cw->smart_obj);
5819 e_comp_object_render_update_add(obj);
5824 EINTERN Evas_Object *
5825 e_comp_object_content_get(Evas_Object *obj)
5829 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5831 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5833 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5840 E_API E_Comp_Object_Content_Type
5841 e_comp_object_content_type_get(Evas_Object *obj)
5843 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5845 return cw->content_type;
5849 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5852 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5853 E_Comp_Config *conf = e_comp_config_get();
5854 if (cw->ec->input_only) return;
5855 if (!conf->dim_rect_enable) return;
5857 cw->dim.mask_set = mask_set;
5863 if (!cw->dim.enable) return;
5864 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5868 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5870 Eina_Bool mask_set = EINA_FALSE;
5874 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5875 E_Comp_Config *conf = e_comp_config_get();
5876 if (cw->ec->input_only) return;
5877 if (!conf->dim_rect_enable) return;
5883 if (cw->dim.mask_obj)
5885 evas_object_smart_member_del(cw->dim.mask_obj);
5886 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5889 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);
5890 o = evas_object_rectangle_add(e_comp->evas);
5891 evas_object_color_set(o, 0, 0, 0, 0);
5892 evas_object_smart_member_add(o, obj);
5893 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5894 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5896 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5897 if (cw->visible) evas_object_show(o);
5899 cw->dim.mask_obj = o;
5900 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5902 evas_object_layer_set(cw->dim.mask_obj, 9998);
5906 if (cw->dim.mask_obj)
5908 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5909 evas_object_smart_member_del(cw->dim.mask_obj);
5910 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5916 e_comp_object_dim_client_set(E_Client *ec)
5918 E_Comp_Config *conf = e_comp_config_get();
5920 if (!conf->dim_rect_enable) return ;
5921 if (dim_client == ec) return;
5923 Eina_Bool prev_dim = EINA_FALSE;
5924 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5926 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5927 prev_dim = EINA_TRUE;
5929 if (prev_dim && dim_client->visible && ec)
5931 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5932 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5936 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5937 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5943 e_comp_object_dim_client_get(void)
5945 E_Comp_Config *conf = e_comp_config_get();
5947 if (!conf->dim_rect_enable ) return NULL;
5953 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
5956 char emit[32] = "\0";
5957 E_Comp_Config *conf = e_comp_config_get();
5960 if (!conf->dim_rect_enable) return;
5961 if (!cw->effect_obj) return;
5962 if (enable == cw->dim.enable) return;
5964 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
5965 if (noeffect || !conf->dim_rect_effect)
5967 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
5971 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
5974 cw->dim.enable = enable;
5976 if (cw->dim.mask_set && !enable)
5978 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5979 edje_object_signal_emit(cw->effect_obj, emit, "e");
5981 else if (cw->dim.mask_set && enable)
5983 edje_object_signal_emit(cw->effect_obj, emit, "e");
5984 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5988 edje_object_signal_emit(cw->effect_obj, emit, "e");
5993 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
5995 API_ENTRY EINA_FALSE;
5996 E_Comp_Config *conf = e_comp_config_get();
5998 if (!ec) return EINA_FALSE;
5999 if (!conf->dim_rect_enable) return EINA_FALSE;
6001 if (cw->dim.enable) return EINA_TRUE;
6007 _e_comp_object_dim_update(E_Comp_Object *cw)
6009 E_Comp_Config *conf = e_comp_config_get();
6012 if (!conf->dim_rect_enable) return;
6013 if (!cw->effect_obj) return;
6016 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6017 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6019 if (cw->dim.mask_set)
6021 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6027 e_comp_object_clear(Evas_Object *obj)
6031 _e_comp_object_clear(cw);
6035 e_comp_object_hwc_update_exists(Evas_Object *obj)
6037 API_ENTRY EINA_FALSE;
6038 return cw->hwc_need_update;
6043 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6046 cw->hwc_need_update = set;
6050 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6052 API_ENTRY EINA_FALSE;
6053 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6057 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6060 if (cw->indicator.obj != indicator)
6061 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6062 cw->indicator.obj = indicator;
6063 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6067 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6070 if (cw->indicator.obj != indicator) return;
6071 cw->indicator.obj = NULL;
6072 edje_object_part_unswallow(cw->shobj, indicator);
6076 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6079 Edje_Message_Int_Set *msg;
6081 if (!cw->indicator.obj) return;
6083 cw->indicator.w = w;
6084 cw->indicator.h = h;
6086 if (!cw->shobj) return;
6088 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6092 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6093 edje_object_message_signal_process(cw->shobj);
6096 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6098 e_comp_object_map_update(Evas_Object *obj)
6101 E_Client *ec = cw->ec;
6102 E_Comp_Wl_Client_Data *cdata;
6104 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6107 int l, remain = sizeof buffer;
6110 if (e_object_is_del(E_OBJECT(ec))) return;
6111 cdata = e_client_cdata_get(ec);
6114 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6115 * when new buffer is attached.
6117 if (!cdata->buffer_ref.buffer) return;
6119 if ((!cw->redirected) ||
6120 (e_client_video_hw_composition_check(ec)) ||
6121 (!e_comp_wl_output_buffer_transform_get(ec) &&
6122 cdata->scaler.buffer_viewport.buffer.scale == 1))
6124 if (evas_object_map_enable_get(cw->effect_obj))
6126 ELOGF("TRANSFORM", "map: disable", cw->ec);
6127 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6128 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6129 evas_object_resize(cw->effect_obj, tw, th);
6136 EINA_SAFETY_ON_NULL_RETURN(map);
6138 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6144 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6146 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6147 e_map_point_image_uv_set(map, 0, x, y);
6148 l = snprintf(p, remain, "%d,%d", x, y);
6149 p += l, remain -= l;
6151 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6152 e_map_point_image_uv_set(map, 1, x, y);
6153 l = snprintf(p, remain, " %d,%d", x, y);
6154 p += l, remain -= l;
6156 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6157 e_map_point_image_uv_set(map, 2, x, y);
6158 l = snprintf(p, remain, " %d,%d", x, y);
6159 p += l, remain -= l;
6161 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6162 e_map_point_image_uv_set(map, 3, x, y);
6163 l = snprintf(p, remain, " %d,%d", x, y);
6164 p += l, remain -= l;
6166 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6168 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6170 e_comp_object_map_set(cw->effect_obj, map);
6171 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6175 /* if there's screen rotation with comp mode, then ec->effect_obj and
6176 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6178 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6179 evas_object_resize(cw->effect_obj, tw, th);
6183 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6185 API_ENTRY EINA_FALSE;
6187 cw->render_trace = set;
6193 e_comp_object_native_usable_get(Evas_Object *obj)
6195 API_ENTRY EINA_FALSE;
6196 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6198 if (cw->ec->input_only) return EINA_FALSE;
6199 if (cw->external_content) return EINA_FALSE;
6200 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6202 /* just return true value, if it is normal case */
6203 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6206 Evas_Native_Surface *ns;
6207 ns = evas_object_image_native_surface_get(cw->obj);
6209 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6212 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6220 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6222 API_ENTRY EINA_FALSE;
6223 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6224 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6225 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6229 case E_COMP_IMAGE_FILTER_BLUR:
6230 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6232 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6233 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6235 case E_COMP_IMAGE_FILTER_INVERSE:
6236 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6238 case E_COMP_IMAGE_FILTER_NONE:
6240 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6244 cw->image_filter = filter;
6249 EINTERN E_Comp_Image_Filter
6250 e_comp_object_image_filter_get(Evas_Object *obj)
6252 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6253 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6254 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6255 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6257 return cw->image_filter;
6261 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6265 if (!_damage_trace) return;
6267 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6268 evas_object_del(obj);
6270 _damage_trace_post_objs = NULL;
6274 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6276 if (!_damage_trace) return;
6278 _damage_trace_post_objs = _damage_trace_objs;
6279 _damage_trace_objs = NULL;
6283 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6285 if (_damage_trace == onoff) return;
6289 evas_event_callback_add(e_comp->evas,
6290 EVAS_CALLBACK_RENDER_PRE,
6291 _e_comp_object_damage_trace_render_pre_cb,
6294 evas_event_callback_add(e_comp->evas,
6295 EVAS_CALLBACK_RENDER_POST,
6296 _e_comp_object_damage_trace_render_post_cb,
6303 EINA_LIST_FREE(_damage_trace_objs, obj)
6304 evas_object_del(obj);
6306 _damage_trace_objs = NULL;
6308 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6309 evas_object_del(obj);
6311 _damage_trace_post_objs = NULL;
6313 evas_event_callback_del(e_comp->evas,
6314 EVAS_CALLBACK_RENDER_PRE,
6315 _e_comp_object_damage_trace_render_pre_cb);
6317 evas_event_callback_del(e_comp->evas,
6318 EVAS_CALLBACK_RENDER_POST,
6319 _e_comp_object_damage_trace_render_post_cb);
6322 _damage_trace = onoff;
6326 e_comp_object_redirected_get(Evas_Object *obj)
6328 API_ENTRY EINA_FALSE;
6329 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6331 return cw->redirected;
6335 e_comp_object_color_visible_get(Evas_Object *obj)
6337 API_ENTRY EINA_FALSE;
6340 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6342 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6346 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6350 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6354 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6362 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6364 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6366 return e_map_set_to_comp_object(em, obj);
6370 e_comp_object_map_get(const Evas_Object *obj)
6372 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6374 return e_map_get_from_comp_object(obj);
6378 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6380 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6382 evas_object_map_enable_set(obj, enable);
6388 e_comp_object_render_update_lock(Evas_Object *obj)
6390 E_Comp_Wl_Buffer *buffer;
6391 struct wayland_tbm_client_queue *cqueue;
6393 API_ENTRY EINA_FALSE;
6395 if (cw->render_update_lock.lock == 0)
6397 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6399 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6400 if ((buffer) && (buffer->resource))
6402 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6404 wayland_tbm_server_client_queue_flush(cqueue);
6407 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6408 e_comp_object_render_update_del(obj);
6410 ELOGF("COMP", "Render update lock enabled", cw->ec);
6413 cw->render_update_lock.lock++;
6419 e_comp_object_render_update_unlock(Evas_Object *obj)
6423 if (cw->render_update_lock.lock == 0)
6426 cw->render_update_lock.lock--;
6428 if (cw->render_update_lock.lock == 0)
6431 if (cw->render_update_lock.pending_move_set)
6433 evas_object_move(obj,
6434 cw->render_update_lock.pending_move_x,
6435 cw->render_update_lock.pending_move_y);
6436 cw->render_update_lock.pending_move_x = 0;
6437 cw->render_update_lock.pending_move_y = 0;
6438 cw->render_update_lock.pending_move_set = EINA_FALSE;
6441 if (cw->render_update_lock.pending_resize_set)
6443 evas_object_resize(obj,
6444 cw->render_update_lock.pending_resize_w,
6445 cw->render_update_lock.pending_resize_h);
6446 cw->render_update_lock.pending_resize_w = 0;
6447 cw->render_update_lock.pending_resize_h = 0;
6448 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6451 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6453 if ((cw->ec->exp_iconify.buffer_flush) &&
6454 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6455 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6456 e_comp_object_clear(obj);
6458 e_comp_object_render_update_add(obj);
6460 ELOGF("COMP", "Render update lock disabled", cw->ec);
6465 e_comp_object_render_update_lock_get(Evas_Object *obj)
6467 API_ENTRY EINA_FALSE;
6469 if (cw->render_update_lock.lock > 0)
6476 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6480 if (cw->transparent.set)
6482 if (r) *r = cw->transparent.user_r;
6483 if (g) *g = cw->transparent.user_g;
6484 if (b) *b = cw->transparent.user_b;
6485 if (a) *a = cw->transparent.user_a;
6489 evas_object_color_get(obj, r, g, b, a);
6494 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6498 evas_object_render_op_set(cw->obj, op);
6501 EINTERN Evas_Render_Op
6502 e_comp_object_render_op_get(Evas_Object *obj)
6504 API_ENTRY EVAS_RENDER_BLEND;
6506 return evas_object_render_op_get(cw->obj);
6510 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6513 wl_signal_add(&cw->events.lower, listener);
6517 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6520 wl_signal_add(&cw->events.show, listener);
6524 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6527 wl_signal_add(&cw->events.hide, listener);