2 #include "e_comp_object_intern.h"
3 #include "e_bindings_intern.h"
4 #include "e_utils_intern.h"
5 #ifdef REFACTOR_DESK_AREA
7 #include "e_comp_canvas_intern.h"
10 #include "e_comp_cfdata_intern.h"
11 #include "e_comp_wl_subsurface_intern.h"
12 #include "e_comp_wl_tbm_intern.h"
13 #include "e_comp_intern.h"
14 #include "e_pixmap_intern.h"
15 #include "e_map_intern.h"
16 #include "e_hwc_window_intern.h"
17 #include "e_hwc_windows_intern.h"
18 #include "e_policy_visibility_intern.h"
19 #include "e_client_video_intern.h"
20 #include "e_client_intern.h"
24 = keys that return objects =
25 - E_Client: the client associated with the object (E_Client*)
26 - comp_smart_obj: cw->smart_obj (Evas_Object*)
27 - comp_obj: cw (E_Comp_Object*)
29 = keys that are bool flags =
30 - client_restack: client needs a protocol-level restack
31 - comp_override: object is triggering a nocomp override to force compositing
32 - comp_ref: object has a ref from visibility animations
33 - comp_showing: object is currently running its show animation
34 - comp_hiding: object is currently running its hiding animation
35 - comp_object: object is a compositor-created object
36 - comp_object_skip: object has a name which prohibits theme shadows
37 - comp_object-to_del: list of objects which will be deleted when this object is deleted
38 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
39 - effect_running: object is animating by external module
42 #define UPDATE_MAX 512 // same as evas
43 #define FAILURE_MAX 2 // seems reasonable
44 #define SMART_NAME "e_comp_object"
45 #define INPUT_OBJ_SMART_NAME "input_object"
47 /* for non-util functions */
48 #define API_ENTRY E_Comp_Object *cw; \
49 cw = evas_object_smart_data_get(obj); \
50 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
52 /* for util functions (obj may or may not be E_Comp_Object */
53 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
56 CRI("YOU PASSED NULL! ARGH!"); \
59 cw = evas_object_smart_data_get(obj); \
60 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
62 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
64 /* enable for lots of client size info in console output */
66 # define e_util_size_debug_set(x, y)
69 /* enable along with display-specific damage INF calls to enable render tracing
73 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
75 #define RENDER_DEBUG(...)
78 typedef struct _E_Input_Rect_Data
84 typedef struct _E_Input_Rect_Smart_Data
86 Eina_List *input_rect_data_list;
88 } E_Input_Rect_Smart_Data;
90 struct E_Comp_Object_Mover
93 E_Comp_Object_Mover_Cb func;
99 static Eina_Inlist *_e_comp_object_movers = NULL;
100 static Evas_Smart *_e_comp_smart = NULL;
101 static Evas_Smart *_e_comp_input_obj_smart = NULL;
103 static int _e_comp_object_hooks_delete = 0;
104 static int _e_comp_object_hooks_walking = 0;
106 static Eina_Inlist *_e_comp_object_hooks[] =
108 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
109 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
110 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
111 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
112 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
113 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
114 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
115 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
118 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
119 static int _e_comp_object_intercept_hooks_delete = 0;
120 static int _e_comp_object_intercept_hooks_walking = 0;
122 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
124 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
125 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
129 static Eina_Bool _damage_trace = EINA_FALSE;
130 static Eina_List *_damage_trace_objs = NULL;
131 static Eina_List *_damage_trace_post_objs = NULL;
133 /* sekrit functionzzz */
134 EINTERN void e_client_focused_set(E_Client *ec);
136 /* emitted every time a new noteworthy comp object is added */
137 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
139 /* ecore event define */
140 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
141 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
142 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
144 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
145 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
146 static void _e_comp_object_dim_update(E_Comp_Object *cw);
147 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
148 #ifdef REFACTOR_DESK_AREA
150 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
151 static void _e_comp_object_raise(Evas_Object *obj);
152 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
153 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
154 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
155 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
158 static E_Client *dim_client = NULL;
161 _e_comp_object_hooks_clean(void)
164 E_Comp_Object_Hook *ch;
167 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
168 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
170 if (!ch->delete_me) continue;
171 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
177 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
179 E_Comp_Object_Hook *ch;
180 Eina_Bool ret = EINA_TRUE;
182 if (e_object_is_del(E_OBJECT(ec)))
184 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
185 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
186 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
197 e_object_ref(E_OBJECT(ec));
198 _e_comp_object_hooks_walking++;
199 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
201 if (ch->delete_me) continue;
202 if (!(ch->func(ch->data, ec)))
208 _e_comp_object_hooks_walking--;
209 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
210 _e_comp_object_hooks_clean();
212 e_object_unref(E_OBJECT(ec));
217 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
219 _e_comp_object_intercept_hooks_clean(void)
222 E_Comp_Object_Intercept_Hook *ch;
225 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
226 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
228 if (!ch->delete_me) continue;
229 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
235 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
237 E_Comp_Object_Intercept_Hook *ch;
238 Eina_Bool ret = EINA_TRUE;
240 if (e_object_is_del(E_OBJECT(ec))) return ret;
241 e_object_ref(E_OBJECT(ec));
242 _e_comp_object_intercept_hooks_walking++;
243 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
245 if (ch->delete_me) continue;
246 if (!(ch->func(ch->data, ec)))
252 _e_comp_object_intercept_hooks_walking--;
253 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
254 _e_comp_object_intercept_hooks_clean();
256 e_object_unref(E_OBJECT(ec));
263 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
265 E_Event_Comp_Object *ev = event;
268 ec = evas_object_data_get(ev->comp_object, "E_Client");
272 e_object_unref(E_OBJECT(ec));
274 evas_object_unref(ev->comp_object);
279 _e_comp_object_event_add(Evas_Object *obj)
281 E_Event_Comp_Object *ev;
284 if (stopping) return;
285 ev = E_NEW(E_Event_Comp_Object, 1);
286 EINA_SAFETY_ON_NULL_RETURN(ev);
288 evas_object_ref(obj);
289 ev->comp_object = obj;
290 ec = evas_object_data_get(ev->comp_object, "E_Client");
294 e_object_ref(E_OBJECT(ec));
296 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
300 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
302 E_Event_Comp_Object *ev = event;
305 ec = evas_object_data_get(ev->comp_object, "E_Client");
309 e_object_unref(E_OBJECT(ec));
311 evas_object_unref(ev->comp_object);
316 _e_comp_object_event_simple(Evas_Object *obj, int type)
318 E_Event_Comp_Object *ev;
321 ev = E_NEW(E_Event_Comp_Object, 1);
324 evas_object_ref(obj);
325 ev->comp_object = obj;
326 ec = evas_object_data_get(ev->comp_object, "E_Client");
330 e_object_ref(E_OBJECT(ec));
332 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
334 /////////////////////////////////////
337 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
339 E_Comp_Object *cw = data;
341 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
345 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
347 E_Comp_Object *cw = data;
349 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
350 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
353 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
354 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
358 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
360 E_Comp_Object *cw = data;
363 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
364 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
367 /////////////////////////////////////
369 #ifdef REFACTOR_DESK_AREA
371 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
374 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
379 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
380 if (cw->ec->input_only) return;
382 layer = evas_object_layer_get(obj);
384 if (cw->transform_bg_obj)
386 if (layer != evas_object_layer_get(cw->transform_bg_obj))
388 evas_object_layer_set(cw->transform_bg_obj, layer);
391 evas_object_stack_below(cw->transform_bg_obj, obj);
394 if (cw->transform_tranp_obj)
396 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
398 evas_object_layer_set(cw->transform_tranp_obj, layer);
401 evas_object_stack_below(cw->transform_tranp_obj, obj);
406 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
413 if (!map) return NULL;
415 e_map_util_points_populate_from_object_full(map, obj, 0);
416 e_map_util_points_color_set(map, 255, 255, 255, 255);
418 for (i = 0 ; i < 4 ; ++i)
423 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
424 e_map_point_coord_set(map, i, x, y, 1.0);
431 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
437 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
440 e_comp_object_map_set(obj, map);
441 e_comp_object_map_enable_set(obj, EINA_TRUE);
448 evas_object_map_enable_set(obj, EINA_FALSE);
453 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
459 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
462 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
464 e_comp_object_map_set(obj, map);
465 e_comp_object_map_enable_set(obj, EINA_TRUE);
472 evas_object_map_enable_set(obj, EINA_FALSE);
475 /////////////////////////////////////
477 static inline Eina_Bool
478 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
480 if (num > 1) return EINA_TRUE;
481 if ((rects[0].x == 0) && (rects[0].y == 0) &&
482 ((int)rects[0].w == w) && ((int)rects[0].h == h))
487 /////////////////////////////////////
489 /* add a client to the layer-client list */
490 #ifdef REFACTOR_DESK_AREA
493 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
495 g_rec_mutex_lock(&e_comp->ec_list_mutex);
498 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));
500 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));
501 if ((!above) && (!below))
504 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
505 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
506 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508 e_comp->layers[cw->layer].clients_count++;
510 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
514 _e_comp_object_layers_remove(E_Comp_Object *cw)
516 g_rec_mutex_lock(&e_comp->ec_list_mutex);
518 if (cw->ec && e_comp->layers[cw->layer].clients)
520 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
521 e_comp->layers[cw->layer].clients_count--;
524 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
528 /////////////////////////////////////
530 _e_comp_object_alpha_set(E_Comp_Object *cw)
532 Eina_Bool alpha = cw->ec->argb;
534 if ((cw->external_content) &&
535 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
540 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
541 if (cw->user_alpha_set) alpha = cw->user_alpha;
543 evas_object_image_alpha_set(cw->obj, alpha);
547 _e_comp_object_shadow(E_Comp_Object *cw)
549 if (e_client_util_shadow_state_get(cw->ec))
550 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
552 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
553 if (cw->frame_object)
554 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
555 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
558 /* convert from the surface coordinates to the buffer coordinates */
560 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
562 E_Comp_Wl_Buffer_Viewport *vp;
563 E_Comp_Wl_Client_Data *cdata;
567 cdata = e_client_cdata_get(ec);
569 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
576 vp = &cdata->scaler.buffer_viewport;
577 transform = e_comp_wl_output_buffer_transform_get(ec);
579 e_pixmap_size_get(ec->pixmap, &bw, &bh);
581 /* for subsurface, it should be swap 90 and 270 */
582 if (e_comp_wl_subsurface_check(ec))
585 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
586 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
587 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
588 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
594 case WL_OUTPUT_TRANSFORM_NORMAL:
595 default: tx = sx, ty = sy; break;
596 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
597 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
598 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
599 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
600 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
601 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
605 tx *= vp->buffer.scale;
606 ty *= vp->buffer.scale;
613 _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)
621 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
622 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
629 if (dw) *dw = MAX(x1, x2) - mx;
630 if (dh) *dh = MAX(y1, y2) - my;
634 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
635 int *dx, int *dy, int *dw, int *dh)
637 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
638 E_Util_Transform_Rect_Vertex sv, dv;
642 e_pixmap_size_get(ec->pixmap, &bw, &bh);
644 sv = e_util_transform_rect_to_vertices(&rect);
646 for (i = 0; i < 4; i++)
648 double x = 0.0, y = 0.0;
650 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
652 /* if evas decide coordinate is outside of map, it returns (0, 0)
653 in this case, full damage is added.
655 if ((i != 0) && (x == 0.0) && (y == 0.0))
658 dv.vertices[i].vertex[0] = x;
659 dv.vertices[i].vertex[1] = y;
660 dv.vertices[i].vertex[2] = 1.0;
661 dv.vertices[i].vertex[3] = 1.0;
664 rect = e_util_transform_vertices_to_rect(&dv);
666 if (dx) *dx = rect.x;
667 if (dy) *dy = rect.y;
668 if (dw) *dw = rect.w;
669 if (dh) *dh = rect.h;
683 _e_comp_object_map_damage_transform_get(E_Client *ec)
690 if (!e_client_transform_core_enable_get(ec))
693 m = e_client_map_get(ec);
697 e_pixmap_size_get(ec->pixmap, &bw, &bh);
698 if ((bw == 0) || (bh == 0))
711 e_map_point_coord_set(m2, 0, 0, 0, 0);
712 e_map_point_coord_set(m2, 1, bw, 0, 0);
713 e_map_point_coord_set(m2, 2, bw, bh, 0);
714 e_map_point_coord_set(m2, 3, 0, bh, 0);
716 for (i = 0; i < 4; i++)
720 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
721 e_map_point_image_uv_set(m2, i, map_x, map_y);
728 /////////////////////////////////////
730 /* handle evas mouse-in events on client object */
732 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
734 Evas_Event_Mouse_In *ev = event_info;
735 E_Comp_Object *cw = data;
737 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
740 /* handle evas mouse-out events on client object */
742 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
744 Evas_Event_Mouse_Out *ev = event_info;
745 E_Comp_Object *cw = data;
747 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
750 /* handle evas mouse wheel events on client object */
752 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
754 Evas_Event_Mouse_Wheel *ev = event_info;
755 E_Comp_Object *cw = data;
756 E_Binding_Event_Wheel ev2;
759 if (e_client_action_get()) return;
760 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
761 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
764 /* handle evas mouse down events on client object */
766 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
768 Evas_Event_Mouse_Down *ev = event_info;
769 E_Comp_Object *cw = data;
770 E_Binding_Event_Mouse_Button ev2;
773 if (e_client_action_get()) return;
774 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
775 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
778 /* handle evas mouse up events on client object */
780 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
782 Evas_Event_Mouse_Up *ev = event_info;
783 E_Comp_Object *cw = data;
784 E_Binding_Event_Mouse_Button ev2;
787 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
788 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
789 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
792 /* handle evas mouse movement events on client object */
794 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
796 Evas_Event_Mouse_Move *ev = event_info;
797 E_Comp_Object *cw = data;
800 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
801 e_client_mouse_move(cw->ec, &ev->cur.output);
803 /////////////////////////////////////
805 /* helper function for checking compositor themes based on user-defined matches */
807 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
809 if (((m->title) && (!ec->netwm.name)) ||
810 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
812 #if defined(__cplusplus) || defined(c_plusplus)
813 if (((m->clas) && (!ec->icccm.cpp_class)) ||
814 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
817 if (((m->clas) && (!ec->icccm.class)) ||
818 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
822 if (((m->role) && (!ec->icccm.window_role)) ||
823 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
829 if ((int)ec->netwm.type != m->primary_type)
832 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
835 if (m->borderless != 0)
839 if (e_client_util_borderless(ec))
841 if (!(((m->borderless == -1) && (!borderless)) ||
842 ((m->borderless == 1) && (borderless))))
849 if (((ec->icccm.transient_for != 0) ||
852 if (!(((m->dialog == -1) && (!dialog)) ||
853 ((m->dialog == 1) && (dialog))))
856 if (m->accepts_focus != 0)
858 int accepts_focus = 0;
860 if (ec->icccm.accepts_focus)
862 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
863 ((m->accepts_focus == 1) && (accepts_focus))))
872 if (!(((m->vkbd == -1) && (!vkbd)) ||
873 ((m->vkbd == 1) && (vkbd))))
878 if (!(((m->argb == -1) && (!ec->argb)) ||
879 ((m->argb == 1) && (ec->argb))))
882 if (m->fullscreen != 0)
884 int fullscreen = ec->fullscreen;
886 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
887 ((m->fullscreen == 1) && (fullscreen))))
892 if (!(m->modal == -1))
898 /* function for setting up a client's compositor frame theme (cw->shobj) */
900 _e_comp_object_shadow_setup(E_Comp_Object *cw)
904 Eina_List *list = NULL, *l;
905 E_Input_Rect_Data *input_rect_data;
906 E_Input_Rect_Smart_Data *input_rect_sd;
908 Eina_Stringshare *reshadow_group = NULL;
909 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
910 Eina_Stringshare *name, *title;
911 E_Comp_Config *conf = e_comp_config_get();
913 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
914 /* match correct client type */
915 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
916 name = cw->ec->icccm.name;
917 title = cw->ec->icccm.title;
918 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
919 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
921 /* skipping here is mostly a hack for systray because I hate it */
924 EINA_LIST_FOREACH(list, l, m)
926 if (((m->name) && (!name)) ||
927 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
929 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
932 no_shadow = m->no_shadow;
935 /* fast effects are just themes with "/fast" appended and shorter effect times */
938 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
939 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
941 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
943 /* default to non-fast style if fast not available */
946 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
947 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
949 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
951 if (ok && m->visibility_effect)
952 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
959 if (skip || (cw->ec->e.state.video))
961 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
963 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
966 if (conf->shadow_style)
970 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
971 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
973 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
977 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
978 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
980 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
987 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
989 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
993 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
995 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1000 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1005 if (cw->ec->override)
1007 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1008 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1010 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1011 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1017 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1018 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1021 _e_comp_object_shadow(cw);
1024 if (focus || cw->ec->focused || cw->ec->override)
1025 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1027 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1029 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1031 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1032 /* visibility must always be enabled for re_manage clients to prevent
1033 * pop-in animations every time the user sees a persistent client again;
1034 * applying visibility for iconic clients prevents the client from getting
1037 if (cw->visible || cw->ec->re_manage)
1038 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1040 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1042 /* breaks animation counter */
1043 if (cw->frame_object)
1045 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1046 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1047 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1048 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1054 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1058 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1061 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1063 if (input_rect_data->obj)
1065 pass_event_flag = EINA_TRUE;
1071 if (cw->indicator.obj)
1073 Evas_Object *indicator;
1074 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1075 if (indicator != cw->indicator.obj)
1077 edje_object_part_unswallow(cw->shobj, indicator);
1078 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1079 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1083 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1084 evas_object_pass_events_set(cw->obj, pass_event_flag);
1089 /////////////////////////////////////////////
1092 _e_comp_object_animating_begin(E_Comp_Object *cw)
1095 if (cw->animating == 1)
1097 e_comp->animating++;
1099 e_object_ref(E_OBJECT(cw->ec));
1104 _e_comp_object_animating_end(E_Comp_Object *cw)
1113 if (cw->ec->launching)
1115 if (!cw->ec->extra_animating)
1117 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1118 cw->ec->launching = EINA_FALSE;
1119 if (cw->ec->first_mapped)
1121 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1122 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1125 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1129 e_comp->animating--;
1130 cw->showing = cw->hiding = 0;
1132 if (e_comp->animating == 0)
1133 e_comp_visibility_calculation_set(EINA_TRUE);
1134 /* remove ref from animation start, account for possibility of deletion from unref */
1135 return !!e_object_unref(E_OBJECT(cw->ec));
1141 /* handle the end of a compositor animation */
1143 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1145 E_Comp_Object *cw = data;
1147 /* visible clients which have never been sized are a bug */
1148 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1149 CRI("ACK! ec:%p", cw->ec);
1150 if (!_e_comp_object_animating_end(cw)) return;
1151 if (cw->animating) return;
1152 /* hide only after animation finishes to guarantee a full run of the animation */
1153 if (!cw->defer_hide) return;
1154 if ((!strcmp(emission, "e,action,hide,done")) ||
1155 (!strcmp(emission, "e,action,done")) ||
1156 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1158 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1159 evas_object_hide(cw->smart_obj);
1163 /* run a visibility compositor effect if available, return false if object is dead */
1165 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1171 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1172 if (!cw->effect_running)
1173 _e_comp_object_animating_begin(cw);
1174 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1175 return _e_comp_object_animating_end(cw);
1176 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1177 return _e_comp_object_animating_end(cw);
1179 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1182 zone = e_comp_zone_find_by_ec(cw->ec);
1184 zw = zone->w, zh = zone->h;
1189 zone = e_comp_object_util_zone_get(cw->smart_obj);
1190 if (!zone) zone = e_zone_current_get();
1197 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1198 cw->w, cw->h, zw, zh, x, y}, 8);
1199 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1200 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1203 /////////////////////////////////////////////
1205 /* create necessary objects for clients that e manages */
1207 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1209 if (cw->set_mouse_callbacks) return;
1210 if (!cw->smart_obj) return;
1212 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1213 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1214 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1219 cw->set_mouse_callbacks = EINA_TRUE;
1223 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1225 if (!cw->set_mouse_callbacks) return;
1226 if (!cw->smart_obj) return;
1228 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1229 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1230 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1235 cw->set_mouse_callbacks = EINA_FALSE;
1239 _e_comp_object_setup(E_Comp_Object *cw)
1241 cw->clip = evas_object_rectangle_add(e_comp->evas);
1242 evas_object_move(cw->clip, -9999, -9999);
1243 evas_object_resize(cw->clip, 999999, 999999);
1244 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1245 cw->effect_obj = edje_object_add(e_comp->evas);
1246 evas_object_move(cw->effect_obj, cw->x, cw->y);
1247 evas_object_clip_set(cw->effect_obj, cw->clip);
1248 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1249 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1250 cw->shobj = edje_object_add(e_comp->evas);
1251 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1252 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1253 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1255 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1256 if (cw->ec->override)
1258 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1259 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1260 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1262 else if (!cw->ec->input_only)
1264 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1265 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1266 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1268 cw->real_hid = !cw->ec->input_only;
1269 if (!cw->ec->input_only)
1271 e_util_size_debug_set(cw->effect_obj, 1);
1272 _e_comp_object_mouse_event_callback_set(cw);
1275 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1276 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1277 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1278 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1279 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1280 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1282 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1285 /////////////////////////////////////////////
1287 /* for fast path evas rendering; only called during render */
1289 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1291 E_Comp_Object *cw = data;
1292 E_Client *ec = cw->ec;
1294 int bx, by, bxx, byy;
1296 if (e_object_is_del(E_OBJECT(ec))) return;
1297 if (cw->external_content) return;
1298 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1299 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1302 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1303 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1305 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1307 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1308 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1312 bx = by = bxx = byy = 0;
1313 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1316 Edje_Message_Int_Set *msg;
1317 Edje_Message_Int msg2;
1318 Eina_Bool id = (bx || by || bxx || byy);
1320 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1326 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1328 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1332 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1333 e_comp_client_post_update_add(cw->ec);
1335 else if (e_comp_object_render(ec->frame))
1337 /* apply shape mask if necessary */
1338 if ((!cw->native) && (ec->shaped))
1339 e_comp_object_shape_apply(ec->frame);
1341 /* shaped clients get precise mouse events to handle transparent pixels */
1342 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1344 /* queue another render if client is still dirty; cannot refresh here. */
1345 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1346 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1348 if (cw->render_trace)
1350 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1356 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1358 E_Comp_Object *cw = data;
1359 E_Client *ec = cw->ec;
1361 if (e_object_is_del(E_OBJECT(ec))) return;
1362 if (cw->external_content) return;
1363 if (!e_comp->hwc) return;
1365 e_comp_client_render_list_add(cw->ec);
1367 if (!ec->hwc_window) return;
1369 e_hwc_windows_rendered_window_add(ec->hwc_window);
1372 /////////////////////////////////////////////
1375 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1377 E_Comp_Object *cw = data;
1380 if (cw->render_update_lock.lock)
1382 cw->render_update_lock.pending_move_x = x;
1383 cw->render_update_lock.pending_move_y = y;
1384 cw->render_update_lock.pending_move_set = EINA_TRUE;
1388 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1389 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1390 (cw->external_content))
1392 /* delay to move until the external content is unset */
1393 cw->ec->changes.pos = 1;
1398 if (cw->ec->move_after_resize)
1400 if ((x != cw->ec->x) || (y != cw->ec->y))
1402 if (!cw->ec->is_cursor)
1403 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1404 e_client_pos_set(cw->ec, x, y);
1405 cw->ec->changes.pos = 1;
1411 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1412 (cw->ec->manage_resize.resize_obj))
1414 e_client_pos_set(cw->ec, x, y);
1415 cw->ec->client.x = x + cw->client_inset.l;
1416 cw->ec->client.y = y + cw->client_inset.t;
1417 e_policy_visibility_client_defer_move(cw->ec);
1421 /* if frame_object does not exist, client_inset indicates CSD.
1422 * this means that ec->client matches cw->x/y, the opposite
1425 fx = (!cw->frame_object) * cw->client_inset.l;
1426 fy = (!cw->frame_object) * cw->client_inset.t;
1427 if ((cw->x == x + fx) && (cw->y == y + fy))
1429 if ((cw->ec->x != x) || (cw->ec->y != y))
1431 /* handle case where client tries to move to position and back very quickly */
1432 e_client_pos_set(cw->ec, x, y);
1433 cw->ec->client.x = x + cw->client_inset.l;
1434 cw->ec->client.y = y + cw->client_inset.t;
1438 if (!cw->ec->maximize_override)
1440 /* prevent moving in some directions while directionally maximized */
1441 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1443 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1446 ix = x + cw->client_inset.l;
1447 iy = y + cw->client_inset.t;
1448 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1449 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1450 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1452 /* prevent moving at all if move isn't allowed in current maximize state */
1453 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1454 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1457 zone = e_comp_zone_find_by_ec(cw->ec);
1460 cw->ec->changes.need_unmaximize = 1;
1461 cw->ec->saved.x = ix - zone->x;
1462 cw->ec->saved.y = iy - zone->y;
1463 cw->ec->saved.w = cw->ec->client.w;
1464 cw->ec->saved.h = cw->ec->client.h;
1468 /* only update during resize if triggered by resize */
1469 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1470 /* delay to move while surface waits paired commit serial*/
1471 if (e_client_pending_geometry_has(cw->ec))
1473 /* do nothing while waiting paired commit serial*/
1477 e_client_pos_set(cw->ec, x, y);
1478 if (cw->ec->new_client)
1480 /* don't actually do anything until first client idler loop */
1481 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1482 cw->ec->changes.pos = 1;
1487 /* only update xy position of client to avoid invalid
1488 * first damage region if it is not a new_client. */
1489 cw->ec->client.x = ix;
1490 cw->ec->client.y = iy;
1493 if (!cw->frame_object)
1495 evas_object_move(obj, x, y);
1500 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1502 E_Comp_Object *cw = data;
1503 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1506 if (cw->render_update_lock.lock)
1508 cw->render_update_lock.pending_resize_w = w;
1509 cw->render_update_lock.pending_resize_h = h;
1510 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1514 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1516 e_client_size_set(cw->ec, w, h);
1517 evas_object_resize(obj, w, h);
1521 /* if frame_object does not exist, client_inset indicates CSD.
1522 * this means that ec->client matches cw->w/h, the opposite
1525 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1526 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1527 if ((cw->w == w + fw) && (cw->h == h + fh))
1529 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1530 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1531 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1533 /* handle case where client tries to resize itself and back very quickly */
1534 e_client_size_set(cw->ec, w, h);
1535 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1536 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1537 evas_object_smart_callback_call(obj, "client_resize", NULL);
1541 /* guarantee that fullscreen is fullscreen */
1542 zone = e_comp_zone_find_by_ec(cw->ec);
1544 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1546 if (!e_client_transform_core_enable_get(cw->ec))
1549 /* calculate client size */
1550 iw = w - cw->client_inset.l - cw->client_inset.r;
1551 ih = h - cw->client_inset.t - cw->client_inset.b;
1552 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1554 /* prevent resizing while maximized depending on direction and config */
1555 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1557 Eina_Bool reject = EINA_FALSE;
1558 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1560 if (cw->ec->client.h != ih)
1562 cw->ec->saved.h = ih;
1563 cw->ec->saved.y = cw->ec->client.y - zone->y;
1564 reject = cw->ec->changes.need_unmaximize = 1;
1567 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1569 if (cw->ec->client.w != iw)
1571 cw->ec->saved.w = iw;
1572 cw->ec->saved.x = cw->ec->client.x - zone->x;
1573 reject = cw->ec->changes.need_unmaximize = 1;
1582 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1584 /* do nothing until client idler loops */
1585 if ((cw->ec->w != w) || (cw->ec->h != h))
1587 e_client_size_set(cw->ec, w, h);
1588 cw->ec->changes.size = 1;
1593 if (e_client_pending_geometry_has(cw->ec))
1595 /* do nothing while waiting paired commit serial*/
1599 e_client_size_set(cw->ec, w, h);
1601 cw->ec->client.w = iw;
1602 cw->ec->client.h = ih;
1603 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1605 /* The size of non-compositing window can be changed, so there is a
1606 * need to check that cw is H/W composited if cw is not redirected.
1607 * And of course we have to change size of evas object of H/W composited cw,
1608 * otherwise cw can't receive input events even if it is shown on the screen.
1610 Eina_Bool redirected = cw->redirected;
1612 redirected = e_comp_is_on_overlay(cw->ec);
1614 if ((!cw->ec->input_only) && (redirected) &&
1615 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1616 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1617 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1618 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1621 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1622 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1624 prev_w = cw->w, prev_h = cw->h;
1625 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1626 /* check shading and clamp to pixmap size for regular clients */
1627 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1628 (((w - fw != pw) || (h - fh != ph))))
1630 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1631 evas_object_smart_callback_call(obj, "client_resize", NULL);
1633 if (cw->frame_object || cw->ec->input_only)
1634 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1637 if ((cw->w == w) && (cw->h == h))
1639 /* going to be a noop resize which won't trigger smart resize */
1640 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1641 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1643 evas_object_resize(obj, w, h);
1647 evas_object_smart_callback_call(obj, "client_resize", NULL);
1650 if ((!cw->frame_object) && (!cw->ec->input_only))
1652 /* "just do it" for overrides */
1653 evas_object_resize(obj, w, h);
1655 if (!cw->ec->override)
1657 /* shape probably changed for non-overrides */
1662 /* this fixes positioning jiggles when using a resize mode
1663 * which also changes the client's position
1666 if (cw->frame_object)
1667 x = cw->x, y = cw->y;
1669 x = cw->ec->x, y = cw->ec->y;
1670 switch (cw->ec->resize_mode)
1672 case E_POINTER_RESIZE_BL:
1673 case E_POINTER_RESIZE_L:
1674 evas_object_move(obj, x + prev_w - cw->w, y);
1676 case E_POINTER_RESIZE_TL:
1677 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1679 case E_POINTER_RESIZE_T:
1680 case E_POINTER_RESIZE_TR:
1681 evas_object_move(obj, x, y + prev_h - cw->h);
1690 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1692 #ifdef REFACTOR_DESK_AREA
1693 E_Comp_Object *cw = data;
1694 E_Comp_Object_Data_Set_Layer layer_set_data;
1696 layer_set_data.cw = cw;
1697 layer_set_data.layer = layer;
1699 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1703 e_comp_render_queue();
1704 e_comp_object_transform_obj_stack_update(obj);
1708 E_Comp_Object *cw = data;
1709 E_Comp_Wl_Client_Data *child_cdata;
1710 unsigned int l = e_comp_canvas_layer_map(layer);
1713 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1715 /* doing a compositor effect, follow directions */
1716 _e_comp_object_layer_set(obj, layer);
1717 if (layer == cw->ec->layer) //trying to put layer back
1721 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1722 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1723 if (cw->layer != l) goto layer_set;
1727 e_comp_render_queue();
1729 ec = e_client_above_get(cw->ec);
1730 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1731 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1732 ec = e_client_above_get(ec);
1733 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1735 ec = e_client_below_get(cw->ec);
1736 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1737 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1738 ec = e_client_below_get(ec);
1739 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1741 evas_object_stack_above(obj, ec->frame);
1746 if (ec && (cw->ec->parent == ec))
1748 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1749 evas_object_stack_above(obj, ec->frame);
1751 evas_object_stack_below(obj, ec->frame);
1754 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1760 if (cw->layer == l) return;
1761 if (e_comp_canvas_client_layer_map(layer) == 9999)
1762 return; //invalid layer for clients not doing comp effects
1763 if (cw->ec->fullscreen)
1765 cw->ec->saved.layer = layer;
1768 oldraise = e_config->transient.raise;
1770 /* clamp to valid client layer */
1771 layer = e_comp_canvas_client_layer_map_nearest(layer);
1772 cw->ec->layer = layer;
1773 if (e_config->transient.layer)
1776 Eina_List *list = eina_list_clone(cw->ec->transients);
1778 /* We need to set raise to one, else the child wont
1779 * follow to the new layer. It should be like this,
1780 * even if the user usually doesn't want to raise
1783 e_config->transient.raise = 1;
1784 EINA_LIST_FREE(list, child)
1786 child_cdata = e_client_cdata_get(child);
1787 if (child_cdata && !child_cdata->mapped)
1789 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1792 e_client_layer_set(child, layer);
1796 e_config->transient.raise = oldraise;
1798 _e_comp_object_layers_remove(cw);
1799 cw->layer = e_comp_canvas_layer_map(layer);
1800 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1801 //if (cw->ec->new_client)
1802 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1803 _e_comp_object_layer_set(obj, layer);
1804 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1805 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1806 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1808 /* can't stack a client above its own layer marker */
1809 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1811 if (!cw->visible) return;
1812 e_comp_render_queue();
1813 _e_comp_object_transform_obj_stack_update(obj);
1817 #ifdef REFACTOR_DESK_AREA
1819 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1822 #ifdef REFACTOR_DESK_AREA
1824 e_comp_object_raise(Evas_Object *obj)
1827 _e_comp_object_raise(Evas_Object *obj)
1830 evas_object_raise(obj);
1832 if (evas_object_smart_smart_get(obj))
1834 E_Client *ec = e_comp_object_client_get(obj);
1836 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1840 #ifdef REFACTOR_DESK_AREA
1842 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1845 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1848 evas_object_lower(obj);
1850 if (evas_object_smart_smart_get(obj))
1852 E_Client *ec = e_comp_object_client_get(obj);
1855 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1856 #ifdef REFACTOR_DESK_AREA
1857 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1859 wl_signal_emit_mutable(&cw->events.lower, NULL);
1865 #ifdef REFACTOR_DESK_AREA
1867 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1870 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1873 evas_object_stack_above(obj, target);
1875 if (evas_object_smart_smart_get(obj))
1877 E_Client *ec = e_comp_object_client_get(obj);
1879 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1883 #ifdef REFACTOR_DESK_AREA
1885 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1888 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1891 evas_object_stack_below(obj, target);
1893 if (evas_object_smart_smart_get(obj))
1895 E_Client *ec = e_comp_object_client_get(obj);
1897 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1901 #ifdef REFACTOR_DESK_AREA
1903 e_comp_object_layer_set(Evas_Object *obj, short layer)
1906 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1909 evas_object_layer_set(obj, layer);
1911 if (evas_object_smart_smart_get(obj))
1913 E_Client *ec = e_comp_object_client_get(obj);
1915 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1919 #ifdef REFACTOR_DESK_AREA
1922 _e_comp_object_is_pending(E_Client *ec)
1926 if (!ec) return EINA_FALSE;
1928 topmost = e_comp_wl_topmost_parent_get(ec);
1930 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1934 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1936 E_Comp_Object *cw2 = NULL;
1939 Evas_Object *o = stack;
1940 #ifdef REFACTOR_DESK_AREA
1941 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
1943 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1946 /* We should consider topmost's layer_pending for subsurface */
1947 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1949 if (_e_comp_object_is_pending(cw->ec))
1950 e_comp_object_layer_update(cw->smart_obj,
1951 raising? stack : NULL,
1952 raising? NULL : stack);
1954 /* obey compositor effects! */
1955 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1956 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
1957 stack_cb(cw->smart_obj, stack);
1958 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1959 evas_object_data_del(cw->smart_obj, "client_restack");
1963 cw2 = evas_object_data_get(o, "comp_obj");
1965 /* assume someone knew what they were doing during client init */
1966 if (cw->ec->new_client)
1967 layer = cw->ec->layer;
1968 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
1969 layer = cw2->ec->layer;
1971 layer = evas_object_layer_get(stack);
1972 ecstack = e_client_below_get(cw->ec);
1973 if (layer != e_comp_canvas_layer_map_to(cw->layer))
1975 evas_object_layer_set(cw->smart_obj, layer);
1976 /* we got our layer wrangled, return now! */
1977 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
1980 /* check if we're stacking below another client */
1983 /* check for non-client layer object */
1984 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
1986 /* find an existing client to use for layering
1987 * by walking up the object stack
1989 * this is guaranteed to be pretty quick since we'll either:
1990 * - run out of client layers
1991 * - find a stacking client
1993 o = evas_object_above_get(o);
1994 if ((!o) || (o == cw->smart_obj)) break;
1995 if (evas_object_layer_get(o) != layer)
1997 /* reached the top client layer somehow
1998 * use top client object
2000 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2003 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2004 * return here since the top client layer window
2009 ec = e_client_top_get();
2014 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2017 if (cw2 && cw->layer != cw2->layer)
2020 /* remove existing layers */
2021 _e_comp_object_layers_remove(cw);
2024 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2025 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2026 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2027 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2028 else //if no stacking objects found, either raise or lower
2029 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2032 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2034 /* find new object for stacking if cw2 is on state of layer_pending */
2035 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2037 E_Client *new_stack = NULL, *current_ec = NULL;
2038 current_ec = cw2->ec;
2041 while ((new_stack = e_client_below_get(current_ec)))
2043 current_ec = new_stack;
2044 if (new_stack == cw->ec) continue;
2045 if (new_stack->layer != cw2->ec->layer) break;
2046 if (!_e_comp_object_is_pending(new_stack)) break;
2048 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2049 stack = new_stack->frame;
2052 /* stack it above layer object */
2054 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2055 stack = e_comp->layers[below_layer].obj;
2060 while ((new_stack = e_client_above_get(current_ec)))
2062 current_ec = new_stack;
2063 if (new_stack == cw->ec) continue;
2064 if (new_stack->layer != cw2->ec->layer) break;
2065 if (!_e_comp_object_is_pending(new_stack)) break;
2067 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2068 stack = new_stack->frame;
2070 stack = e_comp->layers[cw2->layer].obj;
2074 /* set restack if stacking has changed */
2075 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2076 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2077 stack_cb(cw->smart_obj, stack);
2078 if (e_comp->layers[cw->layer].obj)
2079 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2081 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2083 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2084 evas_object_data_del(cw->smart_obj, "client_restack");
2085 if (!cw->visible) return;
2086 e_comp_render_queue();
2091 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2093 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2095 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2097 #ifdef REFACTOR_DESK_AREA
2098 E_Comp_Object *cw = data;
2099 E_Comp_Object_Data_Stack_Above stack_above_data;
2101 stack_above_data.cw = cw;
2102 stack_above_data.above_obj = above;
2104 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2106 if (evas_object_below_get(obj) == above)
2108 e_comp_object_layer_update(obj, above, NULL);
2112 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2114 _e_comp_object_transform_obj_stack_update(obj);
2115 _e_comp_object_transform_obj_stack_update(above);
2122 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2124 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2126 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2128 #ifdef REFACTOR_DESK_AREA
2129 E_Comp_Object *cw = data;
2130 E_Comp_Object_Data_Stack_Below stack_below_data;
2132 stack_below_data.cw = cw;
2133 stack_below_data.below_obj = below;
2135 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2138 e_comp_render_queue();
2140 if (evas_object_above_get(obj) == below)
2142 e_comp_object_layer_update(obj, NULL, below);
2146 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2148 if (evas_object_smart_smart_get(obj))
2149 _e_comp_object_transform_obj_stack_update(obj);
2150 if (evas_object_smart_smart_get(below))
2151 _e_comp_object_transform_obj_stack_update(below);
2158 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2160 E_Comp_Object *cw = data;
2162 #ifdef REFACTOR_DESK_AREA
2167 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2169 #ifdef REFACTOR_DESK_AREA
2170 wl_signal_emit_mutable(&cw->events.lower, cw);
2172 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2174 if (cw->ec->layer_pending)
2175 e_comp_object_layer_update(obj, NULL, obj);
2177 #ifdef REFACTOR_DESK_AREA
2178 e_comp_object_lower(cw, obj);
2180 _e_comp_object_lower(cw, obj);
2184 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2185 o = evas_object_below_get(obj);
2186 _e_comp_object_layers_remove(cw);
2187 /* prepend to client list since this client should be the first item now */
2188 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2189 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2190 evas_object_data_set(obj, "client_restack", (void*)1);
2191 #ifdef REFACTOR_DESK_AREA
2192 e_comp_object_lower(cw, obj);
2194 _e_comp_object_lower(cw, obj);
2196 evas_object_data_del(obj, "client_restack");
2197 if (!cw->visible) goto end;
2198 e_comp_render_queue();
2199 #ifdef REFACTOR_DESK_AREA
2200 e_comp_object_transform_obj_stack_update(obj);
2202 _e_comp_object_transform_obj_stack_update(obj);
2211 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2213 E_Comp_Object *cw = data;
2214 #ifdef REFACTOR_DESK_AREA
2220 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2222 #ifdef REFACTOR_DESK_AREA
2223 wl_signal_emit_mutable(&cw->events.raise, cw);
2225 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2227 if (cw->ec->layer_pending)
2229 int obj_layer = evas_object_layer_get(obj);
2230 if (cw->ec->layer != obj_layer)
2231 e_comp_object_layer_update(obj, NULL, NULL);
2233 #ifdef REFACTOR_DESK_AREA
2234 e_comp_object_raise(obj);
2236 _e_comp_object_raise(obj);
2240 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2241 o = evas_object_above_get(obj);
2242 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2244 /* still stack below override below the layer marker */
2245 for (op = o = e_comp->layers[cw->layer].obj;
2246 o && o != e_comp->layers[cw->layer - 1].obj;
2247 op = o, o = evas_object_below_get(o))
2249 if (evas_object_smart_smart_get(o))
2253 ec = e_comp_object_client_get(o);
2254 if (ec && (!ec->override)) break;
2257 #ifdef REFACTOR_DESK_AREA
2258 e_comp_object_stack_below(obj, op);
2260 _e_comp_object_stack_below(obj, op);
2262 e_client_focus_defer_set(cw->ec);
2264 if (!cw->visible) goto end;
2265 e_comp_render_queue();
2266 #ifdef REFACTOR_DESK_AREA
2267 e_comp_object_transform_obj_stack_update(obj);
2269 _e_comp_object_transform_obj_stack_update(obj);
2278 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2280 E_Comp_Object *cw = data;
2282 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2283 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2285 ELOGF("COMP", "Hide. intercepted", cw->ec);
2290 if (cw->ec->launching == EINA_TRUE)
2292 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2293 cw->ec->launching = EINA_FALSE;
2298 /* hidden flag = just do it */
2299 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2300 evas_object_hide(obj);
2302 wl_signal_emit_mutable(&cw->events.hide, NULL);
2307 if (cw->ec->input_only)
2309 /* input_only = who cares */
2310 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2311 evas_object_hide(obj);
2313 wl_signal_emit_mutable(&cw->events.hide, NULL);
2317 /* already hidden or currently animating */
2318 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2320 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2324 /* don't try hiding during shutdown */
2325 cw->defer_hide |= stopping;
2326 if (!cw->defer_hide)
2328 if ((!cw->ec->iconic) && (!cw->ec->override))
2329 /* unset delete requested so the client doesn't break */
2330 cw->ec->delete_requested = 0;
2331 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2333 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2334 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2337 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2340 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2342 _e_comp_object_animating_begin(cw);
2343 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2345 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2346 cw->defer_hide = !!cw->animating;
2348 e_comp_object_effect_set(obj, NULL);
2351 if (cw->animating) return;
2352 /* if we have no animations running, go ahead and hide */
2354 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2355 evas_object_hide(obj);
2357 wl_signal_emit_mutable(&cw->events.hide, NULL);
2361 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2363 E_Client *ec = cw->ec;
2366 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2368 if (ec->show_pending.count > 0)
2370 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2371 ec->show_pending.running = EINA_TRUE;
2375 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2376 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2378 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2383 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,
2384 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2385 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2388 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2391 if (ec->iconic && cw->animating)
2393 /* triggered during iconify animation */
2394 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2397 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2400 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2401 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2403 evas_object_move(cw->smart_obj, ec->x, ec->y);
2404 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2405 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2407 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2408 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2411 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2412 evas_object_show(cw->smart_obj);
2415 e_client_focus_defer_set(ec);
2419 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2423 pw = ec->client.w, ph = ec->client.h;
2425 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2427 ec->changes.visible = !ec->hidden;
2430 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2434 cw->updates = eina_tiler_new(pw, ph);
2437 ec->changes.visible = !ec->hidden;
2440 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2445 eina_tiler_tile_size_set(cw->updates, 1, 1);
2448 /* ignore until client idler first run */
2449 ec->changes.visible = !ec->hidden;
2452 ELOGF("COMP", "show_helper. return. new_client", ec);
2459 evas_object_move(cw->smart_obj, ec->x, ec->y);
2460 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2461 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2462 evas_object_show(cw->smart_obj);
2465 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2467 /* start_drag not received */
2468 ec->changes.visible = 1;
2471 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2474 /* re-set geometry */
2475 evas_object_move(cw->smart_obj, ec->x, ec->y);
2476 /* force resize in case it hasn't happened yet, or just to update size */
2477 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2478 if ((cw->w < 1) || (cw->h < 1))
2480 /* if resize didn't go through, try again */
2481 ec->visible = ec->changes.visible = 1;
2483 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2486 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2487 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2488 e_pixmap_clear(ec->pixmap);
2490 if (cw->real_hid && w && h)
2493 /* force comp theming in case it didn't happen already */
2494 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2495 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2496 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2499 /* only do the show if show is allowed */
2502 if (ec->internal) //internal clients render when they feel like it
2503 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2505 if (!e_client_is_iconified_by_client(ec)||
2506 e_policy_visibility_client_is_uniconic(ec))
2508 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2509 evas_object_show(cw->smart_obj);
2511 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2512 it is rendered in idle callback without native surface and
2513 compositor shows an empty frame if other objects aren't shown
2514 because job callback of e_comp called at the next loop.
2515 it causes a visual defect when windows are switched.
2519 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2520 e_comp_object_dirty(cw->smart_obj);
2521 e_comp_object_render(cw->smart_obj);
2526 wl_signal_emit_mutable(&cw->events.show, NULL);
2530 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2532 E_Comp_Object *cw = data;
2533 E_Client *ec = cw->ec;
2535 E_Input_Rect_Data *input_rect_data;
2536 E_Input_Rect_Smart_Data *input_rect_sd;
2539 if (ec->ignored) return;
2543 //INF("SHOW2 %p", ec);
2544 _e_comp_intercept_show_helper(cw);
2547 //INF("SHOW %p", ec);
2550 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2551 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2552 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2553 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2557 if ((!cw->obj) && (cw->external_content))
2559 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2563 _e_comp_object_setup(cw);
2566 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2567 cw->obj = evas_object_image_filled_add(e_comp->evas);
2568 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2569 e_util_size_debug_set(cw->obj, 1);
2570 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2571 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2572 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2573 evas_object_name_set(cw->obj, "cw->obj");
2574 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2576 _e_comp_object_alpha_set(cw);
2579 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2582 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2583 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2586 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2589 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2591 if (input_rect_data->obj)
2593 evas_object_geometry_set(input_rect_data->obj,
2594 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2595 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2596 input_rect_data->rect.w, input_rect_data->rect.h);
2603 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2605 _e_comp_intercept_show_helper(cw);
2609 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2611 E_Comp_Object *cw = data;
2615 /* note: this is here as it seems there are enough apps that do not even
2616 * expect us to emulate a look of focus but not actually set x input
2617 * focus as we do - so simply abort any focus set on such windows */
2618 /* be strict about accepting focus hint */
2619 /* be strict about accepting focus hint */
2620 if ((!ec->icccm.accepts_focus) &&
2621 (!ec->icccm.take_focus))
2625 if (e_client_focused_get() == ec)
2626 e_client_focused_set(NULL);
2628 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2629 evas_object_focus_set(obj, focus);
2633 if (focus && ec->lock_focus_out) return;
2634 if (e_object_is_del(E_OBJECT(ec)) && focus)
2635 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2637 /* filter focus setting based on current state */
2642 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2643 evas_object_focus_set(obj, focus);
2646 if ((ec->iconic) && (!ec->deskshow))
2648 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2650 /* don't focus an iconified window. that's silly! */
2651 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2652 e_client_uniconify(ec);
2653 e_client_focus_latest_set(ec);
2667 /* not yet visible, wait till the next time... */
2668 ec->want_focus = !ec->hidden;
2673 e_client_focused_set(ec);
2677 if (e_client_focused_get() == ec)
2678 e_client_focused_set(NULL);
2682 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2684 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2686 evas_object_focus_set(obj, focus);
2690 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2692 E_Comp_Object *cw = data;
2694 if (cw->transparent.set)
2696 cw->transparent.user_r = r;
2697 cw->transparent.user_g = g;
2698 cw->transparent.user_b = b;
2699 cw->transparent.user_a = a;
2701 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2703 cw->transparent.user_r,
2704 cw->transparent.user_g,
2705 cw->transparent.user_b,
2706 cw->transparent.user_a);
2710 evas_object_color_set(obj, r, g, b, a);
2713 ////////////////////////////////////////////////////
2716 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2718 int w, h, ox, oy, ow, oh;
2720 Eina_Bool pass_event_flag = EINA_FALSE;
2721 E_Input_Rect_Data *input_rect_data;
2722 E_Input_Rect_Smart_Data *input_rect_sd;
2724 if (cw->frame_object)
2726 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2727 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2728 /* set a fixed size, force edje calc, check size difference */
2729 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2730 edje_object_message_signal_process(cw->frame_object);
2731 edje_object_calc_force(cw->frame_object);
2732 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2733 cw->client_inset.l = ox;
2734 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2735 cw->client_inset.t = oy;
2736 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2737 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2738 evas_object_resize(cw->frame_object, w, h);
2742 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2745 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2747 if (input_rect_data->obj)
2749 pass_event_flag = EINA_TRUE;
2755 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2756 evas_object_pass_events_set(cw->obj, pass_event_flag);
2760 cw->client_inset.l = 0;
2761 cw->client_inset.r = 0;
2762 cw->client_inset.t = 0;
2763 cw->client_inset.b = 0;
2765 cw->client_inset.calc = !!cw->frame_object;
2769 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2771 E_Comp_Object *cw = data;
2775 /* - get current size
2777 * - readjust for new frame size
2780 w = cw->ec->w, h = cw->ec->h;
2781 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2783 _e_comp_object_frame_recalc(cw);
2785 if (!cw->ec->fullscreen)
2786 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2788 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2789 if (cw->ec->fullscreen)
2791 zone = e_comp_zone_find_by_ec(cw->ec);
2793 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2795 else if (cw->ec->new_client)
2797 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2798 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2799 evas_object_resize(cw->ec->frame, w, h);
2801 else if ((w != cw->ec->w) || (h != cw->ec->h))
2802 evas_object_resize(cw->ec->frame, w, h);
2806 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2808 E_Comp_Object *cw = data;
2810 _e_comp_object_shadow_setup(cw);
2811 if (cw->frame_object)
2813 _e_comp_object_shadow(cw);
2814 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2815 _e_comp_object_frame_recalc(cw);
2816 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2821 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2823 E_Comp_Object *cw = data;
2825 if (_e_comp_object_shadow_setup(cw))
2826 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2827 if (cw->frame_object)
2829 _e_comp_object_shadow(cw);
2830 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2831 _e_comp_object_frame_recalc(cw);
2832 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2837 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2839 E_Comp_Object *cw = data;
2841 if (cw->frame_object)
2843 _e_comp_object_shadow(cw);
2844 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2845 _e_comp_object_frame_recalc(cw);
2846 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2851 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2853 E_Comp_Object *cw = data;
2855 if (_e_comp_object_shadow_setup(cw))
2858 cw->ec->changes.size = 1;
2860 if (cw->frame_object)
2862 _e_comp_object_shadow(cw);
2863 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2864 _e_comp_object_frame_recalc(cw);
2865 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2870 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2872 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2876 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2878 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2882 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2884 E_Comp_Object *cw = data;
2886 if (!cw->ec) return; //NYI
2887 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2891 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2893 E_Comp_Object *cw = data;
2895 if (!cw->ec) return; //NYI
2896 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2900 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2902 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2906 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2908 E_Comp_Object *cw = data;
2910 if (!e_object_is_del(E_OBJECT(cw->ec)))
2911 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2915 _e_comp_input_obj_smart_add(Evas_Object *obj)
2917 E_Input_Rect_Smart_Data *input_rect_sd;
2918 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2920 if (!input_rect_sd) return;
2921 evas_object_smart_data_set(obj, input_rect_sd);
2925 _e_comp_input_obj_smart_del(Evas_Object *obj)
2927 E_Input_Rect_Smart_Data *input_rect_sd;
2928 E_Input_Rect_Data *input_rect_data;
2930 input_rect_sd = evas_object_smart_data_get(obj);
2931 if (!input_rect_sd) return;
2933 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2935 if (input_rect_data->obj)
2937 evas_object_smart_member_del(input_rect_data->obj);
2938 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2940 E_FREE(input_rect_data);
2942 E_FREE(input_rect_sd);
2946 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2948 E_Input_Rect_Smart_Data *input_rect_sd;
2949 E_Input_Rect_Data *input_rect_data;
2953 input_rect_sd = evas_object_smart_data_get(obj);
2954 if (!input_rect_sd) return;
2956 cw = input_rect_sd->cw;
2957 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2959 if (input_rect_data->obj)
2961 evas_object_geometry_set(input_rect_data->obj,
2962 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2963 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2964 input_rect_data->rect.w, input_rect_data->rect.h);
2970 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2972 E_Input_Rect_Smart_Data *input_rect_sd;
2973 E_Input_Rect_Data *input_rect_data;
2977 input_rect_sd = evas_object_smart_data_get(obj);
2978 if (!input_rect_sd) return;
2980 cw = input_rect_sd->cw;
2981 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2983 if (input_rect_data->obj)
2985 evas_object_geometry_set(input_rect_data->obj,
2986 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2987 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2988 input_rect_data->rect.w, input_rect_data->rect.h);
2994 _e_comp_input_obj_smart_show(Evas_Object *obj)
2996 E_Input_Rect_Smart_Data *input_rect_sd;
2997 E_Input_Rect_Data *input_rect_data;
3000 input_rect_sd = evas_object_smart_data_get(obj);
3001 if (!input_rect_sd) return;
3003 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3005 if (input_rect_data->obj)
3007 evas_object_show(input_rect_data->obj);
3013 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3015 E_Input_Rect_Smart_Data *input_rect_sd;
3016 E_Input_Rect_Data *input_rect_data;
3019 input_rect_sd = evas_object_smart_data_get(obj);
3020 if (!input_rect_sd) return;
3022 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3024 if (input_rect_data->obj)
3026 evas_object_hide(input_rect_data->obj);
3032 _e_comp_input_obj_smart_init(void)
3034 if (_e_comp_input_obj_smart) return;
3036 static const Evas_Smart_Class sc =
3038 INPUT_OBJ_SMART_NAME,
3039 EVAS_SMART_CLASS_VERSION,
3040 _e_comp_input_obj_smart_add,
3041 _e_comp_input_obj_smart_del,
3042 _e_comp_input_obj_smart_move,
3043 _e_comp_input_obj_smart_resize,
3044 _e_comp_input_obj_smart_show,
3045 _e_comp_input_obj_smart_hide,
3058 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3064 _e_comp_smart_add(Evas_Object *obj)
3068 cw = E_NEW(E_Comp_Object, 1);
3069 EINA_SAFETY_ON_NULL_RETURN(cw);
3071 wl_signal_init(&cw->events.lower);
3072 #ifdef REFACTOR_DESK_AREA
3073 wl_signal_init(&cw->events.lower_done);
3074 wl_signal_init(&cw->events.raise);
3076 wl_signal_init(&cw->events.show);
3077 wl_signal_init(&cw->events.hide);
3078 #ifdef REFACTOR_DESK_AREA
3079 wl_signal_init(&cw->events.set_layer);
3080 wl_signal_init(&cw->events.stack_above);
3081 wl_signal_init(&cw->events.stack_below);
3084 cw->smart_obj = obj;
3085 cw->x = cw->y = cw->w = cw->h = -1;
3086 evas_object_smart_data_set(obj, cw);
3087 cw->opacity = 255.0;
3088 cw->external_content = 0;
3089 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3090 cw->transform_bg_color.r = 0;
3091 cw->transform_bg_color.g = 0;
3092 cw->transform_bg_color.b = 0;
3093 cw->transform_bg_color.a = 255;
3094 evas_object_data_set(obj, "comp_obj", cw);
3095 evas_object_move(obj, -1, -1);
3096 /* intercept ALL the callbacks! */
3097 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3098 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3099 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3100 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3101 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3102 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3103 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3104 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3105 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3106 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3107 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3109 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3110 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3111 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3112 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3114 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3115 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3117 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3118 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3120 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3122 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3123 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3127 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3130 evas_object_color_set(cw->clip, r, g, b, a);
3131 evas_object_smart_callback_call(obj, "color_set", NULL);
3136 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3139 evas_object_clip_set(cw->clip, clip);
3143 _e_comp_smart_clip_unset(Evas_Object *obj)
3146 evas_object_clip_unset(cw->clip);
3150 _e_comp_smart_hide(Evas_Object *obj)
3152 TRACE_DS_BEGIN(COMP:SMART HIDE);
3157 evas_object_hide(cw->clip);
3158 if (cw->input_obj) evas_object_hide(cw->input_obj);
3159 evas_object_hide(cw->effect_obj);
3160 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3161 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3162 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3169 /* unset native surface if current displaying buffer was destroied */
3170 if (!cw->buffer_destroy_listener.notify)
3172 Evas_Native_Surface *ns;
3173 ns = evas_object_image_native_surface_get(cw->obj);
3174 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3175 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3178 if (!cw->ec->input_only)
3180 edje_object_freeze(cw->effect_obj);
3181 edje_object_freeze(cw->shobj);
3182 edje_object_play_set(cw->shobj, 0);
3183 if (cw->frame_object)
3184 edje_object_play_set(cw->frame_object, 0);
3187 e_comp_render_queue(); //force nocomp recheck
3193 _e_comp_smart_show(Evas_Object *obj)
3201 if ((cw->w < 0) || (cw->h < 0))
3202 CRI("ACK! ec:%p", cw->ec);
3204 TRACE_DS_BEGIN(COMP:SMART SHOW);
3206 e_comp_object_map_update(obj);
3208 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3209 evas_object_show(tmp->frame);
3211 evas_object_show(cw->clip);
3212 if (cw->input_obj) evas_object_show(cw->input_obj);
3213 if (!cw->ec->input_only)
3215 edje_object_thaw(cw->effect_obj);
3216 edje_object_thaw(cw->shobj);
3217 edje_object_play_set(cw->shobj, 1);
3218 if (cw->frame_object)
3219 edje_object_play_set(cw->frame_object, 1);
3221 evas_object_show(cw->effect_obj);
3222 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3223 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3224 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3225 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3226 e_comp_render_queue();
3227 if (cw->ec->input_only)
3232 if (cw->ec->iconic && (!cw->ec->new_client))
3234 if (e_client_is_iconified_by_client(cw->ec))
3236 ELOGF("COMP", "Set launching flag..", cw->ec);
3237 cw->ec->launching = EINA_TRUE;
3240 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3242 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3245 ELOGF("COMP", "Set launching flag..", cw->ec);
3246 cw->ec->launching = EINA_TRUE;
3248 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3249 _e_comp_object_animating_begin(cw);
3250 if (!_e_comp_object_effect_visibility_start(cw, 1))
3256 /* ensure some random effect doesn't lock the client offscreen */
3260 e_comp_object_effect_set(obj, NULL);
3263 _e_comp_object_dim_update(cw);
3269 _e_comp_smart_del(Evas_Object *obj)
3275 if (cw->buffer_destroy_listener.notify)
3277 wl_list_remove(&cw->buffer_destroy_listener.link);
3278 cw->buffer_destroy_listener.notify = NULL;
3281 if (cw->tbm_surface)
3283 tbm_surface_internal_unref(cw->tbm_surface);
3284 cw->tbm_surface = NULL;
3287 if (cw->render_update_lock.buffer_ref.buffer)
3289 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3290 cw->ec, cw->render_update_lock.lock);
3291 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3294 e_comp_object_render_update_del(cw->smart_obj);
3295 E_FREE_FUNC(cw->updates, eina_tiler_free);
3296 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3303 EINA_LIST_FREE(cw->obj_mirror, o)
3305 evas_object_image_data_set(o, NULL);
3306 evas_object_freeze_events_set(o, 1);
3307 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3311 #ifdef REFACTOR_DESK_AREA
3313 _e_comp_object_layers_remove(cw);
3315 l = evas_object_data_get(obj, "comp_object-to_del");
3316 E_FREE_LIST(l, evas_object_del);
3317 _e_comp_object_mouse_event_callback_unset(cw);
3318 evas_object_del(cw->clip);
3319 evas_object_del(cw->obj);
3320 evas_object_del(cw->shobj);
3321 evas_object_del(cw->effect_obj);
3322 evas_object_del(cw->frame_object);
3323 evas_object_del(cw->input_obj);
3324 evas_object_del(cw->mask.obj);
3325 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3326 evas_object_del(cw->transform_bg_obj);
3327 evas_object_del(cw->transform_tranp_obj);
3328 evas_object_del(cw->default_input_obj);
3329 eina_stringshare_del(cw->frame_theme);
3330 eina_stringshare_del(cw->frame_name);
3334 e_comp->animating--;
3336 e_object_unref(E_OBJECT(cw->ec));
3338 cw->ec->frame = NULL;
3343 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3347 cw->x = x, cw->y = y;
3348 evas_object_move(cw->effect_obj, x, y);
3349 evas_object_move(cw->default_input_obj, x, y);
3350 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3352 e_comp_object_map_update(obj);
3356 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3358 Eina_Bool first = EINA_FALSE;
3363 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3365 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3367 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3369 if (cw->w != w || cw->h != h)
3370 e_comp_object_map_update(obj);
3372 first = ((cw->w < 1) || (cw->h < 1));
3373 cw->w = w, cw->h = h;
3377 if (cw->frame_object)
3378 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3381 /* verify pixmap:object size */
3382 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3384 if ((ww != pw) || (hh != ph))
3385 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3387 evas_object_resize(cw->effect_obj, tw, th);
3388 evas_object_resize(cw->default_input_obj, w, h);
3390 evas_object_resize(cw->input_obj, w, h);
3392 evas_object_resize(cw->mask.obj, w, h);
3393 /* resize render update tiler */
3396 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3397 cw->updates_full = 0;
3398 if (cw->updates) eina_tiler_clear(cw->updates);
3402 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3403 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3411 e_comp_render_queue();
3417 _e_comp_smart_init(void)
3419 if (_e_comp_smart) return;
3421 static const Evas_Smart_Class sc =
3424 EVAS_SMART_CLASS_VERSION,
3428 _e_comp_smart_resize,
3431 _e_comp_smart_color_set,
3432 _e_comp_smart_clip_set,
3433 _e_comp_smart_clip_unset,
3443 _e_comp_smart = evas_smart_class_new(&sc);
3448 e_comp_object_init(void)
3450 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3451 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3452 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3453 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3457 e_comp_object_shutdown(void)
3463 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3465 API_ENTRY EINA_FALSE;
3466 return !!cw->force_visible;
3468 /////////////////////////////////////////////////////////
3471 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3474 Eina_Bool comp_object;
3476 comp_object = !!evas_object_data_get(obj, "comp_object");
3481 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3483 e_comp_render_queue();
3485 l = evas_object_data_get(obj, "comp_object-to_del");
3486 E_FREE_LIST(l, evas_object_del);
3490 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3492 if (e_comp_util_object_is_above_nocomp(obj) &&
3493 (!evas_object_data_get(obj, "comp_override")))
3495 evas_object_data_set(obj, "comp_override", (void*)1);
3496 e_comp_override_add();
3501 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3503 Eina_Bool ref = EINA_TRUE;
3504 if (evas_object_visible_get(obj))
3508 d = evas_object_data_del(obj, "comp_hiding");
3510 /* currently trying to hide */
3513 /* already visible */
3517 evas_object_show(obj);
3520 evas_object_ref(obj);
3521 evas_object_data_set(obj, "comp_ref", (void*)1);
3523 edje_object_signal_emit(obj, "e,state,visible", "e");
3524 evas_object_data_set(obj, "comp_showing", (void*)1);
3525 if (e_comp_util_object_is_above_nocomp(obj))
3527 evas_object_data_set(obj, "comp_override", (void*)1);
3528 e_comp_override_add();
3533 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3535 if (!evas_object_visible_get(obj)) return;
3536 /* already hiding */
3537 if (evas_object_data_get(obj, "comp_hiding")) return;
3538 if (!evas_object_data_del(obj, "comp_showing"))
3540 evas_object_ref(obj);
3541 evas_object_data_set(obj, "comp_ref", (void*)1);
3543 edje_object_signal_emit(obj, "e,state,hidden", "e");
3544 evas_object_data_set(obj, "comp_hiding", (void*)1);
3546 if (evas_object_data_del(obj, "comp_override"))
3547 e_comp_override_timed_pop();
3551 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3553 if (!e_util_strcmp(emission, "e,action,hide,done"))
3555 if (!evas_object_data_del(obj, "comp_hiding")) return;
3556 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3557 evas_object_hide(obj);
3558 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3561 evas_object_data_del(obj, "comp_showing");
3562 if (evas_object_data_del(obj, "comp_ref"))
3563 evas_object_unref(obj);
3567 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3573 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3577 E_API E_Comp_Object_Hook *
3578 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3580 E_Comp_Object_Hook *ch;
3582 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3583 ch = E_NEW(E_Comp_Object_Hook, 1);
3584 if (!ch) return NULL;
3585 ch->hookpoint = hookpoint;
3587 ch->data = (void*)data;
3588 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3593 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3596 if (_e_comp_object_hooks_walking == 0)
3598 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3602 _e_comp_object_hooks_delete++;
3605 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3606 E_API E_Comp_Object_Intercept_Hook *
3607 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3609 E_Comp_Object_Intercept_Hook *ch;
3611 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3612 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3613 if (!ch) return NULL;
3614 ch->hookpoint = hookpoint;
3616 ch->data = (void*)data;
3617 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3622 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3625 if (_e_comp_object_intercept_hooks_walking == 0)
3627 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3631 _e_comp_object_intercept_hooks_delete++;
3636 e_comp_object_util_add(Evas_Object *obj)
3640 E_Comp_Config *conf = e_comp_config_get();
3641 Eina_Bool skip = EINA_FALSE;
3647 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3649 name = evas_object_name_get(obj);
3650 vis = evas_object_visible_get(obj);
3651 o = edje_object_add(e_comp->evas);
3652 evas_object_data_set(o, "comp_object", (void*)1);
3654 skip = (!strncmp(name, "noshadow", 8));
3656 evas_object_data_set(o, "comp_object_skip", (void*)1);
3658 if (conf->shadow_style)
3660 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3661 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3664 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3665 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3666 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3668 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3670 evas_object_geometry_get(obj, &x, &y, &w, &h);
3671 evas_object_geometry_set(o, x, y, w, h);
3672 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3674 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3676 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3677 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3678 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3679 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3680 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3681 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3683 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3685 edje_object_part_swallow(o, "e.swallow.content", obj);
3687 _e_comp_object_event_add(o);
3690 evas_object_show(o);
3695 /* utility functions for deleting objects when their "owner" is deleted */
3697 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3702 EINA_SAFETY_ON_NULL_RETURN(to_del);
3703 l = evas_object_data_get(obj, "comp_object-to_del");
3704 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3705 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3706 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3710 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3715 EINA_SAFETY_ON_NULL_RETURN(to_del);
3716 l = evas_object_data_get(obj, "comp_object-to_del");
3718 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3721 /////////////////////////////////////////////////////////
3723 EINTERN Evas_Object *
3724 e_comp_object_client_add(E_Client *ec)
3729 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3730 if (ec->frame) return NULL;
3731 _e_comp_smart_init();
3732 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3733 cw = evas_object_smart_data_get(o);
3734 if (!cw) return NULL;
3735 evas_object_data_set(o, "E_Client", ec);
3738 evas_object_data_set(o, "comp_object", (void*)1);
3740 _e_comp_object_event_add(o);
3745 /* utility functions for getting client inset */
3747 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3750 if (!cw->client_inset.calc)
3756 if (ax) *ax = x - cw->client_inset.l;
3757 if (ay) *ay = y - cw->client_inset.t;
3761 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3764 if (!cw->client_inset.calc)
3770 if (ax) *ax = x + cw->client_inset.l;
3771 if (ay) *ay = y + cw->client_inset.t;
3775 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3778 if (!cw->client_inset.calc)
3784 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3785 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3789 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3792 if (!cw->client_inset.calc)
3798 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3799 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3803 e_comp_object_client_get(Evas_Object *obj)
3808 /* FIXME: remove this when eo is used */
3809 o = evas_object_data_get(obj, "comp_smart_obj");
3811 return e_comp_object_client_get(o);
3812 return cw ? cw->ec : NULL;
3816 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3819 if (cw->frame_extends)
3820 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3825 if (w) *w = cw->ec->w;
3826 if (h) *h = cw->ec->h;
3831 e_comp_object_util_zone_get(Evas_Object *obj)
3833 E_Zone *zone = NULL;
3837 zone = e_comp_zone_find_by_ec(cw->ec);
3842 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3843 zone = e_comp_zone_xy_get(x, y);
3849 e_comp_object_util_center(Evas_Object *obj)
3851 int x, y, w, h, ow, oh;
3856 zone = e_comp_object_util_zone_get(obj);
3857 EINA_SAFETY_ON_NULL_RETURN(zone);
3858 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3859 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3860 ow = cw->ec->w, oh = cw->ec->h;
3862 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3863 x = x + (w - ow) / 2;
3864 y = y + (h - oh) / 2;
3865 evas_object_move(obj, x, y);
3869 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3871 int x, y, w, h, ow, oh;
3874 EINA_SAFETY_ON_NULL_RETURN(on);
3875 evas_object_geometry_get(on, &x, &y, &w, &h);
3876 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3877 ow = cw->ec->w, oh = cw->ec->h;
3879 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3880 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3884 e_comp_object_util_fullscreen(Evas_Object *obj)
3889 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3892 evas_object_move(obj, 0, 0);
3893 evas_object_resize(obj, e_comp->w, e_comp->h);
3898 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3906 ow = cw->w, oh = cw->h;
3908 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3909 zone = e_comp_object_util_zone_get(obj);
3910 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3911 if (x) *x = zx + (zw - ow) / 2;
3912 if (y) *y = zy + (zh - oh) / 2;
3916 e_comp_object_input_objs_del(Evas_Object *obj)
3919 E_Input_Rect_Data *input_rect_data;
3920 E_Input_Rect_Smart_Data *input_rect_sd;
3925 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3926 if (!input_rect_sd) return;
3928 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3930 if (input_rect_data->obj)
3932 evas_object_smart_member_del(input_rect_data->obj);
3933 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3935 E_FREE(input_rect_data);
3940 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3943 E_Input_Rect_Data *input_rect_data = NULL;
3944 E_Input_Rect_Smart_Data *input_rect_sd;
3945 int client_w, client_h;
3947 if (cw->ec->client.w)
3948 client_w = cw->ec->client.w;
3950 client_w = cw->ec->w;
3952 if (cw->ec->client.h)
3953 client_h = cw->ec->client.h;
3955 client_h = cw->ec->h;
3957 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3961 _e_comp_input_obj_smart_init();
3962 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3963 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3964 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3967 input_rect_sd->cw = cw;
3970 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3973 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3974 if (input_rect_data)
3976 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3977 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3981 if ((input_rect_data) &&
3982 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3984 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3985 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3986 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3987 evas_object_clip_set(input_rect_data->obj, cw->clip);
3988 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3989 evas_object_geometry_set(input_rect_data->obj,
3990 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3991 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3992 evas_object_pass_events_set(cw->default_input_obj, 1);
3993 evas_object_pass_events_set(cw->obj, 1);
3996 evas_object_show(input_rect_data->obj);
3997 evas_object_show(cw->input_obj);
4002 evas_object_smart_member_del(cw->input_obj);
4003 E_FREE_FUNC(cw->input_obj, evas_object_del);
4004 evas_object_pass_events_set(cw->default_input_obj, 0);
4005 evas_object_pass_events_set(cw->obj, 0);
4010 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4013 E_Input_Rect_Smart_Data *input_rect_sd;
4014 E_Input_Rect_Data *input_rect_data;
4017 if (!cw->input_obj) return;
4019 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4022 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4024 *list = eina_list_append(*list, &input_rect_data->rect);
4030 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4033 if (l) *l = cw->client_inset.l;
4034 if (r) *r = cw->client_inset.r;
4035 if (t) *t = cw->client_inset.t;
4036 if (b) *b = cw->client_inset.b;
4039 /* set geometry for CSD */
4041 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4047 if (cw->frame_object)
4048 CRI("ACK! ec:%p", cw->ec);
4049 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4050 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4051 calc = cw->client_inset.calc;
4052 cw->client_inset.calc = l || r || t || b;
4053 eina_stringshare_replace(&cw->frame_theme, "borderless");
4054 if (cw->client_inset.calc)
4056 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4057 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4058 e_client_size_set(cw->ec, tw, th);
4060 else if (cw->ec->maximized || cw->ec->fullscreen)
4062 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4063 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4065 if (!cw->ec->new_client)
4067 if (calc && cw->client_inset.calc)
4069 tx = cw->ec->x - (l - cw->client_inset.l);
4070 ty = cw->ec->y - (t - cw->client_inset.t);
4071 e_client_pos_set(cw->ec, tx, ty);
4073 cw->ec->changes.pos = cw->ec->changes.size = 1;
4076 cw->client_inset.l = l;
4077 cw->client_inset.r = r;
4078 cw->client_inset.t = t;
4079 cw->client_inset.b = b;
4083 e_comp_object_frame_allowed(Evas_Object *obj)
4085 API_ENTRY EINA_FALSE;
4086 return (cw->frame_object || (!cw->client_inset.calc));
4090 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4092 API_ENTRY EINA_FALSE;
4093 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4094 eina_stringshare_replace(&cw->frame_name, name);
4095 if (cw->frame_object)
4096 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4101 e_comp_object_frame_exists(Evas_Object *obj)
4103 API_ENTRY EINA_FALSE;
4104 return !!cw->frame_object;
4108 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4110 Evas_Object *o, *pbg;
4113 Eina_Stringshare *theme;
4115 API_ENTRY EINA_FALSE;
4117 if (!e_util_strcmp(cw->frame_theme, name))
4118 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4119 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4120 return _e_comp_object_shadow_setup(cw);
4121 pbg = cw->frame_object;
4122 theme = eina_stringshare_add(name);
4124 if (cw->frame_object)
4128 w = cw->ec->w, h = cw->ec->h;
4129 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4130 if ((cw->ec->w != w) || (cw->ec->h != h))
4132 cw->ec->changes.size = 1;
4135 E_FREE_FUNC(cw->frame_object, evas_object_del);
4136 if (!name) goto reshadow;
4138 o = edje_object_add(e_comp->evas);
4139 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4140 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4141 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4143 cw->frame_object = NULL;
4145 eina_stringshare_del(cw->frame_theme);
4146 cw->frame_theme = theme;
4151 if (theme != e_config->theme_default_border_style)
4153 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4154 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4158 ok = e_theme_edje_object_set(o, "base/theme/border",
4159 "e/widgets/border/default/border");
4160 if (ok && (theme == e_config->theme_default_border_style))
4162 /* Reset default border style to default */
4163 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4164 e_config_save_queue();
4171 cw->frame_object = o;
4172 eina_stringshare_del(cw->frame_theme);
4173 cw->frame_theme = theme;
4174 evas_object_name_set(o, "cw->frame_object");
4177 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4181 cw->ec->changes.icon = 1;
4187 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4192 _e_comp_object_shadow_setup(cw);
4195 int old_x, old_y, new_x = 0, new_y = 0;
4197 old_x = cw->x, old_y = cw->y;
4199 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4201 new_x = cw->ec->x, new_y = cw->ec->y;
4202 else if (cw->ec->placed || (!cw->ec->new_client))
4204 /* if no previous frame:
4205 * - reapply client_inset
4210 if (cw->ec->changes.size)
4218 zone = e_comp_zone_find_by_ec(cw->ec);
4221 x = cw->ec->client.x, y = cw->ec->client.y;
4222 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4223 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4225 new_x = x, new_y = y;
4228 if (old_x != new_x || old_y != new_y)
4230 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4231 cw->y = cw->x = -99999;
4232 evas_object_move(obj, new_x, new_y);
4236 if (cw->ec->maximized)
4238 cw->ec->changes.need_maximize = 1;
4241 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4242 if (cw->frame_object)
4244 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4247 cw->frame_extends = 0;
4248 evas_object_del(pbg);
4253 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4255 E_Comp_Object_Mover *prov;
4258 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4259 edje_object_signal_emit(cw->shobj, sig, src);
4260 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4261 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4262 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4264 /* start with highest priority callback first */
4265 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4267 if (!e_util_glob_match(sig, prov->sig)) continue;
4268 if (prov->func(prov->data, obj, sig)) break;
4273 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4275 /* FIXME: at some point I guess this should use eo to inherit
4276 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4277 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4280 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4284 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4287 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4291 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4294 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4298 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4301 Eina_Rectangle rect;
4304 if (cw->ec->input_only || (!cw->updates)) return;
4305 if (cw->nocomp) return;
4306 rect.x = x, rect.y = y;
4307 rect.w = w, rect.h = h;
4308 evas_object_smart_callback_call(obj, "damage", &rect);
4310 if (e_comp_is_on_overlay(cw->ec))
4312 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4313 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4314 * E module attempts to block screen update due to the particular policy.
4316 if (e_pixmap_resource_get(cw->ec->pixmap))
4317 cw->hwc_need_update = EINA_TRUE;
4320 /* ignore overdraw */
4321 if (cw->updates_full)
4323 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4324 e_comp_object_render_update_add(obj);
4326 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4327 evas_object_show(cw->smart_obj);
4331 /* clip rect to client surface */
4332 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4333 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4334 /* if rect is the total size of the client after clip, clear the updates
4335 * since this is guaranteed to be the whole region anyway
4337 eina_tiler_area_size_get(cw->updates, &tw, &th);
4338 if ((w > tw) || (h > th))
4340 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4341 eina_tiler_clear(cw->updates);
4342 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4344 tw = cw->ec->client.w, th = cw->ec->client.h;
4346 if ((!x) && (!y) && (w == tw) && (h == th))
4348 eina_tiler_clear(cw->updates);
4349 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4350 cw->updates_full = 1;
4351 cw->update_count = 0;
4354 if (cw->update_count > UPDATE_MAX)
4356 /* this is going to get really dumb, so just update the whole thing */
4357 eina_tiler_clear(cw->updates);
4358 cw->update_count = cw->updates_full = 1;
4359 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4360 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4364 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4365 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4367 cw->updates_exist = 1;
4368 e_comp_object_render_update_add(obj);
4370 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4371 evas_object_show(cw->smart_obj);
4375 e_comp_object_damage_exists(Evas_Object *obj)
4377 API_ENTRY EINA_FALSE;
4378 return cw->updates_exist;
4382 e_comp_object_render_update_add(Evas_Object *obj)
4386 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4387 if (cw->render_update_lock.lock) return;
4388 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4392 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4394 e_comp_render_queue();
4398 e_comp_object_render_update_del(Evas_Object *obj)
4402 if (cw->ec->input_only || (!cw->updates)) return;
4403 if (!cw->update) return;
4405 /* this gets called during comp animating to clear the update flag */
4406 if (e_comp->grabbed) return;
4407 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4408 if (!e_comp->updates)
4410 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4411 if (e_comp->render_animator)
4412 ecore_animator_freeze(e_comp->render_animator);
4417 e_comp_object_shape_apply(Evas_Object *obj)
4421 unsigned int i, *pix, *p;
4425 if (!cw->ec) return; //NYI
4426 if (cw->external_content) return;
4429 if ((cw->ec->shape_rects_num >= 1) &&
4430 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4435 ERR("BUGGER: shape with native surface? cw=%p", cw);
4438 evas_object_image_size_get(cw->obj, &w, &h);
4439 if ((w < 1) || (h < 1)) return;
4442 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4443 _e_comp_object_alpha_set(cw);
4444 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4445 evas_object_image_alpha_set(o, 1);
4447 p = pix = evas_object_image_data_get(cw->obj, 1);
4450 evas_object_image_data_set(cw->obj, pix);
4455 unsigned char *spix, *sp;
4457 spix = calloc(w * h, sizeof(unsigned char));
4459 for (i = 0; i < cw->ec->shape_rects_num; i++)
4463 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4464 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4465 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4466 sp = spix + (w * ry) + rx;
4467 for (py = 0; py < rh; py++)
4469 for (px = 0; px < rw; px++)
4477 for (py = 0; py < h; py++)
4479 for (px = 0; px < w; px++)
4481 unsigned int mask, imask;
4483 mask = ((unsigned int)(*sp)) << 24;
4485 imask |= imask >> 8;
4486 imask |= imask >> 8;
4487 *p = mask | (*p & imask);
4488 //if (*sp) *p = 0xff000000 | *p;
4489 //else *p = 0x00000000;
4498 for (py = 0; py < h; py++)
4500 for (px = 0; px < w; px++)
4504 evas_object_image_data_set(cw->obj, pix);
4505 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4506 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4508 evas_object_image_data_set(o, pix);
4509 evas_object_image_data_update_add(o, 0, 0, w, h);
4511 // don't need to fix alpha chanel as blending
4512 // should be totally off here regardless of
4513 // alpha channel content
4517 _e_comp_object_clear(E_Comp_Object *cw)
4522 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4524 if (cw->render_update_lock.lock) return;
4527 e_pixmap_clear(cw->ec->pixmap);
4529 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4530 evas_object_image_size_set(cw->obj, 1, 1);
4531 evas_object_image_data_set(cw->obj, NULL);
4532 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4534 evas_object_image_size_set(o, 1, 1);
4535 evas_object_image_data_set(o, NULL);
4538 e_comp_object_render_update_del(cw->smart_obj);
4542 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4546 API_ENTRY EINA_FALSE;
4548 if (cw->transparent.set == set)
4553 evas_object_color_get(obj, &r, &g, &b, &a);
4554 evas_object_color_set(obj, 0, 0, 0, 0);
4556 cw->transparent.user_r = r;
4557 cw->transparent.user_g = g;
4558 cw->transparent.user_b = b;
4559 cw->transparent.user_a = a;
4561 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4563 cw->transparent.user_r,
4564 cw->transparent.user_g,
4565 cw->transparent.user_b,
4566 cw->transparent.user_a);
4568 cw->transparent.set = EINA_TRUE;
4572 cw->transparent.set = EINA_FALSE;
4574 evas_object_color_set(obj,
4575 cw->transparent.user_r,
4576 cw->transparent.user_g,
4577 cw->transparent.user_b,
4578 cw->transparent.user_a);
4580 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4582 cw->transparent.user_r,
4583 cw->transparent.user_g,
4584 cw->transparent.user_b,
4585 cw->transparent.user_a);
4591 /* helper function to simplify toggling of redirection for display servers which support it */
4593 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4598 if (cw->redirected == set) return;
4599 cw->redirected = set;
4600 if (cw->external_content) return;
4602 e_comp_object_map_update(obj);
4606 if (cw->updates_exist)
4607 e_comp_object_render_update_add(obj);
4609 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4611 _e_comp_object_transparent_set(obj, EINA_FALSE);
4612 evas_object_smart_callback_call(obj, "redirected", NULL);
4616 _e_comp_object_clear(cw);
4617 _e_comp_object_transparent_set(obj, EINA_TRUE);
4618 evas_object_smart_callback_call(obj, "unredirected", NULL);
4623 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4626 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4628 if (cw->buffer_destroy_listener.notify)
4630 cw->buffer_destroy_listener.notify = NULL;
4631 wl_list_remove(&cw->buffer_destroy_listener.link);
4634 if (e_object_is_del(E_OBJECT(cw->ec)))
4636 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4641 /* if it's current displaying buffer, do not remove its content */
4642 if (!evas_object_visible_get(cw->ec->frame))
4643 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4648 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4653 if (cw->buffer_destroy_listener.notify)
4655 wl_list_remove(&cw->buffer_destroy_listener.link);
4656 cw->buffer_destroy_listener.notify = NULL;
4659 if (cw->tbm_surface)
4661 tbm_surface_internal_unref(cw->tbm_surface);
4662 cw->tbm_surface = NULL;
4667 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4669 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4670 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4672 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4674 tbm_surface_internal_ref(ns->data.tbm.buffer);
4675 cw->tbm_surface = ns->data.tbm.buffer;
4679 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4680 evas_object_image_native_surface_set(cw->obj, ns);
4684 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4686 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4687 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4688 evas_object_image_native_surface_set(o, ns);
4695 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4697 Evas_Native_Surface ns;
4700 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4701 if (cw->ec->input_only) return;
4702 if (cw->external_content) return;
4703 if (cw->render_update_lock.lock) return;
4706 memset(&ns, 0, sizeof(Evas_Native_Surface));
4710 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4711 set = (!cw->ec->shaped);
4713 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4717 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4721 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4724 if (cw->ec->input_only) return;
4727 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4728 _e_comp_object_alpha_set(cw);
4730 e_comp_object_native_surface_set(obj, cw->native);
4731 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4735 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4741 if (cw->blanked == set) return;
4743 _e_comp_object_alpha_set(cw);
4746 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4747 evas_object_image_data_set(cw->obj, NULL);
4751 e_comp_object_native_surface_set(obj, 1);
4752 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4756 _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)
4761 if (!_damage_trace) return;
4765 if (!evas_object_visible_get(cw->obj)) return;
4767 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4769 o = evas_object_rectangle_add(e_comp->evas);
4770 evas_object_layer_set(o, E_LAYER_MAX);
4771 evas_object_name_set(o, "damage_trace");
4772 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4773 evas_object_resize(o, dmg_w, dmg_h);
4774 evas_object_color_set(o, 0, 128, 0, 128);
4775 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4776 evas_object_pass_events_set(o, EINA_TRUE);
4777 evas_object_show(o);
4779 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4781 dmg_w, dmg_h, dmg_x, dmg_y,
4782 origin->w, origin->h, origin->x, origin->y);
4784 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4787 /* mark an object as dirty and setup damages */
4789 e_comp_object_dirty(Evas_Object *obj)
4792 Eina_Rectangle *rect;
4796 Eina_Bool dirty, visible;
4800 if (cw->external_content) return;
4801 if (!cw->redirected) return;
4802 if (cw->render_update_lock.lock)
4804 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4807 /* only actually dirty if pixmap is available */
4808 if (!e_pixmap_resource_get(cw->ec->pixmap))
4810 // e_pixmap_size_get returns last attached buffer size
4811 // eventhough it is destroyed
4812 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4815 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4816 visible = cw->visible;
4817 if (!dirty) w = h = 1;
4818 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4820 evas_object_image_data_set(cw->obj, NULL);
4821 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4822 evas_object_image_size_set(cw->obj, tw, th);
4823 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4824 if (cw->pending_updates)
4825 eina_tiler_area_size_set(cw->pending_updates, w, h);
4826 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4828 evas_object_image_pixels_dirty_set(o, dirty);
4830 evas_object_image_data_set(o, NULL);
4831 evas_object_image_size_set(o, tw, th);
4832 visible |= evas_object_visible_get(o);
4836 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4840 e_comp_object_native_surface_set(obj, 1);
4842 m = _e_comp_object_map_damage_transform_get(cw->ec);
4843 it = eina_tiler_iterator_new(cw->updates);
4844 EINA_ITERATOR_FOREACH(it, rect)
4846 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4847 * of evas engine and doesn't convert damage according to evas_map.
4848 * so damage of evas_object_image use surface coordinate.
4852 int damage_x, damage_y, damage_w, damage_h;
4854 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4855 &damage_x, &damage_y, &damage_w, &damage_h);
4856 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4857 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4861 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4862 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4865 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4866 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4867 if (cw->pending_updates)
4868 eina_tiler_rect_add(cw->pending_updates, rect);
4870 eina_iterator_free(it);
4871 if (m) e_map_free(m);
4872 if (cw->pending_updates)
4873 eina_tiler_clear(cw->updates);
4876 cw->pending_updates = cw->updates;
4877 cw->updates = eina_tiler_new(w, h);
4878 eina_tiler_tile_size_set(cw->updates, 1, 1);
4880 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4881 evas_object_smart_callback_call(obj, "dirty", NULL);
4882 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4883 /* force render if main object is hidden but mirrors are visible */
4884 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4885 e_comp_object_render(obj);
4889 e_comp_object_render(Evas_Object *obj)
4896 API_ENTRY EINA_FALSE;
4898 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4899 if (cw->ec->input_only) return EINA_TRUE;
4900 if (cw->external_content) return EINA_TRUE;
4901 if (cw->native) return EINA_FALSE;
4902 /* if comp object is not redirected state, comp object should not be set by newly committed data
4903 because image size of comp object is 1x1 and it should not be shown on canvas */
4904 if (!cw->redirected) return EINA_TRUE;
4905 if (cw->render_update_lock.lock)
4907 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4910 e_comp_object_render_update_del(obj);
4911 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4913 if (!cw->pending_updates)
4915 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4916 evas_object_image_data_set(cw->obj, NULL);
4917 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4918 evas_object_image_data_set(o, NULL);
4922 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4924 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4926 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4929 e_pixmap_image_refresh(cw->ec->pixmap);
4930 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4933 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4934 e_pixmap_image_data_ref(cw->ec->pixmap);
4936 /* set pixel data */
4937 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4938 _e_comp_object_alpha_set(cw);
4939 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4941 evas_object_image_data_set(o, pix);
4942 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4943 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4946 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4948 e_comp_client_post_update_add(cw->ec);
4953 /* create a duplicate of an evas object */
4955 e_comp_object_util_mirror_add(Evas_Object *obj)
4959 unsigned int *pix = NULL;
4960 Eina_Bool argb = EINA_FALSE;
4965 cw = evas_object_data_get(obj, "comp_mirror");
4968 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4969 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4970 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4971 evas_object_image_alpha_set(o, 1);
4972 evas_object_image_source_set(o, obj);
4975 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4976 if (cw->external_content)
4978 ERR("%p of client %p is external content.", obj, cw->ec);
4981 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4982 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4983 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4984 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4985 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4986 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4987 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4988 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4989 evas_object_data_set(o, "comp_mirror", cw);
4991 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4992 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4994 evas_object_image_size_set(o, tw, th);
4997 pix = evas_object_image_data_get(cw->obj, 0);
5003 evas_object_image_native_surface_set(o, cw->ns);
5006 Evas_Native_Surface ns;
5007 memset(&ns, 0, sizeof(Evas_Native_Surface));
5008 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5009 evas_object_image_native_surface_set(o, &ns);
5014 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5015 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5017 (e_pixmap_image_exists(cw->ec->pixmap)))
5018 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5020 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5027 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5028 evas_object_image_pixels_dirty_set(o, dirty);
5029 evas_object_image_data_set(o, pix);
5030 evas_object_image_data_set(cw->obj, pix);
5032 evas_object_image_data_update_add(o, 0, 0, tw, th);
5037 //////////////////////////////////////////////////////
5040 e_comp_object_effect_allowed_get(Evas_Object *obj)
5042 API_ENTRY EINA_FALSE;
5044 if (!cw->shobj) return EINA_FALSE;
5045 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5046 return !e_comp_config_get()->match.disable_borders;
5049 /* setup an api effect for a client */
5051 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5054 Eina_Stringshare *grp;
5055 E_Comp_Config *config;
5056 Eina_Bool loaded = EINA_FALSE;
5058 API_ENTRY EINA_FALSE;
5059 if (!cw->shobj) return EINA_FALSE; //input window
5061 if (!effect) effect = "none";
5062 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5064 config = e_comp_config_get();
5065 if ((config) && (config->effect_file))
5067 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5069 cw->effect_set = EINA_TRUE;
5076 edje_object_file_get(cw->effect_obj, NULL, &grp);
5077 cw->effect_set = !eina_streq(effect, "none");
5078 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5079 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5081 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5082 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5083 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5085 if (cw->effect_running)
5087 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5090 cw->effect_set = EINA_FALSE;
5091 return cw->effect_set;
5095 if (cw->effect_running)
5097 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5100 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5101 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5102 if (cw->effect_clip)
5104 evas_object_clip_unset(cw->clip);
5105 cw->effect_clip = 0;
5107 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5109 _e_comp_object_dim_update(cw);
5111 return cw->effect_set;
5114 /* set params for embryo scripts in effect */
5116 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5118 Edje_Message_Int_Set *msg;
5122 EINA_SAFETY_ON_NULL_RETURN(params);
5123 EINA_SAFETY_ON_FALSE_RETURN(count);
5124 if (!cw->effect_set) return;
5126 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5127 msg->count = (int)count;
5128 for (x = 0; x < count; x++)
5129 msg->val[x] = params[x];
5130 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5131 edje_object_message_signal_process(cw->effect_obj);
5135 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5137 Edje_Signal_Cb end_cb;
5139 E_Comp_Object *cw = data;
5141 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5142 cw->effect_running = 0;
5143 if (!_e_comp_object_animating_end(cw)) return;
5145 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5147 evas_object_data_del(cw->smart_obj, "effect_running");
5148 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5149 e_comp_visibility_calculation_set(EINA_TRUE);
5152 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5153 if (!end_cb) return;
5154 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5155 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5156 end_cb(end_data, cw->smart_obj, emission, source);
5159 /* clip effect to client's zone */
5161 e_comp_object_effect_clip(Evas_Object *obj)
5165 zone = e_comp_zone_find_by_ec(cw->ec);
5167 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5168 if (!cw->effect_clip_able) return;
5169 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5170 cw->effect_clip = 1;
5173 /* unclip effect from client's zone */
5175 e_comp_object_effect_unclip(Evas_Object *obj)
5178 if (!cw->effect_clip) return;
5179 evas_object_clip_unset(cw->smart_obj);
5180 cw->effect_clip = 0;
5183 /* start effect, running end_cb after */
5185 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5187 API_ENTRY EINA_FALSE;
5188 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5189 if (!cw->effect_set) return EINA_FALSE;
5191 if (cw->effect_running)
5193 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5196 e_comp_object_effect_clip(obj);
5197 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5199 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5200 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5201 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5202 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5204 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5205 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5207 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5208 _e_comp_object_animating_begin(cw);
5209 cw->effect_running = 1;
5213 /* stop a currently-running effect immediately */
5215 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5218 Edje_Signal_Cb end_cb_before = NULL;
5219 void *end_data_before = NULL;
5220 API_ENTRY EINA_FALSE;
5222 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5223 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5225 if (end_cb_before != end_cb) return EINA_TRUE;
5226 e_comp_object_effect_unclip(obj);
5227 if (cw->effect_clip)
5229 evas_object_clip_unset(cw->effect_obj);
5230 cw->effect_clip = 0;
5232 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5233 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5235 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5237 evas_object_data_del(cw->smart_obj, "effect_running");
5238 e_comp_visibility_calculation_set(EINA_TRUE);
5241 cw->effect_running = 0;
5242 ret = _e_comp_object_animating_end(cw);
5244 if ((ret) && (end_cb_before))
5246 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5247 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5254 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5256 return a->pri - b->pri;
5259 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5260 E_API E_Comp_Object_Mover *
5261 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5263 E_Comp_Object_Mover *prov;
5265 prov = E_NEW(E_Comp_Object_Mover, 1);
5266 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5267 prov->func = provider;
5268 prov->data = (void*)data;
5271 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5272 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5277 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5279 EINA_SAFETY_ON_NULL_RETURN(prov);
5280 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5285 e_comp_object_effect_object_get(Evas_Object *obj)
5289 return cw->effect_obj;
5293 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5295 API_ENTRY EINA_FALSE;
5296 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5297 if (!cw->effect_set) return EINA_FALSE;
5304 ////////////////////////////////////
5307 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5309 if (e_comp->autoclose.obj)
5311 e_comp_ungrab_input(0, 1);
5312 if (e_comp->autoclose.del_cb)
5313 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5314 else if (!already_del)
5316 evas_object_hide(e_comp->autoclose.obj);
5317 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5319 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5321 e_comp->autoclose.obj = NULL;
5322 e_comp->autoclose.data = NULL;
5323 e_comp->autoclose.del_cb = NULL;
5324 e_comp->autoclose.key_cb = NULL;
5325 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5329 _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)
5331 _e_comp_object_autoclose_cleanup(0);
5335 _e_comp_object_autoclose_setup(Evas_Object *obj)
5337 if (!e_comp->autoclose.rect)
5339 /* create rect just below autoclose object to catch mouse events */
5340 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5341 evas_object_move(e_comp->autoclose.rect, 0, 0);
5342 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5343 evas_object_show(e_comp->autoclose.rect);
5344 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5345 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5346 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5347 e_comp_grab_input(0, 1);
5349 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5350 evas_object_focus_set(obj, 1);
5354 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5356 _e_comp_object_autoclose_setup(obj);
5357 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5361 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5363 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5364 _e_comp_object_autoclose_cleanup(1);
5365 if (e_client_focused_get()) return;
5367 E_Zone *zone = e_zone_current_get();
5370 e_zone_focus_reset(zone);
5374 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5378 if (e_comp->autoclose.obj)
5380 if (e_comp->autoclose.obj == obj) return;
5381 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5382 e_comp->autoclose.obj = obj;
5383 e_comp->autoclose.del_cb = del_cb;
5384 e_comp->autoclose.key_cb = cb;
5385 e_comp->autoclose.data = (void*)data;
5386 if (evas_object_visible_get(obj))
5387 _e_comp_object_autoclose_setup(obj);
5389 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5390 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5393 e_comp->autoclose.obj = obj;
5394 e_comp->autoclose.del_cb = del_cb;
5395 e_comp->autoclose.key_cb = cb;
5396 e_comp->autoclose.data = (void*)data;
5397 if (evas_object_visible_get(obj))
5398 _e_comp_object_autoclose_setup(obj);
5400 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5401 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5405 e_comp_object_is_animating(Evas_Object *obj)
5409 return cw->animating;
5413 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5417 if ((cw->external_content) &&
5418 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5420 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5421 "But current external content is %d object for %p.",
5422 cw->content_type, cw->ec);
5426 cw->user_alpha_set = EINA_TRUE;
5427 cw->user_alpha = alpha;
5429 if (!cw->obj) return;
5431 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5433 evas_object_image_alpha_set(cw->obj, alpha);
5435 if ((!cw->native) && (!cw->external_content))
5436 evas_object_image_data_set(cw->obj, NULL);
5440 e_comp_object_alpha_get(Evas_Object *obj)
5442 API_ENTRY EINA_FALSE;
5444 return evas_object_image_alpha_get(cw->obj);
5448 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5450 Eina_Bool mask_set = EINA_FALSE;
5454 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5455 if (cw->ec->input_only) return;
5462 o = evas_object_rectangle_add(e_comp->evas);
5463 evas_object_color_set(o, 0, 0, 0, 0);
5464 evas_object_clip_set(o, cw->clip);
5465 evas_object_smart_member_add(o, obj);
5466 evas_object_move(o, 0, 0);
5467 evas_object_resize(o, cw->w, cw->h);
5468 /* save render op value to restore when clear a mask.
5470 * NOTE: DO NOT change the render op on ec->frame while mask object
5471 * is set. it will overwrite the changed op value. */
5472 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5473 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5474 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5475 if (cw->visible) evas_object_show(o);
5478 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5479 ELOGF("COMP", " |mask_obj", cw->ec);
5480 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5487 evas_object_smart_member_del(cw->mask.obj);
5488 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5490 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5491 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5497 e_comp_object_mask_has(Evas_Object *obj)
5499 API_ENTRY EINA_FALSE;
5501 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5505 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5510 if ((cw->external_content) &&
5511 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5513 WRN("Can set up size to ONLY evas \"image\" object. "
5514 "But current external content is %d object for %p.",
5515 cw->content_type, cw->ec);
5519 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5521 evas_object_image_size_set(cw->obj, tw, th);
5525 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5527 Eina_Bool transform_set = EINA_FALSE;
5529 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5530 if (cw->ec->input_only) return;
5532 transform_set = !!set;
5536 if (!cw->transform_bg_obj)
5538 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5539 evas_object_move(o, 0, 0);
5540 evas_object_resize(o, 1, 1);
5541 if (cw->transform_bg_color.a >= 255)
5542 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5544 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5545 evas_object_color_set(o,
5546 cw->transform_bg_color.r,
5547 cw->transform_bg_color.g,
5548 cw->transform_bg_color.b,
5549 cw->transform_bg_color.a);
5550 if (cw->visible) evas_object_show(o);
5552 cw->transform_bg_obj = o;
5553 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5555 #ifdef REFACTOR_DESK_AREA
5556 e_comp_object_transform_obj_stack_update(obj);
5558 _e_comp_object_transform_obj_stack_update(obj);
5563 if (cw->transform_bg_obj)
5565 evas_object_smart_member_del(cw->transform_bg_obj);
5566 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5572 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5576 cw->transform_bg_color.r = r;
5577 cw->transform_bg_color.g = g;
5578 cw->transform_bg_color.b = b;
5579 cw->transform_bg_color.a = a;
5581 if (cw->transform_bg_obj)
5583 evas_object_color_set(cw->transform_bg_obj,
5584 cw->transform_bg_color.r,
5585 cw->transform_bg_color.g,
5586 cw->transform_bg_color.b,
5587 cw->transform_bg_color.a);
5592 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5595 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5596 if (cw->ec->input_only) return;
5597 if (!cw->transform_bg_obj) return;
5599 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5603 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5606 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5607 if (cw->ec->input_only) return;
5608 if (!cw->transform_bg_obj) return;
5610 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5614 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5616 Eina_Bool transform_set = EINA_FALSE;
5618 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5619 if (cw->ec->input_only) return;
5621 transform_set = !!set;
5625 if (!cw->transform_tranp_obj)
5627 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5628 evas_object_move(o, 0, 0);
5629 evas_object_resize(o, 1, 1);
5630 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5631 evas_object_color_set(o, 0, 0, 0, 0);
5632 if (cw->visible) evas_object_show(o);
5634 cw->transform_tranp_obj = o;
5635 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5636 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5637 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5639 #ifdef REFACTOR_DESK_AREA
5640 e_comp_object_transform_obj_stack_update(obj);
5642 _e_comp_object_transform_obj_stack_update(obj);
5647 if (cw->transform_tranp_obj)
5649 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5650 evas_object_smart_member_del(cw->transform_tranp_obj);
5651 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5657 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5660 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5661 if (cw->ec->input_only) return;
5662 if (!cw->transform_tranp_obj) return;
5664 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5668 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5671 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5672 if (cw->ec->input_only) return;
5673 if (!cw->transform_tranp_obj) return;
5675 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5678 #ifdef REFACTOR_DESK_AREA
5681 e_comp_object_layer_update(Evas_Object *obj,
5682 Evas_Object *above, Evas_Object *below)
5684 E_Comp_Object *cw2 = NULL;
5685 Evas_Object *o = NULL;
5690 if (cw->ec->layer_block) return;
5691 if ((above) && (below))
5693 ERR("Invalid layer update request! cw=%p", cw);
5701 layer = evas_object_layer_get(o);
5702 cw2 = evas_object_data_get(o, "comp_obj");
5705 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5707 o = evas_object_above_get(o);
5708 if ((!o) || (o == cw->smart_obj)) break;
5709 if (evas_object_layer_get(o) != layer)
5711 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5716 ec = e_client_top_get();
5717 if (ec) o = ec->frame;
5720 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5724 _e_comp_object_layers_remove(cw);
5727 if (cw2->layer > cw->layer)
5728 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5729 else if (cw2->layer == cw->layer)
5732 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5734 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5736 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5739 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5742 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5747 e_comp_object_layer_get(Evas_Object *obj)
5754 e_comp_object_content_set(Evas_Object *obj,
5755 Evas_Object *content,
5756 E_Comp_Object_Content_Type type)
5758 API_ENTRY EINA_FALSE;
5760 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5761 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5762 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5766 ERR("Can't set e.swallow.content to requested content. "
5767 "Previous comp object should not be changed at all.");
5771 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5773 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5774 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5776 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5777 type, content, cw->ec, cw->ec->pixmap);
5781 cw->external_content = EINA_TRUE;
5784 cw->content_type = type;
5785 e_util_size_debug_set(cw->obj, 1);
5786 evas_object_name_set(cw->obj, "cw->obj");
5787 _e_comp_object_alpha_set(cw);
5790 _e_comp_object_shadow_setup(cw);
5796 e_comp_object_content_unset(Evas_Object *obj)
5798 API_ENTRY EINA_FALSE;
5800 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5801 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5803 if (!cw->obj && !cw->ec->visible)
5805 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5809 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5811 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5817 if (cw->frame_object)
5818 edje_object_part_unswallow(cw->frame_object, cw->obj);
5820 edje_object_part_unswallow(cw->shobj, cw->obj);
5822 evas_object_del(cw->obj);
5823 evas_object_hide(cw->obj);
5827 cw->external_content = EINA_FALSE;
5828 if (cw->ec->is_cursor)
5831 DBG("%p is cursor surface..", cw->ec);
5832 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5834 evas_object_resize(cw->ec->frame, pw, ph);
5835 evas_object_hide(cw->ec->frame);
5840 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5841 cw->obj = evas_object_image_filled_add(e_comp->evas);
5842 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5843 e_util_size_debug_set(cw->obj, 1);
5844 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5845 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5846 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5847 evas_object_name_set(cw->obj, "cw->obj");
5848 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5849 _e_comp_object_alpha_set(cw);
5852 _e_comp_object_shadow_setup(cw);
5857 _e_comp_intercept_show_helper(cw);
5861 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5862 e_comp_object_dirty(cw->smart_obj);
5863 e_comp_object_render(cw->smart_obj);
5864 e_comp_object_render_update_add(obj);
5869 EINTERN Evas_Object *
5870 e_comp_object_content_get(Evas_Object *obj)
5874 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5876 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5878 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5885 E_API E_Comp_Object_Content_Type
5886 e_comp_object_content_type_get(Evas_Object *obj)
5888 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5890 return cw->content_type;
5894 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5897 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5898 E_Comp_Config *conf = e_comp_config_get();
5899 if (cw->ec->input_only) return;
5900 if (!conf->dim_rect_enable) return;
5902 cw->dim.mask_set = mask_set;
5908 if (!cw->dim.enable) return;
5909 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5913 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5915 Eina_Bool mask_set = EINA_FALSE;
5919 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5920 E_Comp_Config *conf = e_comp_config_get();
5921 if (cw->ec->input_only) return;
5922 if (!conf->dim_rect_enable) return;
5928 if (cw->dim.mask_obj)
5930 evas_object_smart_member_del(cw->dim.mask_obj);
5931 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5934 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);
5935 o = evas_object_rectangle_add(e_comp->evas);
5936 evas_object_color_set(o, 0, 0, 0, 0);
5937 evas_object_smart_member_add(o, obj);
5938 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5939 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5941 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5942 if (cw->visible) evas_object_show(o);
5944 cw->dim.mask_obj = o;
5945 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5947 evas_object_layer_set(cw->dim.mask_obj, 9998);
5951 if (cw->dim.mask_obj)
5953 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5954 evas_object_smart_member_del(cw->dim.mask_obj);
5955 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5961 e_comp_object_dim_client_set(E_Client *ec)
5963 E_Comp_Config *conf = e_comp_config_get();
5965 if (!conf->dim_rect_enable) return ;
5966 if (dim_client == ec) return;
5968 Eina_Bool prev_dim = EINA_FALSE;
5969 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5971 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5972 prev_dim = EINA_TRUE;
5974 if (prev_dim && dim_client->visible && ec)
5976 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5977 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5981 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5982 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5988 e_comp_object_dim_client_get(void)
5990 E_Comp_Config *conf = e_comp_config_get();
5992 if (!conf->dim_rect_enable ) return NULL;
5998 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6001 char emit[32] = "\0";
6002 E_Comp_Config *conf = e_comp_config_get();
6005 if (!conf->dim_rect_enable) return;
6006 if (!cw->effect_obj) return;
6007 if (enable == cw->dim.enable) return;
6009 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6010 if (noeffect || !conf->dim_rect_effect)
6012 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6016 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6019 cw->dim.enable = enable;
6021 if (cw->dim.mask_set && !enable)
6023 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6024 edje_object_signal_emit(cw->effect_obj, emit, "e");
6026 else if (cw->dim.mask_set && enable)
6028 edje_object_signal_emit(cw->effect_obj, emit, "e");
6029 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6033 edje_object_signal_emit(cw->effect_obj, emit, "e");
6038 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6040 API_ENTRY EINA_FALSE;
6041 E_Comp_Config *conf = e_comp_config_get();
6043 if (!ec) return EINA_FALSE;
6044 if (!conf->dim_rect_enable) return EINA_FALSE;
6046 if (cw->dim.enable) return EINA_TRUE;
6052 _e_comp_object_dim_update(E_Comp_Object *cw)
6054 E_Comp_Config *conf = e_comp_config_get();
6057 if (!conf->dim_rect_enable) return;
6058 if (!cw->effect_obj) return;
6061 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6062 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6064 if (cw->dim.mask_set)
6066 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6072 e_comp_object_clear(Evas_Object *obj)
6076 _e_comp_object_clear(cw);
6080 e_comp_object_hwc_update_exists(Evas_Object *obj)
6082 API_ENTRY EINA_FALSE;
6083 return cw->hwc_need_update;
6088 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6091 cw->hwc_need_update = set;
6095 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6097 API_ENTRY EINA_FALSE;
6098 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6102 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6105 if (cw->indicator.obj != indicator)
6106 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6107 cw->indicator.obj = indicator;
6108 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6112 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6115 if (cw->indicator.obj != indicator) return;
6116 cw->indicator.obj = NULL;
6117 edje_object_part_unswallow(cw->shobj, indicator);
6121 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6124 Edje_Message_Int_Set *msg;
6126 if (!cw->indicator.obj) return;
6128 cw->indicator.w = w;
6129 cw->indicator.h = h;
6131 if (!cw->shobj) return;
6133 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6137 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6138 edje_object_message_signal_process(cw->shobj);
6141 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6143 e_comp_object_map_update(Evas_Object *obj)
6146 E_Client *ec = cw->ec;
6147 E_Comp_Wl_Client_Data *cdata;
6149 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6152 int l, remain = sizeof buffer;
6155 if (e_object_is_del(E_OBJECT(ec))) return;
6156 cdata = e_client_cdata_get(ec);
6159 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6160 * when new buffer is attached.
6162 if (!cdata->buffer_ref.buffer) return;
6164 if ((!cw->redirected) ||
6165 (e_client_video_hw_composition_check(ec)) ||
6166 (!e_comp_wl_output_buffer_transform_get(ec) &&
6167 cdata->scaler.buffer_viewport.buffer.scale == 1))
6169 if (evas_object_map_enable_get(cw->effect_obj))
6171 ELOGF("TRANSFORM", "map: disable", cw->ec);
6172 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6173 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6174 evas_object_resize(cw->effect_obj, tw, th);
6181 EINA_SAFETY_ON_NULL_RETURN(map);
6183 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6189 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6191 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6192 e_map_point_image_uv_set(map, 0, x, y);
6193 l = snprintf(p, remain, "%d,%d", x, y);
6194 p += l, remain -= l;
6196 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6197 e_map_point_image_uv_set(map, 1, x, y);
6198 l = snprintf(p, remain, " %d,%d", x, y);
6199 p += l, remain -= l;
6201 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6202 e_map_point_image_uv_set(map, 2, x, y);
6203 l = snprintf(p, remain, " %d,%d", x, y);
6204 p += l, remain -= l;
6206 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6207 e_map_point_image_uv_set(map, 3, x, y);
6208 l = snprintf(p, remain, " %d,%d", x, y);
6209 p += l, remain -= l;
6211 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6213 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6215 e_comp_object_map_set(cw->effect_obj, map);
6216 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6220 /* if there's screen rotation with comp mode, then ec->effect_obj and
6221 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6223 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6224 evas_object_resize(cw->effect_obj, tw, th);
6228 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6230 API_ENTRY EINA_FALSE;
6232 cw->render_trace = set;
6238 e_comp_object_native_usable_get(Evas_Object *obj)
6240 API_ENTRY EINA_FALSE;
6241 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6243 if (cw->ec->input_only) return EINA_FALSE;
6244 if (cw->external_content) return EINA_FALSE;
6245 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6247 /* just return true value, if it is normal case */
6248 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6251 Evas_Native_Surface *ns;
6252 ns = evas_object_image_native_surface_get(cw->obj);
6254 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6257 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6265 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6267 API_ENTRY EINA_FALSE;
6268 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6269 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6270 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6274 case E_COMP_IMAGE_FILTER_BLUR:
6275 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6277 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6278 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6280 case E_COMP_IMAGE_FILTER_INVERSE:
6281 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6283 case E_COMP_IMAGE_FILTER_NONE:
6285 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6289 cw->image_filter = filter;
6294 EINTERN E_Comp_Image_Filter
6295 e_comp_object_image_filter_get(Evas_Object *obj)
6297 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6298 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6299 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6300 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6302 return cw->image_filter;
6306 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6310 if (!_damage_trace) return;
6312 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6313 evas_object_del(obj);
6315 _damage_trace_post_objs = NULL;
6319 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6321 if (!_damage_trace) return;
6323 _damage_trace_post_objs = _damage_trace_objs;
6324 _damage_trace_objs = NULL;
6328 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6330 if (_damage_trace == onoff) return;
6334 evas_event_callback_add(e_comp->evas,
6335 EVAS_CALLBACK_RENDER_PRE,
6336 _e_comp_object_damage_trace_render_pre_cb,
6339 evas_event_callback_add(e_comp->evas,
6340 EVAS_CALLBACK_RENDER_POST,
6341 _e_comp_object_damage_trace_render_post_cb,
6348 EINA_LIST_FREE(_damage_trace_objs, obj)
6349 evas_object_del(obj);
6351 _damage_trace_objs = NULL;
6353 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6354 evas_object_del(obj);
6356 _damage_trace_post_objs = NULL;
6358 evas_event_callback_del(e_comp->evas,
6359 EVAS_CALLBACK_RENDER_PRE,
6360 _e_comp_object_damage_trace_render_pre_cb);
6362 evas_event_callback_del(e_comp->evas,
6363 EVAS_CALLBACK_RENDER_POST,
6364 _e_comp_object_damage_trace_render_post_cb);
6367 _damage_trace = onoff;
6371 e_comp_object_redirected_get(Evas_Object *obj)
6373 API_ENTRY EINA_FALSE;
6374 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6376 return cw->redirected;
6380 e_comp_object_color_visible_get(Evas_Object *obj)
6382 API_ENTRY EINA_FALSE;
6385 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6387 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6391 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6395 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6399 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6407 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6409 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6411 return e_map_set_to_comp_object(em, obj);
6415 e_comp_object_map_get(const Evas_Object *obj)
6417 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6419 return e_map_get_from_comp_object(obj);
6423 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6425 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6427 evas_object_map_enable_set(obj, enable);
6433 e_comp_object_render_update_lock(Evas_Object *obj)
6435 E_Comp_Wl_Buffer *buffer;
6436 struct wayland_tbm_client_queue *cqueue;
6438 API_ENTRY EINA_FALSE;
6440 if (cw->render_update_lock.lock == 0)
6442 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6444 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6445 if ((buffer) && (buffer->resource))
6447 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6449 wayland_tbm_server_client_queue_flush(cqueue);
6452 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6453 e_comp_object_render_update_del(obj);
6455 ELOGF("COMP", "Render update lock enabled", cw->ec);
6458 cw->render_update_lock.lock++;
6464 e_comp_object_render_update_unlock(Evas_Object *obj)
6468 if (cw->render_update_lock.lock == 0)
6471 cw->render_update_lock.lock--;
6473 if (cw->render_update_lock.lock == 0)
6476 if (cw->render_update_lock.pending_move_set)
6478 evas_object_move(obj,
6479 cw->render_update_lock.pending_move_x,
6480 cw->render_update_lock.pending_move_y);
6481 cw->render_update_lock.pending_move_x = 0;
6482 cw->render_update_lock.pending_move_y = 0;
6483 cw->render_update_lock.pending_move_set = EINA_FALSE;
6486 if (cw->render_update_lock.pending_resize_set)
6488 evas_object_resize(obj,
6489 cw->render_update_lock.pending_resize_w,
6490 cw->render_update_lock.pending_resize_h);
6491 cw->render_update_lock.pending_resize_w = 0;
6492 cw->render_update_lock.pending_resize_h = 0;
6493 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6496 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6498 if ((cw->ec->exp_iconify.buffer_flush) &&
6499 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6500 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6501 e_comp_object_clear(obj);
6503 e_comp_object_render_update_add(obj);
6505 ELOGF("COMP", "Render update lock disabled", cw->ec);
6510 e_comp_object_render_update_lock_get(Evas_Object *obj)
6512 API_ENTRY EINA_FALSE;
6514 if (cw->render_update_lock.lock > 0)
6521 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6525 if (cw->transparent.set)
6527 if (r) *r = cw->transparent.user_r;
6528 if (g) *g = cw->transparent.user_g;
6529 if (b) *b = cw->transparent.user_b;
6530 if (a) *a = cw->transparent.user_a;
6534 evas_object_color_get(obj, r, g, b, a);
6539 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6543 evas_object_render_op_set(cw->obj, op);
6546 EINTERN Evas_Render_Op
6547 e_comp_object_render_op_get(Evas_Object *obj)
6549 API_ENTRY EVAS_RENDER_BLEND;
6551 return evas_object_render_op_get(cw->obj);
6555 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6558 wl_signal_add(&cw->events.lower, listener);
6561 #ifdef REFACTOR_DESK_AREA
6563 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6566 wl_signal_add(&cw->events.lower_done, listener);
6570 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6573 wl_signal_add(&cw->events.raise, listener);
6578 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6581 wl_signal_add(&cw->events.show, listener);
6585 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6588 wl_signal_add(&cw->events.hide, listener);
6591 #ifdef REFACTOR_DESK_AREA
6593 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6596 wl_signal_add(&cw->events.set_layer, listener);
6600 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6603 wl_signal_add(&cw->events.stack_above, listener);
6607 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6610 wl_signal_add(&cw->events.stack_below, listener);