1 #include "e_comp_object_intern.h"
2 #include "e_bindings_intern.h"
3 #include "e_utils_intern.h"
4 #ifdef REFACTOR_DESK_AREA
6 #include "e_comp_canvas_intern.h"
8 #include "e_comp_cfdata_intern.h"
9 #include "e_comp_wl_subsurface_intern.h"
10 #include "e_comp_wl_tbm_intern.h"
11 #include "e_comp_intern.h"
12 #include "e_pixmap_intern.h"
13 #include "e_map_intern.h"
14 #include "e_hwc_window_intern.h"
15 #include "e_hwc_windows_intern.h"
16 #include "e_policy_visibility_intern.h"
17 #include "e_client_video_intern.h"
18 #include "e_client_intern.h"
19 #include "e_zone_intern.h"
20 #include "e_theme_intern.h"
21 #include "e_config_intern.h"
25 = keys that return objects =
26 - E_Client: the client associated with the object (E_Client*)
27 - comp_smart_obj: cw->smart_obj (Evas_Object*)
28 - comp_obj: cw (E_Comp_Object*)
30 = keys that are bool flags =
31 - client_restack: client needs a protocol-level restack
32 - comp_override: object is triggering a nocomp override to force compositing
33 - comp_ref: object has a ref from visibility animations
34 - comp_showing: object is currently running its show animation
35 - comp_hiding: object is currently running its hiding animation
36 - comp_object: object is a compositor-created object
37 - comp_object_skip: object has a name which prohibits theme shadows
38 - comp_object-to_del: list of objects which will be deleted when this object is deleted
39 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
40 - effect_running: object is animating by external module
43 #define UPDATE_MAX 512 // same as evas
44 #define FAILURE_MAX 2 // seems reasonable
45 #define SMART_NAME "e_comp_object"
46 #define INPUT_OBJ_SMART_NAME "input_object"
48 /* for non-util functions */
49 #define API_ENTRY E_Comp_Object *cw; \
50 cw = evas_object_smart_data_get(obj); \
51 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
53 /* for util functions (obj may or may not be E_Comp_Object */
54 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
57 CRI("YOU PASSED NULL! ARGH!"); \
60 cw = evas_object_smart_data_get(obj); \
61 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
63 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
65 /* enable for lots of client size info in console output */
67 # define e_util_size_debug_set(x, y)
70 /* enable along with display-specific damage INF calls to enable render tracing
74 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
76 #define RENDER_DEBUG(...)
79 typedef struct _E_Input_Rect_Data
85 typedef struct _E_Input_Rect_Smart_Data
87 Eina_List *input_rect_data_list;
89 } E_Input_Rect_Smart_Data;
91 struct E_Comp_Object_Mover
94 E_Comp_Object_Mover_Cb func;
100 static Eina_Inlist *_e_comp_object_movers = NULL;
101 static Evas_Smart *_e_comp_smart = NULL;
102 static Evas_Smart *_e_comp_input_obj_smart = NULL;
104 static int _e_comp_object_hooks_delete = 0;
105 static int _e_comp_object_hooks_walking = 0;
107 static Eina_Inlist *_e_comp_object_hooks[] =
109 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
110 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
111 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
112 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
113 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
114 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
115 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
116 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
119 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
120 static int _e_comp_object_intercept_hooks_delete = 0;
121 static int _e_comp_object_intercept_hooks_walking = 0;
123 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
125 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
126 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
130 static Eina_Bool _damage_trace = EINA_FALSE;
131 static Eina_List *_damage_trace_objs = NULL;
132 static Eina_List *_damage_trace_post_objs = NULL;
134 /* sekrit functionzzz */
135 EINTERN void e_client_focused_set(E_Client *ec);
137 /* emitted every time a new noteworthy comp object is added */
138 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
140 /* ecore event define */
141 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
142 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
143 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
145 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
146 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
147 static void _e_comp_object_dim_update(E_Comp_Object *cw);
148 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
149 #ifdef REFACTOR_DESK_AREA
151 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
152 static void _e_comp_object_raise(Evas_Object *obj);
153 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
154 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
155 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
156 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
159 static E_Client *dim_client = NULL;
162 _e_comp_object_hooks_clean(void)
165 E_Comp_Object_Hook *ch;
168 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
169 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
171 if (!ch->delete_me) continue;
172 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
178 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
180 E_Comp_Object_Hook *ch;
181 Eina_Bool ret = EINA_TRUE;
183 if (e_object_is_del(E_OBJECT(ec)))
185 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
186 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
192 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
198 e_object_ref(E_OBJECT(ec));
199 _e_comp_object_hooks_walking++;
200 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
202 if (ch->delete_me) continue;
203 if (!(ch->func(ch->data, ec)))
209 _e_comp_object_hooks_walking--;
210 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
211 _e_comp_object_hooks_clean();
213 e_object_unref(E_OBJECT(ec));
218 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
220 _e_comp_object_intercept_hooks_clean(void)
223 E_Comp_Object_Intercept_Hook *ch;
226 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
227 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
229 if (!ch->delete_me) continue;
230 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
236 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
238 E_Comp_Object_Intercept_Hook *ch;
239 Eina_Bool ret = EINA_TRUE;
241 if (e_object_is_del(E_OBJECT(ec))) return ret;
242 e_object_ref(E_OBJECT(ec));
243 _e_comp_object_intercept_hooks_walking++;
244 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
246 if (ch->delete_me) continue;
247 if (!(ch->func(ch->data, ec)))
253 _e_comp_object_intercept_hooks_walking--;
254 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
255 _e_comp_object_intercept_hooks_clean();
257 e_object_unref(E_OBJECT(ec));
264 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
266 E_Event_Comp_Object *ev = event;
269 ec = evas_object_data_get(ev->comp_object, "E_Client");
273 e_object_unref(E_OBJECT(ec));
275 evas_object_unref(ev->comp_object);
280 _e_comp_object_event_add(Evas_Object *obj)
282 E_Event_Comp_Object *ev;
285 if (stopping) return;
286 ev = E_NEW(E_Event_Comp_Object, 1);
287 EINA_SAFETY_ON_NULL_RETURN(ev);
289 evas_object_ref(obj);
290 ev->comp_object = obj;
291 ec = evas_object_data_get(ev->comp_object, "E_Client");
295 e_object_ref(E_OBJECT(ec));
297 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
301 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
303 E_Event_Comp_Object *ev = event;
306 ec = evas_object_data_get(ev->comp_object, "E_Client");
310 e_object_unref(E_OBJECT(ec));
312 evas_object_unref(ev->comp_object);
317 _e_comp_object_event_simple(Evas_Object *obj, int type)
319 E_Event_Comp_Object *ev;
322 ev = E_NEW(E_Event_Comp_Object, 1);
325 evas_object_ref(obj);
326 ev->comp_object = obj;
327 ec = evas_object_data_get(ev->comp_object, "E_Client");
331 e_object_ref(E_OBJECT(ec));
333 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
335 /////////////////////////////////////
338 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
340 E_Comp_Object *cw = data;
342 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
346 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
348 E_Comp_Object *cw = data;
350 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
351 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
354 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
355 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
359 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
361 E_Comp_Object *cw = data;
364 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
365 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
368 /////////////////////////////////////
370 #ifdef REFACTOR_DESK_AREA
372 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
375 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
380 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
381 if (cw->ec->input_only) return;
383 layer = evas_object_layer_get(obj);
385 if (cw->transform_bg_obj)
387 if (layer != evas_object_layer_get(cw->transform_bg_obj))
389 evas_object_layer_set(cw->transform_bg_obj, layer);
392 evas_object_stack_below(cw->transform_bg_obj, obj);
395 if (cw->transform_tranp_obj)
397 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
399 evas_object_layer_set(cw->transform_tranp_obj, layer);
402 evas_object_stack_below(cw->transform_tranp_obj, obj);
407 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
414 if (!map) return NULL;
416 e_map_util_points_populate_from_object_full(map, obj, 0);
417 e_map_util_points_color_set(map, 255, 255, 255, 255);
419 for (i = 0 ; i < 4 ; ++i)
424 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
425 e_map_point_coord_set(map, i, x, y, 1.0);
432 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
438 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
441 e_comp_object_map_set(obj, map);
442 e_comp_object_map_enable_set(obj, EINA_TRUE);
449 evas_object_map_enable_set(obj, EINA_FALSE);
454 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
460 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
463 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
465 e_comp_object_map_set(obj, map);
466 e_comp_object_map_enable_set(obj, EINA_TRUE);
473 evas_object_map_enable_set(obj, EINA_FALSE);
476 /////////////////////////////////////
478 static inline Eina_Bool
479 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
481 if (num > 1) return EINA_TRUE;
482 if ((rects[0].x == 0) && (rects[0].y == 0) &&
483 ((int)rects[0].w == w) && ((int)rects[0].h == h))
488 /////////////////////////////////////
490 /* add a client to the layer-client list */
491 #ifdef REFACTOR_DESK_AREA
494 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
496 g_rec_mutex_lock(&e_comp->ec_list_mutex);
499 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));
501 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));
502 if ((!above) && (!below))
505 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
506 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
507 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
509 e_comp->layers[cw->layer].clients_count++;
511 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
515 _e_comp_object_layers_remove(E_Comp_Object *cw)
517 g_rec_mutex_lock(&e_comp->ec_list_mutex);
519 if (cw->ec && e_comp->layers[cw->layer].clients)
521 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
522 e_comp->layers[cw->layer].clients_count--;
525 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
529 /////////////////////////////////////
531 _e_comp_object_alpha_set(E_Comp_Object *cw)
533 Eina_Bool alpha = cw->ec->argb;
535 if ((cw->external_content) &&
536 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
541 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
542 if (cw->user_alpha_set) alpha = cw->user_alpha;
544 evas_object_image_alpha_set(cw->obj, alpha);
548 _e_comp_object_shadow(E_Comp_Object *cw)
550 if (e_client_util_shadow_state_get(cw->ec))
551 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
553 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
554 if (cw->frame_object)
555 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
556 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
559 /* convert from the surface coordinates to the buffer coordinates */
561 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
563 E_Comp_Wl_Buffer_Viewport *vp;
564 E_Comp_Wl_Client_Data *cdata;
568 cdata = e_client_cdata_get(ec);
570 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
577 vp = &cdata->scaler.buffer_viewport;
578 transform = e_comp_wl_output_buffer_transform_get(ec);
580 e_pixmap_size_get(ec->pixmap, &bw, &bh);
582 /* for subsurface, it should be swap 90 and 270 */
583 if (e_comp_wl_subsurface_check(ec))
586 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
587 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
588 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
589 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
595 case WL_OUTPUT_TRANSFORM_NORMAL:
596 default: tx = sx, ty = sy; break;
597 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
598 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
599 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
600 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
601 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
603 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
606 tx *= vp->buffer.scale;
607 ty *= vp->buffer.scale;
614 _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)
622 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
623 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
630 if (dw) *dw = MAX(x1, x2) - mx;
631 if (dh) *dh = MAX(y1, y2) - my;
635 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
636 int *dx, int *dy, int *dw, int *dh)
638 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
639 E_Util_Transform_Rect_Vertex sv, dv;
643 e_pixmap_size_get(ec->pixmap, &bw, &bh);
645 sv = e_util_transform_rect_to_vertices(&rect);
647 for (i = 0; i < 4; i++)
649 double x = 0.0, y = 0.0;
651 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
653 /* if evas decide coordinate is outside of map, it returns (0, 0)
654 in this case, full damage is added.
656 if ((i != 0) && (x == 0.0) && (y == 0.0))
659 dv.vertices[i].vertex[0] = x;
660 dv.vertices[i].vertex[1] = y;
661 dv.vertices[i].vertex[2] = 1.0;
662 dv.vertices[i].vertex[3] = 1.0;
665 rect = e_util_transform_vertices_to_rect(&dv);
667 if (dx) *dx = rect.x;
668 if (dy) *dy = rect.y;
669 if (dw) *dw = rect.w;
670 if (dh) *dh = rect.h;
684 _e_comp_object_map_damage_transform_get(E_Client *ec)
691 if (!e_client_transform_core_enable_get(ec))
694 m = e_client_map_get(ec);
698 e_pixmap_size_get(ec->pixmap, &bw, &bh);
699 if ((bw == 0) || (bh == 0))
712 e_map_point_coord_set(m2, 0, 0, 0, 0);
713 e_map_point_coord_set(m2, 1, bw, 0, 0);
714 e_map_point_coord_set(m2, 2, bw, bh, 0);
715 e_map_point_coord_set(m2, 3, 0, bh, 0);
717 for (i = 0; i < 4; i++)
721 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
722 e_map_point_image_uv_set(m2, i, map_x, map_y);
729 /////////////////////////////////////
731 /* handle evas mouse-in events on client object */
733 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
735 Evas_Event_Mouse_In *ev = event_info;
736 E_Comp_Object *cw = data;
738 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
741 /* handle evas mouse-out events on client object */
743 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
745 Evas_Event_Mouse_Out *ev = event_info;
746 E_Comp_Object *cw = data;
748 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
751 /* handle evas mouse wheel events on client object */
753 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
755 Evas_Event_Mouse_Wheel *ev = event_info;
756 E_Comp_Object *cw = data;
757 E_Binding_Event_Wheel ev2;
760 if (e_client_action_get()) return;
761 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
762 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
765 /* handle evas mouse down events on client object */
767 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
769 Evas_Event_Mouse_Down *ev = event_info;
770 E_Comp_Object *cw = data;
771 E_Binding_Event_Mouse_Button ev2;
774 if (e_client_action_get()) return;
775 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
776 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
779 /* handle evas mouse up events on client object */
781 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
783 Evas_Event_Mouse_Up *ev = event_info;
784 E_Comp_Object *cw = data;
785 E_Binding_Event_Mouse_Button ev2;
788 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
789 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
790 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
793 /* handle evas mouse movement events on client object */
795 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
797 Evas_Event_Mouse_Move *ev = event_info;
798 E_Comp_Object *cw = data;
801 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
802 e_client_mouse_move(cw->ec, &ev->cur.output);
804 /////////////////////////////////////
806 /* helper function for checking compositor themes based on user-defined matches */
808 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
810 if (((m->title) && (!ec->netwm.name)) ||
811 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
813 #if defined(__cplusplus) || defined(c_plusplus)
814 if (((m->clas) && (!ec->icccm.cpp_class)) ||
815 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
818 if (((m->clas) && (!ec->icccm.class)) ||
819 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
823 if (((m->role) && (!ec->icccm.window_role)) ||
824 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
830 if ((int)ec->netwm.type != m->primary_type)
833 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
836 if (m->borderless != 0)
840 if (e_client_util_borderless(ec))
842 if (!(((m->borderless == -1) && (!borderless)) ||
843 ((m->borderless == 1) && (borderless))))
850 if (((ec->icccm.transient_for != 0) ||
853 if (!(((m->dialog == -1) && (!dialog)) ||
854 ((m->dialog == 1) && (dialog))))
857 if (m->accepts_focus != 0)
859 int accepts_focus = 0;
861 if (ec->icccm.accepts_focus)
863 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
864 ((m->accepts_focus == 1) && (accepts_focus))))
873 if (!(((m->vkbd == -1) && (!vkbd)) ||
874 ((m->vkbd == 1) && (vkbd))))
879 if (!(((m->argb == -1) && (!ec->argb)) ||
880 ((m->argb == 1) && (ec->argb))))
883 if (m->fullscreen != 0)
885 int fullscreen = ec->fullscreen;
887 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
888 ((m->fullscreen == 1) && (fullscreen))))
893 if (!(m->modal == -1))
899 /* function for setting up a client's compositor frame theme (cw->shobj) */
901 _e_comp_object_shadow_setup(E_Comp_Object *cw)
905 Eina_List *list = NULL, *l;
906 E_Input_Rect_Data *input_rect_data;
907 E_Input_Rect_Smart_Data *input_rect_sd;
909 Eina_Stringshare *reshadow_group = NULL;
910 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
911 Eina_Stringshare *name, *title;
912 E_Comp_Config *conf = e_comp_config_get();
914 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
915 /* match correct client type */
916 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
917 name = cw->ec->icccm.name;
918 title = cw->ec->icccm.title;
919 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
920 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
922 /* skipping here is mostly a hack for systray because I hate it */
925 EINA_LIST_FOREACH(list, l, m)
927 if (((m->name) && (!name)) ||
928 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
930 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
933 no_shadow = m->no_shadow;
936 /* fast effects are just themes with "/fast" appended and shorter effect times */
939 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
940 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
942 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
944 /* default to non-fast style if fast not available */
947 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
948 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
950 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
952 if (ok && m->visibility_effect)
953 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
960 if (skip || (cw->ec->e.state.video))
962 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
964 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
967 if (conf->shadow_style)
971 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
972 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
974 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
978 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
979 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
981 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
988 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
990 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
994 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
996 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1001 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1006 if (cw->ec->override)
1008 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1009 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1011 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1012 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1018 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1019 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1022 _e_comp_object_shadow(cw);
1025 if (focus || cw->ec->focused || cw->ec->override)
1026 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1028 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1030 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1032 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1033 /* visibility must always be enabled for re_manage clients to prevent
1034 * pop-in animations every time the user sees a persistent client again;
1035 * applying visibility for iconic clients prevents the client from getting
1038 if (cw->visible || cw->ec->re_manage)
1039 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1041 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1043 /* breaks animation counter */
1044 if (cw->frame_object)
1046 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
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);
1049 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1055 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1059 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1062 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1064 if (input_rect_data->obj)
1066 pass_event_flag = EINA_TRUE;
1072 if (cw->indicator.obj)
1074 Evas_Object *indicator;
1075 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1076 if (indicator != cw->indicator.obj)
1078 edje_object_part_unswallow(cw->shobj, indicator);
1079 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1080 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1084 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1085 evas_object_pass_events_set(cw->obj, pass_event_flag);
1090 /////////////////////////////////////////////
1093 _e_comp_object_animating_begin(E_Comp_Object *cw)
1096 if (cw->animating == 1)
1098 e_comp->animating++;
1100 e_object_ref(E_OBJECT(cw->ec));
1105 _e_comp_object_animating_end(E_Comp_Object *cw)
1114 if (cw->ec->launching)
1116 if (!cw->ec->extra_animating)
1118 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1119 cw->ec->launching = EINA_FALSE;
1120 if (cw->ec->first_mapped)
1122 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1123 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1126 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1130 e_comp->animating--;
1131 cw->showing = cw->hiding = 0;
1133 if (e_comp->animating == 0)
1134 e_comp_visibility_calculation_set(EINA_TRUE);
1135 /* remove ref from animation start, account for possibility of deletion from unref */
1136 return !!e_object_unref(E_OBJECT(cw->ec));
1142 /* handle the end of a compositor animation */
1144 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1146 E_Comp_Object *cw = data;
1148 /* visible clients which have never been sized are a bug */
1149 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1150 CRI("ACK! ec:%p", cw->ec);
1151 if (!_e_comp_object_animating_end(cw)) return;
1152 if (cw->animating) return;
1153 /* hide only after animation finishes to guarantee a full run of the animation */
1154 if (!cw->defer_hide) return;
1155 if ((!strcmp(emission, "e,action,hide,done")) ||
1156 (!strcmp(emission, "e,action,done")) ||
1157 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1159 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1160 evas_object_hide(cw->smart_obj);
1164 /* run a visibility compositor effect if available, return false if object is dead */
1166 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1172 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1173 if (!cw->effect_running)
1174 _e_comp_object_animating_begin(cw);
1175 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1176 return _e_comp_object_animating_end(cw);
1177 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1178 return _e_comp_object_animating_end(cw);
1180 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1183 zone = e_comp_zone_find_by_ec(cw->ec);
1185 zw = zone->w, zh = zone->h;
1190 zone = e_comp_object_util_zone_get(cw->smart_obj);
1191 if (!zone) zone = e_zone_current_get();
1198 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1199 cw->w, cw->h, zw, zh, x, y}, 8);
1200 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1201 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1204 /////////////////////////////////////////////
1206 /* create necessary objects for clients that e manages */
1208 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1210 if (cw->set_mouse_callbacks) return;
1211 if (!cw->smart_obj) return;
1213 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1214 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1218 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1220 cw->set_mouse_callbacks = EINA_TRUE;
1224 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1226 if (!cw->set_mouse_callbacks) return;
1227 if (!cw->smart_obj) return;
1229 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1230 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1234 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1236 cw->set_mouse_callbacks = EINA_FALSE;
1240 _e_comp_object_setup(E_Comp_Object *cw)
1242 cw->clip = evas_object_rectangle_add(e_comp->evas);
1243 evas_object_move(cw->clip, -9999, -9999);
1244 evas_object_resize(cw->clip, 999999, 999999);
1245 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1246 cw->effect_obj = edje_object_add(e_comp->evas);
1247 evas_object_move(cw->effect_obj, cw->x, cw->y);
1248 evas_object_clip_set(cw->effect_obj, cw->clip);
1249 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1250 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1251 cw->shobj = edje_object_add(e_comp->evas);
1252 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1253 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1254 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1256 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1257 if (cw->ec->override)
1259 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1260 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1261 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1263 else if (!cw->ec->input_only)
1265 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1266 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1267 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1269 cw->real_hid = !cw->ec->input_only;
1270 if (!cw->ec->input_only)
1272 e_util_size_debug_set(cw->effect_obj, 1);
1273 _e_comp_object_mouse_event_callback_set(cw);
1276 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1277 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1278 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1279 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1280 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1281 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1283 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1286 /////////////////////////////////////////////
1288 /* for fast path evas rendering; only called during render */
1290 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1292 E_Comp_Object *cw = data;
1293 E_Client *ec = cw->ec;
1295 int bx, by, bxx, byy;
1297 if (e_object_is_del(E_OBJECT(ec))) return;
1298 if (cw->external_content) return;
1299 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1300 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1303 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1304 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1306 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1308 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1309 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1313 bx = by = bxx = byy = 0;
1314 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1317 Edje_Message_Int_Set *msg;
1318 Edje_Message_Int msg2;
1319 Eina_Bool id = (bx || by || bxx || byy);
1321 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1327 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1329 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1333 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1334 e_comp_client_post_update_add(cw->ec);
1336 else if (e_comp_object_render(ec->frame))
1338 /* apply shape mask if necessary */
1339 if ((!cw->native) && (ec->shaped))
1340 e_comp_object_shape_apply(ec->frame);
1342 /* shaped clients get precise mouse events to handle transparent pixels */
1343 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1345 /* queue another render if client is still dirty; cannot refresh here. */
1346 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1347 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1349 if (cw->render_trace)
1351 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1357 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1359 E_Comp_Object *cw = data;
1360 E_Client *ec = cw->ec;
1362 if (e_object_is_del(E_OBJECT(ec))) return;
1363 if (cw->external_content) return;
1364 if (!e_comp->hwc) return;
1366 e_comp_client_render_list_add(cw->ec);
1368 if (!ec->hwc_window) return;
1370 e_hwc_windows_rendered_window_add(ec->hwc_window);
1373 /////////////////////////////////////////////
1376 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1378 E_Comp_Object *cw = data;
1381 if (cw->render_update_lock.lock)
1383 cw->render_update_lock.pending_move_x = x;
1384 cw->render_update_lock.pending_move_y = y;
1385 cw->render_update_lock.pending_move_set = EINA_TRUE;
1389 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1390 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1391 (cw->external_content))
1393 /* delay to move until the external content is unset */
1394 cw->ec->changes.pos = 1;
1399 if (cw->ec->move_after_resize)
1401 if ((x != cw->ec->x) || (y != cw->ec->y))
1403 if (!cw->ec->is_cursor)
1404 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1405 e_client_pos_set(cw->ec, x, y);
1406 cw->ec->changes.pos = 1;
1412 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1413 (cw->ec->manage_resize.resize_obj))
1415 e_client_pos_set(cw->ec, x, y);
1416 cw->ec->client.x = x + cw->client_inset.l;
1417 cw->ec->client.y = y + cw->client_inset.t;
1418 e_policy_visibility_client_defer_move(cw->ec);
1422 /* if frame_object does not exist, client_inset indicates CSD.
1423 * this means that ec->client matches cw->x/y, the opposite
1426 fx = (!cw->frame_object) * cw->client_inset.l;
1427 fy = (!cw->frame_object) * cw->client_inset.t;
1428 if ((cw->x == x + fx) && (cw->y == y + fy))
1430 if ((cw->ec->x != x) || (cw->ec->y != y))
1432 /* handle case where client tries to move to position and back very quickly */
1433 e_client_pos_set(cw->ec, x, y);
1434 cw->ec->client.x = x + cw->client_inset.l;
1435 cw->ec->client.y = y + cw->client_inset.t;
1439 if (!cw->ec->maximize_override)
1441 /* prevent moving in some directions while directionally maximized */
1442 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1444 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1447 ix = x + cw->client_inset.l;
1448 iy = y + cw->client_inset.t;
1449 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1450 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1451 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1453 /* prevent moving at all if move isn't allowed in current maximize state */
1454 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1455 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1458 zone = e_comp_zone_find_by_ec(cw->ec);
1461 cw->ec->changes.need_unmaximize = 1;
1462 cw->ec->saved.x = ix - zone->x;
1463 cw->ec->saved.y = iy - zone->y;
1464 cw->ec->saved.w = cw->ec->client.w;
1465 cw->ec->saved.h = cw->ec->client.h;
1469 /* only update during resize if triggered by resize */
1470 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1471 /* delay to move while surface waits paired commit serial*/
1472 if (e_client_pending_geometry_has(cw->ec))
1474 /* do nothing while waiting paired commit serial*/
1478 e_client_pos_set(cw->ec, x, y);
1479 if (cw->ec->new_client)
1481 /* don't actually do anything until first client idler loop */
1482 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1483 cw->ec->changes.pos = 1;
1488 /* only update xy position of client to avoid invalid
1489 * first damage region if it is not a new_client. */
1490 cw->ec->client.x = ix;
1491 cw->ec->client.y = iy;
1494 if (!cw->frame_object)
1496 evas_object_move(obj, x, y);
1501 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1503 E_Comp_Object *cw = data;
1504 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1507 if (cw->render_update_lock.lock)
1509 cw->render_update_lock.pending_resize_w = w;
1510 cw->render_update_lock.pending_resize_h = h;
1511 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1515 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1517 e_client_size_set(cw->ec, w, h);
1518 evas_object_resize(obj, w, h);
1522 /* if frame_object does not exist, client_inset indicates CSD.
1523 * this means that ec->client matches cw->w/h, the opposite
1526 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1527 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1528 if ((cw->w == w + fw) && (cw->h == h + fh))
1530 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1531 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1532 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1534 /* handle case where client tries to resize itself and back very quickly */
1535 e_client_size_set(cw->ec, w, h);
1536 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1537 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1538 evas_object_smart_callback_call(obj, "client_resize", NULL);
1542 /* guarantee that fullscreen is fullscreen */
1543 zone = e_comp_zone_find_by_ec(cw->ec);
1545 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1547 if (!e_client_transform_core_enable_get(cw->ec))
1550 /* calculate client size */
1551 iw = w - cw->client_inset.l - cw->client_inset.r;
1552 ih = h - cw->client_inset.t - cw->client_inset.b;
1553 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1555 /* prevent resizing while maximized depending on direction and config */
1556 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1558 Eina_Bool reject = EINA_FALSE;
1559 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1561 if (cw->ec->client.h != ih)
1563 cw->ec->saved.h = ih;
1564 cw->ec->saved.y = cw->ec->client.y - zone->y;
1565 reject = cw->ec->changes.need_unmaximize = 1;
1568 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1570 if (cw->ec->client.w != iw)
1572 cw->ec->saved.w = iw;
1573 cw->ec->saved.x = cw->ec->client.x - zone->x;
1574 reject = cw->ec->changes.need_unmaximize = 1;
1583 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1585 /* do nothing until client idler loops */
1586 if ((cw->ec->w != w) || (cw->ec->h != h))
1588 e_client_size_set(cw->ec, w, h);
1589 cw->ec->changes.size = 1;
1594 if (e_client_pending_geometry_has(cw->ec))
1596 /* do nothing while waiting paired commit serial*/
1600 e_client_size_set(cw->ec, w, h);
1602 cw->ec->client.w = iw;
1603 cw->ec->client.h = ih;
1604 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1606 /* The size of non-compositing window can be changed, so there is a
1607 * need to check that cw is H/W composited if cw is not redirected.
1608 * And of course we have to change size of evas object of H/W composited cw,
1609 * otherwise cw can't receive input events even if it is shown on the screen.
1611 Eina_Bool redirected = cw->redirected;
1613 redirected = e_comp_is_on_overlay(cw->ec);
1615 if ((!cw->ec->input_only) && (redirected) &&
1616 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1617 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1618 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1619 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1622 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1623 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1625 prev_w = cw->w, prev_h = cw->h;
1626 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1627 /* check shading and clamp to pixmap size for regular clients */
1628 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1629 (((w - fw != pw) || (h - fh != ph))))
1631 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1632 evas_object_smart_callback_call(obj, "client_resize", NULL);
1634 if (cw->frame_object || cw->ec->input_only)
1635 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1638 if ((cw->w == w) && (cw->h == h))
1640 /* going to be a noop resize which won't trigger smart resize */
1641 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1642 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1644 evas_object_resize(obj, w, h);
1648 evas_object_smart_callback_call(obj, "client_resize", NULL);
1651 if ((!cw->frame_object) && (!cw->ec->input_only))
1653 /* "just do it" for overrides */
1654 evas_object_resize(obj, w, h);
1656 if (!cw->ec->override)
1658 /* shape probably changed for non-overrides */
1663 /* this fixes positioning jiggles when using a resize mode
1664 * which also changes the client's position
1667 if (cw->frame_object)
1668 x = cw->x, y = cw->y;
1670 x = cw->ec->x, y = cw->ec->y;
1671 switch (cw->ec->resize_mode)
1673 case E_POINTER_RESIZE_BL:
1674 case E_POINTER_RESIZE_L:
1675 evas_object_move(obj, x + prev_w - cw->w, y);
1677 case E_POINTER_RESIZE_TL:
1678 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1680 case E_POINTER_RESIZE_T:
1681 case E_POINTER_RESIZE_TR:
1682 evas_object_move(obj, x, y + prev_h - cw->h);
1691 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1693 #ifdef REFACTOR_DESK_AREA
1694 E_Comp_Object *cw = data;
1695 E_Comp_Object_Data_Set_Layer layer_set_data;
1697 layer_set_data.cw = cw;
1698 layer_set_data.layer = layer;
1700 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1704 e_comp_render_queue();
1705 e_comp_object_transform_obj_stack_update(obj);
1709 E_Comp_Object *cw = data;
1710 E_Comp_Wl_Client_Data *child_cdata;
1711 unsigned int l = e_comp_canvas_layer_map(layer);
1714 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1716 /* doing a compositor effect, follow directions */
1717 _e_comp_object_layer_set(obj, layer);
1718 if (layer == cw->ec->layer) //trying to put layer back
1722 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1723 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1724 if (cw->layer != l) goto layer_set;
1728 e_comp_render_queue();
1730 ec = e_client_above_get(cw->ec);
1731 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1732 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1733 ec = e_client_above_get(ec);
1734 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1736 ec = e_client_below_get(cw->ec);
1737 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1738 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1739 ec = e_client_below_get(ec);
1740 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1742 evas_object_stack_above(obj, ec->frame);
1747 if (ec && (cw->ec->parent == ec))
1749 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1750 evas_object_stack_above(obj, ec->frame);
1752 evas_object_stack_below(obj, ec->frame);
1755 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1761 if (cw->layer == l) return;
1762 if (e_comp_canvas_client_layer_map(layer) == 9999)
1763 return; //invalid layer for clients not doing comp effects
1764 if (cw->ec->fullscreen)
1766 cw->ec->saved.layer = layer;
1769 oldraise = e_config->transient.raise;
1771 /* clamp to valid client layer */
1772 layer = e_comp_canvas_client_layer_map_nearest(layer);
1773 cw->ec->layer = layer;
1774 if (e_config->transient.layer)
1777 Eina_List *list = eina_list_clone(cw->ec->transients);
1779 /* We need to set raise to one, else the child wont
1780 * follow to the new layer. It should be like this,
1781 * even if the user usually doesn't want to raise
1784 e_config->transient.raise = 1;
1785 EINA_LIST_FREE(list, child)
1787 child_cdata = e_client_cdata_get(child);
1788 if (child_cdata && !child_cdata->mapped)
1790 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1793 e_client_layer_set(child, layer);
1797 e_config->transient.raise = oldraise;
1799 _e_comp_object_layers_remove(cw);
1800 cw->layer = e_comp_canvas_layer_map(layer);
1801 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1802 //if (cw->ec->new_client)
1803 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1804 _e_comp_object_layer_set(obj, layer);
1805 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1806 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1807 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1809 /* can't stack a client above its own layer marker */
1810 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1812 if (!cw->visible) return;
1813 e_comp_render_queue();
1814 _e_comp_object_transform_obj_stack_update(obj);
1818 #ifdef REFACTOR_DESK_AREA
1820 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1823 #ifdef REFACTOR_DESK_AREA
1825 e_comp_object_raise(Evas_Object *obj)
1828 _e_comp_object_raise(Evas_Object *obj)
1831 evas_object_raise(obj);
1833 if (evas_object_smart_smart_get(obj))
1835 E_Client *ec = e_comp_object_client_get(obj);
1837 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1841 #ifdef REFACTOR_DESK_AREA
1843 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1846 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1849 evas_object_lower(obj);
1851 if (evas_object_smart_smart_get(obj))
1853 E_Client *ec = e_comp_object_client_get(obj);
1856 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1857 #ifdef REFACTOR_DESK_AREA
1858 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1860 wl_signal_emit_mutable(&cw->events.lower, NULL);
1866 #ifdef REFACTOR_DESK_AREA
1868 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1871 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1874 evas_object_stack_above(obj, target);
1876 if (evas_object_smart_smart_get(obj))
1878 E_Client *ec = e_comp_object_client_get(obj);
1880 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1884 #ifdef REFACTOR_DESK_AREA
1886 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1889 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1892 evas_object_stack_below(obj, target);
1894 if (evas_object_smart_smart_get(obj))
1896 E_Client *ec = e_comp_object_client_get(obj);
1898 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1902 #ifdef REFACTOR_DESK_AREA
1904 e_comp_object_layer_set(Evas_Object *obj, short layer)
1907 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1910 evas_object_layer_set(obj, layer);
1912 if (evas_object_smart_smart_get(obj))
1914 E_Client *ec = e_comp_object_client_get(obj);
1916 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1920 #ifdef REFACTOR_DESK_AREA
1923 _e_comp_object_is_pending(E_Client *ec)
1927 if (!ec) return EINA_FALSE;
1929 topmost = e_comp_wl_topmost_parent_get(ec);
1931 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1935 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1937 E_Comp_Object *cw2 = NULL;
1940 Evas_Object *o = stack;
1941 #ifdef REFACTOR_DESK_AREA
1942 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
1944 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1947 /* We should consider topmost's layer_pending for subsurface */
1948 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1950 if (_e_comp_object_is_pending(cw->ec))
1951 e_comp_object_layer_update(cw->smart_obj,
1952 raising? stack : NULL,
1953 raising? NULL : stack);
1955 /* obey compositor effects! */
1956 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1957 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
1958 stack_cb(cw->smart_obj, stack);
1959 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1960 evas_object_data_del(cw->smart_obj, "client_restack");
1964 cw2 = evas_object_data_get(o, "comp_obj");
1966 /* assume someone knew what they were doing during client init */
1967 if (cw->ec->new_client)
1968 layer = cw->ec->layer;
1969 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
1970 layer = cw2->ec->layer;
1972 layer = evas_object_layer_get(stack);
1973 ecstack = e_client_below_get(cw->ec);
1974 if (layer != e_comp_canvas_layer_map_to(cw->layer))
1976 evas_object_layer_set(cw->smart_obj, layer);
1977 /* we got our layer wrangled, return now! */
1978 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
1981 /* check if we're stacking below another client */
1984 /* check for non-client layer object */
1985 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
1987 /* find an existing client to use for layering
1988 * by walking up the object stack
1990 * this is guaranteed to be pretty quick since we'll either:
1991 * - run out of client layers
1992 * - find a stacking client
1994 o = evas_object_above_get(o);
1995 if ((!o) || (o == cw->smart_obj)) break;
1996 if (evas_object_layer_get(o) != layer)
1998 /* reached the top client layer somehow
1999 * use top client object
2001 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2004 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2005 * return here since the top client layer window
2010 ec = e_client_top_get();
2015 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2018 if (cw2 && cw->layer != cw2->layer)
2021 /* remove existing layers */
2022 _e_comp_object_layers_remove(cw);
2025 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2026 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2027 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2028 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2029 else //if no stacking objects found, either raise or lower
2030 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2033 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2035 /* find new object for stacking if cw2 is on state of layer_pending */
2036 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2038 E_Client *new_stack = NULL, *current_ec = NULL;
2039 current_ec = cw2->ec;
2042 while ((new_stack = e_client_below_get(current_ec)))
2044 current_ec = new_stack;
2045 if (new_stack == cw->ec) continue;
2046 if (new_stack->layer != cw2->ec->layer) break;
2047 if (!_e_comp_object_is_pending(new_stack)) break;
2049 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2050 stack = new_stack->frame;
2053 /* stack it above layer object */
2055 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2056 stack = e_comp->layers[below_layer].obj;
2061 while ((new_stack = e_client_above_get(current_ec)))
2063 current_ec = new_stack;
2064 if (new_stack == cw->ec) continue;
2065 if (new_stack->layer != cw2->ec->layer) break;
2066 if (!_e_comp_object_is_pending(new_stack)) break;
2068 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2069 stack = new_stack->frame;
2071 stack = e_comp->layers[cw2->layer].obj;
2075 /* set restack if stacking has changed */
2076 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2077 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2078 stack_cb(cw->smart_obj, stack);
2079 if (e_comp->layers[cw->layer].obj)
2080 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2082 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2084 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2085 evas_object_data_del(cw->smart_obj, "client_restack");
2086 if (!cw->visible) return;
2087 e_comp_render_queue();
2092 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2094 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2096 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2098 #ifdef REFACTOR_DESK_AREA
2099 E_Comp_Object *cw = data;
2100 E_Comp_Object_Data_Stack_Above stack_above_data;
2102 stack_above_data.cw = cw;
2103 stack_above_data.above_obj = above;
2105 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2107 if (evas_object_below_get(obj) == above)
2109 e_comp_object_layer_update(obj, above, NULL);
2113 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2115 _e_comp_object_transform_obj_stack_update(obj);
2116 _e_comp_object_transform_obj_stack_update(above);
2123 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2125 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2127 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2129 #ifdef REFACTOR_DESK_AREA
2130 E_Comp_Object *cw = data;
2131 E_Comp_Object_Data_Stack_Below stack_below_data;
2133 stack_below_data.cw = cw;
2134 stack_below_data.below_obj = below;
2136 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2139 e_comp_render_queue();
2141 if (evas_object_above_get(obj) == below)
2143 e_comp_object_layer_update(obj, NULL, below);
2147 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2149 if (evas_object_smart_smart_get(obj))
2150 _e_comp_object_transform_obj_stack_update(obj);
2151 if (evas_object_smart_smart_get(below))
2152 _e_comp_object_transform_obj_stack_update(below);
2159 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2161 E_Comp_Object *cw = data;
2163 #ifdef REFACTOR_DESK_AREA
2168 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2170 #ifdef REFACTOR_DESK_AREA
2171 wl_signal_emit_mutable(&cw->events.lower, cw);
2173 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2175 if (cw->ec->layer_pending)
2176 e_comp_object_layer_update(obj, NULL, obj);
2178 #ifdef REFACTOR_DESK_AREA
2179 e_comp_object_lower(cw, obj);
2181 _e_comp_object_lower(cw, obj);
2185 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2186 o = evas_object_below_get(obj);
2187 _e_comp_object_layers_remove(cw);
2188 /* prepend to client list since this client should be the first item now */
2189 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2190 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2191 evas_object_data_set(obj, "client_restack", (void*)1);
2192 #ifdef REFACTOR_DESK_AREA
2193 e_comp_object_lower(cw, obj);
2195 _e_comp_object_lower(cw, obj);
2197 evas_object_data_del(obj, "client_restack");
2198 if (!cw->visible) goto end;
2199 e_comp_render_queue();
2200 #ifdef REFACTOR_DESK_AREA
2201 e_comp_object_transform_obj_stack_update(obj);
2203 _e_comp_object_transform_obj_stack_update(obj);
2212 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2214 E_Comp_Object *cw = data;
2215 #ifdef REFACTOR_DESK_AREA
2221 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2223 #ifdef REFACTOR_DESK_AREA
2224 wl_signal_emit_mutable(&cw->events.raise, cw);
2226 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2228 if (cw->ec->layer_pending)
2230 int obj_layer = evas_object_layer_get(obj);
2231 if (cw->ec->layer != obj_layer)
2232 e_comp_object_layer_update(obj, NULL, NULL);
2234 #ifdef REFACTOR_DESK_AREA
2235 e_comp_object_raise(obj);
2237 _e_comp_object_raise(obj);
2241 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2242 o = evas_object_above_get(obj);
2243 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2245 /* still stack below override below the layer marker */
2246 for (op = o = e_comp->layers[cw->layer].obj;
2247 o && o != e_comp->layers[cw->layer - 1].obj;
2248 op = o, o = evas_object_below_get(o))
2250 if (evas_object_smart_smart_get(o))
2254 ec = e_comp_object_client_get(o);
2255 if (ec && (!ec->override)) break;
2258 #ifdef REFACTOR_DESK_AREA
2259 e_comp_object_stack_below(obj, op);
2261 _e_comp_object_stack_below(obj, op);
2263 e_client_focus_defer_set(cw->ec);
2265 if (!cw->visible) goto end;
2266 e_comp_render_queue();
2267 #ifdef REFACTOR_DESK_AREA
2268 e_comp_object_transform_obj_stack_update(obj);
2270 _e_comp_object_transform_obj_stack_update(obj);
2279 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2281 E_Comp_Object *cw = data;
2283 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2284 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2286 ELOGF("COMP", "Hide. intercepted", cw->ec);
2291 if (cw->ec->launching == EINA_TRUE)
2293 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2294 cw->ec->launching = EINA_FALSE;
2299 /* hidden flag = just do it */
2300 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2301 evas_object_hide(obj);
2303 wl_signal_emit_mutable(&cw->events.hide, NULL);
2308 if (cw->ec->input_only)
2310 /* input_only = who cares */
2311 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2312 evas_object_hide(obj);
2314 wl_signal_emit_mutable(&cw->events.hide, NULL);
2318 /* already hidden or currently animating */
2319 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2321 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2325 /* don't try hiding during shutdown */
2326 cw->defer_hide |= stopping;
2327 if (!cw->defer_hide)
2329 if ((!cw->ec->iconic) && (!cw->ec->override))
2330 /* unset delete requested so the client doesn't break */
2331 cw->ec->delete_requested = 0;
2332 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2334 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2335 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2338 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2341 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2343 _e_comp_object_animating_begin(cw);
2344 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2346 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2347 cw->defer_hide = !!cw->animating;
2349 e_comp_object_effect_set(obj, NULL);
2352 if (cw->animating) return;
2353 /* if we have no animations running, go ahead and hide */
2355 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2356 evas_object_hide(obj);
2358 wl_signal_emit_mutable(&cw->events.hide, NULL);
2362 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2364 E_Client *ec = cw->ec;
2367 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2369 if (ec->show_pending.count > 0)
2371 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2372 ec->show_pending.running = EINA_TRUE;
2376 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2377 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2379 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2384 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,
2385 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2386 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2389 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2392 if (ec->iconic && cw->animating)
2394 /* triggered during iconify animation */
2395 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2398 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2401 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2402 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2404 evas_object_move(cw->smart_obj, ec->x, ec->y);
2405 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2406 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2408 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2409 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2412 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2413 evas_object_show(cw->smart_obj);
2416 e_client_focus_defer_set(ec);
2420 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2424 pw = ec->client.w, ph = ec->client.h;
2426 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2428 ec->changes.visible = !ec->hidden;
2431 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2435 cw->updates = eina_tiler_new(pw, ph);
2438 ec->changes.visible = !ec->hidden;
2441 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2446 eina_tiler_tile_size_set(cw->updates, 1, 1);
2449 /* ignore until client idler first run */
2450 ec->changes.visible = !ec->hidden;
2453 ELOGF("COMP", "show_helper. return. new_client", ec);
2460 evas_object_move(cw->smart_obj, ec->x, ec->y);
2461 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2462 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2463 evas_object_show(cw->smart_obj);
2466 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2468 /* start_drag not received */
2469 ec->changes.visible = 1;
2472 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2475 /* re-set geometry */
2476 evas_object_move(cw->smart_obj, ec->x, ec->y);
2477 /* force resize in case it hasn't happened yet, or just to update size */
2478 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2479 if ((cw->w < 1) || (cw->h < 1))
2481 /* if resize didn't go through, try again */
2482 ec->visible = ec->changes.visible = 1;
2484 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2487 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2488 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2489 e_pixmap_clear(ec->pixmap);
2491 if (cw->real_hid && w && h)
2494 /* force comp theming in case it didn't happen already */
2495 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2496 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2497 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2500 /* only do the show if show is allowed */
2503 if (ec->internal) //internal clients render when they feel like it
2504 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2506 if (!e_client_is_iconified_by_client(ec)||
2507 e_policy_visibility_client_is_uniconic(ec))
2509 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2510 evas_object_show(cw->smart_obj);
2512 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2513 it is rendered in idle callback without native surface and
2514 compositor shows an empty frame if other objects aren't shown
2515 because job callback of e_comp called at the next loop.
2516 it causes a visual defect when windows are switched.
2520 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2521 e_comp_object_dirty(cw->smart_obj);
2522 e_comp_object_render(cw->smart_obj);
2527 wl_signal_emit_mutable(&cw->events.show, NULL);
2531 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2533 E_Comp_Object *cw = data;
2534 E_Client *ec = cw->ec;
2536 E_Input_Rect_Data *input_rect_data;
2537 E_Input_Rect_Smart_Data *input_rect_sd;
2540 if (ec->ignored) return;
2544 //INF("SHOW2 %p", ec);
2545 _e_comp_intercept_show_helper(cw);
2548 //INF("SHOW %p", ec);
2551 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2552 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2553 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2554 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2558 if ((!cw->obj) && (cw->external_content))
2560 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2564 _e_comp_object_setup(cw);
2567 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2568 cw->obj = evas_object_image_filled_add(e_comp->evas);
2569 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2570 e_util_size_debug_set(cw->obj, 1);
2571 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2572 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2573 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2574 evas_object_name_set(cw->obj, "cw->obj");
2575 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2577 _e_comp_object_alpha_set(cw);
2580 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2583 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2584 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2587 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2590 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2592 if (input_rect_data->obj)
2594 evas_object_geometry_set(input_rect_data->obj,
2595 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2596 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2597 input_rect_data->rect.w, input_rect_data->rect.h);
2604 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2606 _e_comp_intercept_show_helper(cw);
2610 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2612 E_Comp_Object *cw = data;
2616 /* note: this is here as it seems there are enough apps that do not even
2617 * expect us to emulate a look of focus but not actually set x input
2618 * focus as we do - so simply abort any focus set on such windows */
2619 /* be strict about accepting focus hint */
2620 /* be strict about accepting focus hint */
2621 if ((!ec->icccm.accepts_focus) &&
2622 (!ec->icccm.take_focus))
2626 if (e_client_focused_get() == ec)
2627 e_client_focused_set(NULL);
2629 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2630 evas_object_focus_set(obj, focus);
2634 if (focus && ec->lock_focus_out) return;
2635 if (e_object_is_del(E_OBJECT(ec)) && focus)
2636 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2638 /* filter focus setting based on current state */
2643 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2644 evas_object_focus_set(obj, focus);
2647 if ((ec->iconic) && (!ec->deskshow))
2649 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2651 /* don't focus an iconified window. that's silly! */
2652 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2653 e_client_uniconify(ec);
2654 e_client_focus_latest_set(ec);
2668 /* not yet visible, wait till the next time... */
2669 ec->want_focus = !ec->hidden;
2674 e_client_focused_set(ec);
2678 if (e_client_focused_get() == ec)
2679 e_client_focused_set(NULL);
2683 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2685 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2687 evas_object_focus_set(obj, focus);
2691 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2693 E_Comp_Object *cw = data;
2695 if (cw->transparent.set)
2697 cw->transparent.user_r = r;
2698 cw->transparent.user_g = g;
2699 cw->transparent.user_b = b;
2700 cw->transparent.user_a = a;
2702 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2704 cw->transparent.user_r,
2705 cw->transparent.user_g,
2706 cw->transparent.user_b,
2707 cw->transparent.user_a);
2711 evas_object_color_set(obj, r, g, b, a);
2714 ////////////////////////////////////////////////////
2717 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2719 int w, h, ox, oy, ow, oh;
2721 Eina_Bool pass_event_flag = EINA_FALSE;
2722 E_Input_Rect_Data *input_rect_data;
2723 E_Input_Rect_Smart_Data *input_rect_sd;
2725 if (cw->frame_object)
2727 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2728 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2729 /* set a fixed size, force edje calc, check size difference */
2730 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2731 edje_object_message_signal_process(cw->frame_object);
2732 edje_object_calc_force(cw->frame_object);
2733 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2734 cw->client_inset.l = ox;
2735 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2736 cw->client_inset.t = oy;
2737 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2738 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2739 evas_object_resize(cw->frame_object, w, h);
2743 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2746 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2748 if (input_rect_data->obj)
2750 pass_event_flag = EINA_TRUE;
2756 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2757 evas_object_pass_events_set(cw->obj, pass_event_flag);
2761 cw->client_inset.l = 0;
2762 cw->client_inset.r = 0;
2763 cw->client_inset.t = 0;
2764 cw->client_inset.b = 0;
2766 cw->client_inset.calc = !!cw->frame_object;
2770 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2772 E_Comp_Object *cw = data;
2776 /* - get current size
2778 * - readjust for new frame size
2781 w = cw->ec->w, h = cw->ec->h;
2782 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2784 _e_comp_object_frame_recalc(cw);
2786 if (!cw->ec->fullscreen)
2787 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2789 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2790 if (cw->ec->fullscreen)
2792 zone = e_comp_zone_find_by_ec(cw->ec);
2794 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2796 else if (cw->ec->new_client)
2798 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2799 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2800 evas_object_resize(cw->ec->frame, w, h);
2802 else if ((w != cw->ec->w) || (h != cw->ec->h))
2803 evas_object_resize(cw->ec->frame, w, h);
2807 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2809 E_Comp_Object *cw = data;
2811 _e_comp_object_shadow_setup(cw);
2812 if (cw->frame_object)
2814 _e_comp_object_shadow(cw);
2815 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2816 _e_comp_object_frame_recalc(cw);
2817 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2822 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2824 E_Comp_Object *cw = data;
2826 if (_e_comp_object_shadow_setup(cw))
2827 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2828 if (cw->frame_object)
2830 _e_comp_object_shadow(cw);
2831 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2832 _e_comp_object_frame_recalc(cw);
2833 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2838 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2840 E_Comp_Object *cw = data;
2842 if (cw->frame_object)
2844 _e_comp_object_shadow(cw);
2845 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2846 _e_comp_object_frame_recalc(cw);
2847 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2852 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2854 E_Comp_Object *cw = data;
2856 if (_e_comp_object_shadow_setup(cw))
2859 cw->ec->changes.size = 1;
2861 if (cw->frame_object)
2863 _e_comp_object_shadow(cw);
2864 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2865 _e_comp_object_frame_recalc(cw);
2866 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2871 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2873 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2877 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2879 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2883 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2885 E_Comp_Object *cw = data;
2887 if (!cw->ec) return; //NYI
2888 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2892 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2894 E_Comp_Object *cw = data;
2896 if (!cw->ec) return; //NYI
2897 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2901 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2903 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2907 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2909 E_Comp_Object *cw = data;
2911 if (!e_object_is_del(E_OBJECT(cw->ec)))
2912 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2916 _e_comp_input_obj_smart_add(Evas_Object *obj)
2918 E_Input_Rect_Smart_Data *input_rect_sd;
2919 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2921 if (!input_rect_sd) return;
2922 evas_object_smart_data_set(obj, input_rect_sd);
2926 _e_comp_input_obj_smart_del(Evas_Object *obj)
2928 E_Input_Rect_Smart_Data *input_rect_sd;
2929 E_Input_Rect_Data *input_rect_data;
2931 input_rect_sd = evas_object_smart_data_get(obj);
2932 if (!input_rect_sd) return;
2934 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2936 if (input_rect_data->obj)
2938 evas_object_smart_member_del(input_rect_data->obj);
2939 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2941 E_FREE(input_rect_data);
2943 E_FREE(input_rect_sd);
2947 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2949 E_Input_Rect_Smart_Data *input_rect_sd;
2950 E_Input_Rect_Data *input_rect_data;
2954 input_rect_sd = evas_object_smart_data_get(obj);
2955 if (!input_rect_sd) return;
2957 cw = input_rect_sd->cw;
2958 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2960 if (input_rect_data->obj)
2962 evas_object_geometry_set(input_rect_data->obj,
2963 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2964 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2965 input_rect_data->rect.w, input_rect_data->rect.h);
2971 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2973 E_Input_Rect_Smart_Data *input_rect_sd;
2974 E_Input_Rect_Data *input_rect_data;
2978 input_rect_sd = evas_object_smart_data_get(obj);
2979 if (!input_rect_sd) return;
2981 cw = input_rect_sd->cw;
2982 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2984 if (input_rect_data->obj)
2986 evas_object_geometry_set(input_rect_data->obj,
2987 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2988 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2989 input_rect_data->rect.w, input_rect_data->rect.h);
2995 _e_comp_input_obj_smart_show(Evas_Object *obj)
2997 E_Input_Rect_Smart_Data *input_rect_sd;
2998 E_Input_Rect_Data *input_rect_data;
3001 input_rect_sd = evas_object_smart_data_get(obj);
3002 if (!input_rect_sd) return;
3004 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3006 if (input_rect_data->obj)
3008 evas_object_show(input_rect_data->obj);
3014 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3016 E_Input_Rect_Smart_Data *input_rect_sd;
3017 E_Input_Rect_Data *input_rect_data;
3020 input_rect_sd = evas_object_smart_data_get(obj);
3021 if (!input_rect_sd) return;
3023 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3025 if (input_rect_data->obj)
3027 evas_object_hide(input_rect_data->obj);
3033 _e_comp_input_obj_smart_init(void)
3035 if (_e_comp_input_obj_smart) return;
3037 static const Evas_Smart_Class sc =
3039 INPUT_OBJ_SMART_NAME,
3040 EVAS_SMART_CLASS_VERSION,
3041 _e_comp_input_obj_smart_add,
3042 _e_comp_input_obj_smart_del,
3043 _e_comp_input_obj_smart_move,
3044 _e_comp_input_obj_smart_resize,
3045 _e_comp_input_obj_smart_show,
3046 _e_comp_input_obj_smart_hide,
3059 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3065 _e_comp_smart_add(Evas_Object *obj)
3069 cw = E_NEW(E_Comp_Object, 1);
3070 EINA_SAFETY_ON_NULL_RETURN(cw);
3072 wl_signal_init(&cw->events.lower);
3073 #ifdef REFACTOR_DESK_AREA
3074 wl_signal_init(&cw->events.lower_done);
3075 wl_signal_init(&cw->events.raise);
3077 wl_signal_init(&cw->events.show);
3078 wl_signal_init(&cw->events.hide);
3079 #ifdef REFACTOR_DESK_AREA
3080 wl_signal_init(&cw->events.set_layer);
3081 wl_signal_init(&cw->events.stack_above);
3082 wl_signal_init(&cw->events.stack_below);
3084 wl_signal_init(&cw->events.image_filter_set);
3085 wl_signal_init(&cw->events.render_op_set);
3087 cw->smart_obj = obj;
3088 cw->x = cw->y = cw->w = cw->h = -1;
3089 evas_object_smart_data_set(obj, cw);
3090 cw->opacity = 255.0;
3091 cw->external_content = 0;
3092 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3093 cw->transform_bg_color.r = 0;
3094 cw->transform_bg_color.g = 0;
3095 cw->transform_bg_color.b = 0;
3096 cw->transform_bg_color.a = 255;
3097 evas_object_data_set(obj, "comp_obj", cw);
3098 evas_object_move(obj, -1, -1);
3099 /* intercept ALL the callbacks! */
3100 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3101 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3102 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3103 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3104 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3105 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3106 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3107 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3108 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3109 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3110 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3112 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3113 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3114 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3115 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3117 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3118 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3120 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3121 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3123 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3125 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3126 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3130 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3133 evas_object_color_set(cw->clip, r, g, b, a);
3134 evas_object_smart_callback_call(obj, "color_set", NULL);
3139 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3142 evas_object_clip_set(cw->clip, clip);
3146 _e_comp_smart_clip_unset(Evas_Object *obj)
3149 evas_object_clip_unset(cw->clip);
3153 _e_comp_smart_hide(Evas_Object *obj)
3155 TRACE_DS_BEGIN(COMP:SMART HIDE);
3160 evas_object_hide(cw->clip);
3161 if (cw->input_obj) evas_object_hide(cw->input_obj);
3162 evas_object_hide(cw->effect_obj);
3163 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3164 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3165 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3172 /* unset native surface if current displaying buffer was destroied */
3173 if (!cw->buffer_destroy_listener.notify)
3175 Evas_Native_Surface *ns;
3176 ns = evas_object_image_native_surface_get(cw->obj);
3177 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3178 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3181 if (!cw->ec->input_only)
3183 edje_object_freeze(cw->effect_obj);
3184 edje_object_freeze(cw->shobj);
3185 edje_object_play_set(cw->shobj, 0);
3186 if (cw->frame_object)
3187 edje_object_play_set(cw->frame_object, 0);
3190 e_comp_render_queue(); //force nocomp recheck
3196 _e_comp_smart_show(Evas_Object *obj)
3204 if ((cw->w < 0) || (cw->h < 0))
3205 CRI("ACK! ec:%p", cw->ec);
3207 TRACE_DS_BEGIN(COMP:SMART SHOW);
3209 e_comp_object_map_update(obj);
3211 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3212 evas_object_show(tmp->frame);
3214 evas_object_show(cw->clip);
3215 if (cw->input_obj) evas_object_show(cw->input_obj);
3216 if (!cw->ec->input_only)
3218 edje_object_thaw(cw->effect_obj);
3219 edje_object_thaw(cw->shobj);
3220 edje_object_play_set(cw->shobj, 1);
3221 if (cw->frame_object)
3222 edje_object_play_set(cw->frame_object, 1);
3224 evas_object_show(cw->effect_obj);
3225 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3226 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3227 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3228 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3229 e_comp_render_queue();
3230 if (cw->ec->input_only)
3235 if (cw->ec->iconic && (!cw->ec->new_client))
3237 if (e_client_is_iconified_by_client(cw->ec))
3239 ELOGF("COMP", "Set launching flag..", cw->ec);
3240 cw->ec->launching = EINA_TRUE;
3243 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3245 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3248 ELOGF("COMP", "Set launching flag..", cw->ec);
3249 cw->ec->launching = EINA_TRUE;
3251 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3252 _e_comp_object_animating_begin(cw);
3253 if (!_e_comp_object_effect_visibility_start(cw, 1))
3259 /* ensure some random effect doesn't lock the client offscreen */
3263 e_comp_object_effect_set(obj, NULL);
3266 _e_comp_object_dim_update(cw);
3272 _e_comp_smart_del(Evas_Object *obj)
3278 if (cw->buffer_destroy_listener.notify)
3280 wl_list_remove(&cw->buffer_destroy_listener.link);
3281 cw->buffer_destroy_listener.notify = NULL;
3284 if (cw->tbm_surface)
3286 tbm_surface_internal_unref(cw->tbm_surface);
3287 cw->tbm_surface = NULL;
3290 if (cw->render_update_lock.buffer_ref.buffer)
3292 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3293 cw->ec, cw->render_update_lock.lock);
3294 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3297 e_comp_object_render_update_del(cw->smart_obj);
3298 E_FREE_FUNC(cw->updates, eina_tiler_free);
3299 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3306 EINA_LIST_FREE(cw->obj_mirror, o)
3308 evas_object_image_data_set(o, NULL);
3309 evas_object_freeze_events_set(o, 1);
3310 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3314 #ifdef REFACTOR_DESK_AREA
3316 _e_comp_object_layers_remove(cw);
3318 l = evas_object_data_get(obj, "comp_object-to_del");
3319 E_FREE_LIST(l, evas_object_del);
3320 _e_comp_object_mouse_event_callback_unset(cw);
3321 evas_object_del(cw->clip);
3322 evas_object_del(cw->obj);
3323 evas_object_del(cw->shobj);
3324 evas_object_del(cw->effect_obj);
3325 evas_object_del(cw->frame_object);
3326 evas_object_del(cw->input_obj);
3327 evas_object_del(cw->mask.obj);
3328 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3329 evas_object_del(cw->transform_bg_obj);
3330 evas_object_del(cw->transform_tranp_obj);
3331 evas_object_del(cw->default_input_obj);
3332 eina_stringshare_del(cw->frame_theme);
3333 eina_stringshare_del(cw->frame_name);
3337 e_comp->animating--;
3339 e_object_unref(E_OBJECT(cw->ec));
3341 cw->ec->frame = NULL;
3346 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3350 cw->x = x, cw->y = y;
3351 evas_object_move(cw->effect_obj, x, y);
3352 evas_object_move(cw->default_input_obj, x, y);
3353 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3355 e_comp_object_map_update(obj);
3359 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3361 Eina_Bool first = EINA_FALSE;
3366 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3368 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3370 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3372 if (cw->w != w || cw->h != h)
3373 e_comp_object_map_update(obj);
3375 first = ((cw->w < 1) || (cw->h < 1));
3376 cw->w = w, cw->h = h;
3380 if (cw->frame_object)
3381 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3384 /* verify pixmap:object size */
3385 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3387 if ((ww != pw) || (hh != ph))
3388 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3390 evas_object_resize(cw->effect_obj, tw, th);
3391 evas_object_resize(cw->default_input_obj, w, h);
3393 evas_object_resize(cw->input_obj, w, h);
3395 evas_object_resize(cw->mask.obj, w, h);
3396 /* resize render update tiler */
3399 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3400 cw->updates_full = 0;
3401 if (cw->updates) eina_tiler_clear(cw->updates);
3405 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3406 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3414 e_comp_render_queue();
3420 _e_comp_smart_init(void)
3422 if (_e_comp_smart) return;
3424 static const Evas_Smart_Class sc =
3427 EVAS_SMART_CLASS_VERSION,
3431 _e_comp_smart_resize,
3434 _e_comp_smart_color_set,
3435 _e_comp_smart_clip_set,
3436 _e_comp_smart_clip_unset,
3446 _e_comp_smart = evas_smart_class_new(&sc);
3451 e_comp_object_init(void)
3453 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3454 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3455 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3456 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3460 e_comp_object_shutdown(void)
3466 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3468 API_ENTRY EINA_FALSE;
3469 return !!cw->force_visible;
3471 /////////////////////////////////////////////////////////
3474 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3477 Eina_Bool comp_object;
3479 comp_object = !!evas_object_data_get(obj, "comp_object");
3484 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3486 e_comp_render_queue();
3488 l = evas_object_data_get(obj, "comp_object-to_del");
3489 E_FREE_LIST(l, evas_object_del);
3493 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3495 if (e_comp_util_object_is_above_nocomp(obj) &&
3496 (!evas_object_data_get(obj, "comp_override")))
3498 evas_object_data_set(obj, "comp_override", (void*)1);
3499 e_comp_override_add();
3504 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3506 Eina_Bool ref = EINA_TRUE;
3507 if (evas_object_visible_get(obj))
3511 d = evas_object_data_del(obj, "comp_hiding");
3513 /* currently trying to hide */
3516 /* already visible */
3520 evas_object_show(obj);
3523 evas_object_ref(obj);
3524 evas_object_data_set(obj, "comp_ref", (void*)1);
3526 edje_object_signal_emit(obj, "e,state,visible", "e");
3527 evas_object_data_set(obj, "comp_showing", (void*)1);
3528 if (e_comp_util_object_is_above_nocomp(obj))
3530 evas_object_data_set(obj, "comp_override", (void*)1);
3531 e_comp_override_add();
3536 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3538 if (!evas_object_visible_get(obj)) return;
3539 /* already hiding */
3540 if (evas_object_data_get(obj, "comp_hiding")) return;
3541 if (!evas_object_data_del(obj, "comp_showing"))
3543 evas_object_ref(obj);
3544 evas_object_data_set(obj, "comp_ref", (void*)1);
3546 edje_object_signal_emit(obj, "e,state,hidden", "e");
3547 evas_object_data_set(obj, "comp_hiding", (void*)1);
3549 if (evas_object_data_del(obj, "comp_override"))
3550 e_comp_override_timed_pop();
3554 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3556 if (!e_util_strcmp(emission, "e,action,hide,done"))
3558 if (!evas_object_data_del(obj, "comp_hiding")) return;
3559 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3560 evas_object_hide(obj);
3561 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3564 evas_object_data_del(obj, "comp_showing");
3565 if (evas_object_data_del(obj, "comp_ref"))
3566 evas_object_unref(obj);
3570 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3576 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3580 E_API E_Comp_Object_Hook *
3581 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3583 E_Comp_Object_Hook *ch;
3585 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3586 ch = E_NEW(E_Comp_Object_Hook, 1);
3587 if (!ch) return NULL;
3588 ch->hookpoint = hookpoint;
3590 ch->data = (void*)data;
3591 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3596 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3599 if (_e_comp_object_hooks_walking == 0)
3601 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3605 _e_comp_object_hooks_delete++;
3608 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3609 E_API E_Comp_Object_Intercept_Hook *
3610 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3612 E_Comp_Object_Intercept_Hook *ch;
3614 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3615 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3616 if (!ch) return NULL;
3617 ch->hookpoint = hookpoint;
3619 ch->data = (void*)data;
3620 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3625 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3628 if (_e_comp_object_intercept_hooks_walking == 0)
3630 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3634 _e_comp_object_intercept_hooks_delete++;
3639 e_comp_object_util_add(Evas_Object *obj)
3643 E_Comp_Config *conf = e_comp_config_get();
3644 Eina_Bool skip = EINA_FALSE;
3650 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3652 name = evas_object_name_get(obj);
3653 vis = evas_object_visible_get(obj);
3654 o = edje_object_add(e_comp->evas);
3655 evas_object_data_set(o, "comp_object", (void*)1);
3657 skip = (!strncmp(name, "noshadow", 8));
3659 evas_object_data_set(o, "comp_object_skip", (void*)1);
3661 if (conf->shadow_style)
3663 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3664 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3667 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3668 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3669 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3671 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3673 evas_object_geometry_get(obj, &x, &y, &w, &h);
3674 evas_object_geometry_set(o, x, y, w, h);
3675 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3677 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3679 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3680 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3681 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3682 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3683 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3684 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3686 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3688 edje_object_part_swallow(o, "e.swallow.content", obj);
3690 _e_comp_object_event_add(o);
3693 evas_object_show(o);
3698 /* utility functions for deleting objects when their "owner" is deleted */
3700 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3705 EINA_SAFETY_ON_NULL_RETURN(to_del);
3706 l = evas_object_data_get(obj, "comp_object-to_del");
3707 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3708 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3709 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3713 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3718 EINA_SAFETY_ON_NULL_RETURN(to_del);
3719 l = evas_object_data_get(obj, "comp_object-to_del");
3721 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3724 /////////////////////////////////////////////////////////
3726 EINTERN Evas_Object *
3727 e_comp_object_client_add(E_Client *ec)
3732 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3733 if (ec->frame) return NULL;
3734 _e_comp_smart_init();
3735 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3736 cw = evas_object_smart_data_get(o);
3737 if (!cw) return NULL;
3738 evas_object_data_set(o, "E_Client", ec);
3741 evas_object_data_set(o, "comp_object", (void*)1);
3743 _e_comp_object_event_add(o);
3748 /* utility functions for getting client inset */
3750 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3753 if (!cw->client_inset.calc)
3759 if (ax) *ax = x - cw->client_inset.l;
3760 if (ay) *ay = y - cw->client_inset.t;
3764 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3767 if (!cw->client_inset.calc)
3773 if (ax) *ax = x + cw->client_inset.l;
3774 if (ay) *ay = y + cw->client_inset.t;
3778 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3781 if (!cw->client_inset.calc)
3787 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3788 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3792 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3795 if (!cw->client_inset.calc)
3801 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3802 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3806 e_comp_object_client_get(Evas_Object *obj)
3811 /* FIXME: remove this when eo is used */
3812 o = evas_object_data_get(obj, "comp_smart_obj");
3814 return e_comp_object_client_get(o);
3815 return cw ? cw->ec : NULL;
3819 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3822 if (cw->frame_extends)
3823 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3828 if (w) *w = cw->ec->w;
3829 if (h) *h = cw->ec->h;
3834 e_comp_object_util_zone_get(Evas_Object *obj)
3836 E_Zone *zone = NULL;
3840 zone = e_comp_zone_find_by_ec(cw->ec);
3845 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3846 zone = e_comp_zone_xy_get(x, y);
3852 e_comp_object_util_center(Evas_Object *obj)
3854 int x, y, w, h, ow, oh;
3859 zone = e_comp_object_util_zone_get(obj);
3860 EINA_SAFETY_ON_NULL_RETURN(zone);
3861 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3862 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3863 ow = cw->ec->w, oh = cw->ec->h;
3865 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3866 x = x + (w - ow) / 2;
3867 y = y + (h - oh) / 2;
3868 evas_object_move(obj, x, y);
3872 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3874 int x, y, w, h, ow, oh;
3877 EINA_SAFETY_ON_NULL_RETURN(on);
3878 evas_object_geometry_get(on, &x, &y, &w, &h);
3879 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3880 ow = cw->ec->w, oh = cw->ec->h;
3882 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3883 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3887 e_comp_object_util_fullscreen(Evas_Object *obj)
3892 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3895 evas_object_move(obj, 0, 0);
3896 evas_object_resize(obj, e_comp->w, e_comp->h);
3901 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3909 ow = cw->w, oh = cw->h;
3911 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3912 zone = e_comp_object_util_zone_get(obj);
3913 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3914 if (x) *x = zx + (zw - ow) / 2;
3915 if (y) *y = zy + (zh - oh) / 2;
3919 e_comp_object_input_objs_del(Evas_Object *obj)
3922 E_Input_Rect_Data *input_rect_data;
3923 E_Input_Rect_Smart_Data *input_rect_sd;
3928 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3929 if (!input_rect_sd) return;
3931 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3933 if (input_rect_data->obj)
3935 evas_object_smart_member_del(input_rect_data->obj);
3936 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3938 E_FREE(input_rect_data);
3943 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3946 E_Input_Rect_Data *input_rect_data = NULL;
3947 E_Input_Rect_Smart_Data *input_rect_sd;
3948 int client_w, client_h;
3950 if (cw->ec->client.w)
3951 client_w = cw->ec->client.w;
3953 client_w = cw->ec->w;
3955 if (cw->ec->client.h)
3956 client_h = cw->ec->client.h;
3958 client_h = cw->ec->h;
3960 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3964 _e_comp_input_obj_smart_init();
3965 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3966 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3967 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3970 input_rect_sd->cw = cw;
3973 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3976 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3977 if (input_rect_data)
3979 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3980 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3984 if ((input_rect_data) &&
3985 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3987 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3988 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3989 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3990 evas_object_clip_set(input_rect_data->obj, cw->clip);
3991 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3992 evas_object_geometry_set(input_rect_data->obj,
3993 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3994 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3995 evas_object_pass_events_set(cw->default_input_obj, 1);
3996 evas_object_pass_events_set(cw->obj, 1);
3999 evas_object_show(input_rect_data->obj);
4000 evas_object_show(cw->input_obj);
4005 evas_object_smart_member_del(cw->input_obj);
4006 E_FREE_FUNC(cw->input_obj, evas_object_del);
4007 evas_object_pass_events_set(cw->default_input_obj, 0);
4008 evas_object_pass_events_set(cw->obj, 0);
4013 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4016 E_Input_Rect_Smart_Data *input_rect_sd;
4017 E_Input_Rect_Data *input_rect_data;
4020 if (!cw->input_obj) return;
4022 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4025 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4027 *list = eina_list_append(*list, &input_rect_data->rect);
4033 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4036 if (l) *l = cw->client_inset.l;
4037 if (r) *r = cw->client_inset.r;
4038 if (t) *t = cw->client_inset.t;
4039 if (b) *b = cw->client_inset.b;
4042 /* set geometry for CSD */
4044 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4050 if (cw->frame_object)
4051 CRI("ACK! ec:%p", cw->ec);
4052 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4053 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4054 calc = cw->client_inset.calc;
4055 cw->client_inset.calc = l || r || t || b;
4056 eina_stringshare_replace(&cw->frame_theme, "borderless");
4057 if (cw->client_inset.calc)
4059 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4060 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4061 e_client_size_set(cw->ec, tw, th);
4063 else if (cw->ec->maximized || cw->ec->fullscreen)
4065 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4066 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4068 if (!cw->ec->new_client)
4070 if (calc && cw->client_inset.calc)
4072 tx = cw->ec->x - (l - cw->client_inset.l);
4073 ty = cw->ec->y - (t - cw->client_inset.t);
4074 e_client_pos_set(cw->ec, tx, ty);
4076 cw->ec->changes.pos = cw->ec->changes.size = 1;
4079 cw->client_inset.l = l;
4080 cw->client_inset.r = r;
4081 cw->client_inset.t = t;
4082 cw->client_inset.b = b;
4086 e_comp_object_frame_allowed(Evas_Object *obj)
4088 API_ENTRY EINA_FALSE;
4089 return (cw->frame_object || (!cw->client_inset.calc));
4093 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4095 API_ENTRY EINA_FALSE;
4096 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4097 eina_stringshare_replace(&cw->frame_name, name);
4098 if (cw->frame_object)
4099 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4104 e_comp_object_frame_exists(Evas_Object *obj)
4106 API_ENTRY EINA_FALSE;
4107 return !!cw->frame_object;
4111 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4113 Evas_Object *o, *pbg;
4116 Eina_Stringshare *theme;
4118 API_ENTRY EINA_FALSE;
4120 if (!e_util_strcmp(cw->frame_theme, name))
4121 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4122 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4123 return _e_comp_object_shadow_setup(cw);
4124 pbg = cw->frame_object;
4125 theme = eina_stringshare_add(name);
4127 if (cw->frame_object)
4131 w = cw->ec->w, h = cw->ec->h;
4132 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4133 if ((cw->ec->w != w) || (cw->ec->h != h))
4135 cw->ec->changes.size = 1;
4138 E_FREE_FUNC(cw->frame_object, evas_object_del);
4139 if (!name) goto reshadow;
4141 o = edje_object_add(e_comp->evas);
4142 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4143 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4144 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4146 cw->frame_object = NULL;
4148 eina_stringshare_del(cw->frame_theme);
4149 cw->frame_theme = theme;
4154 if (theme != e_config->theme_default_border_style)
4156 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4157 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4161 ok = e_theme_edje_object_set(o, "base/theme/border",
4162 "e/widgets/border/default/border");
4163 if (ok && (theme == e_config->theme_default_border_style))
4165 /* Reset default border style to default */
4166 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4167 e_config_save_queue();
4174 cw->frame_object = o;
4175 eina_stringshare_del(cw->frame_theme);
4176 cw->frame_theme = theme;
4177 evas_object_name_set(o, "cw->frame_object");
4180 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4184 cw->ec->changes.icon = 1;
4190 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4195 _e_comp_object_shadow_setup(cw);
4198 int old_x, old_y, new_x = 0, new_y = 0;
4200 old_x = cw->x, old_y = cw->y;
4202 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4204 new_x = cw->ec->x, new_y = cw->ec->y;
4205 else if (cw->ec->placed || (!cw->ec->new_client))
4207 /* if no previous frame:
4208 * - reapply client_inset
4213 if (cw->ec->changes.size)
4221 zone = e_comp_zone_find_by_ec(cw->ec);
4224 x = cw->ec->client.x, y = cw->ec->client.y;
4225 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4226 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4228 new_x = x, new_y = y;
4231 if (old_x != new_x || old_y != new_y)
4233 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4234 cw->y = cw->x = -99999;
4235 evas_object_move(obj, new_x, new_y);
4239 if (cw->ec->maximized)
4241 cw->ec->changes.need_maximize = 1;
4244 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4245 if (cw->frame_object)
4247 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4250 cw->frame_extends = 0;
4251 evas_object_del(pbg);
4256 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4258 E_Comp_Object_Mover *prov;
4261 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4262 edje_object_signal_emit(cw->shobj, sig, src);
4263 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4264 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4265 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4267 /* start with highest priority callback first */
4268 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4270 if (!e_util_glob_match(sig, prov->sig)) continue;
4271 if (prov->func(prov->data, obj, sig)) break;
4276 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4278 /* FIXME: at some point I guess this should use eo to inherit
4279 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4280 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4283 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4287 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4290 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4294 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4297 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4301 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4304 Eina_Rectangle rect;
4307 if (cw->ec->input_only || (!cw->updates)) return;
4308 if (cw->nocomp) return;
4309 rect.x = x, rect.y = y;
4310 rect.w = w, rect.h = h;
4311 evas_object_smart_callback_call(obj, "damage", &rect);
4313 if (e_comp_is_on_overlay(cw->ec))
4315 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4316 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4317 * E module attempts to block screen update due to the particular policy.
4319 if (e_pixmap_resource_get(cw->ec->pixmap))
4320 cw->hwc_need_update = EINA_TRUE;
4323 /* ignore overdraw */
4324 if (cw->updates_full)
4326 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4327 e_comp_object_render_update_add(obj);
4329 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4330 evas_object_show(cw->smart_obj);
4334 /* clip rect to client surface */
4335 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4336 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4337 /* if rect is the total size of the client after clip, clear the updates
4338 * since this is guaranteed to be the whole region anyway
4340 eina_tiler_area_size_get(cw->updates, &tw, &th);
4341 if ((w > tw) || (h > th))
4343 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4344 eina_tiler_clear(cw->updates);
4345 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4347 tw = cw->ec->client.w, th = cw->ec->client.h;
4349 if ((!x) && (!y) && (w == tw) && (h == th))
4351 eina_tiler_clear(cw->updates);
4352 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4353 cw->updates_full = 1;
4354 cw->update_count = 0;
4357 if (cw->update_count > UPDATE_MAX)
4359 /* this is going to get really dumb, so just update the whole thing */
4360 eina_tiler_clear(cw->updates);
4361 cw->update_count = cw->updates_full = 1;
4362 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4363 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4367 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4368 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4370 cw->updates_exist = 1;
4371 e_comp_object_render_update_add(obj);
4373 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4374 evas_object_show(cw->smart_obj);
4378 e_comp_object_damage_exists(Evas_Object *obj)
4380 API_ENTRY EINA_FALSE;
4381 return cw->updates_exist;
4385 e_comp_object_render_update_add(Evas_Object *obj)
4389 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4390 if (cw->render_update_lock.lock) return;
4391 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4395 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4397 e_comp_render_queue();
4401 e_comp_object_render_update_del(Evas_Object *obj)
4405 if (cw->ec->input_only || (!cw->updates)) return;
4406 if (!cw->update) return;
4408 /* this gets called during comp animating to clear the update flag */
4409 if (e_comp->grabbed) return;
4410 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4411 if (!e_comp->updates)
4413 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4414 if (e_comp->render_animator)
4415 ecore_animator_freeze(e_comp->render_animator);
4420 e_comp_object_shape_apply(Evas_Object *obj)
4424 unsigned int i, *pix, *p;
4428 if (!cw->ec) return; //NYI
4429 if (cw->external_content) return;
4432 if ((cw->ec->shape_rects_num >= 1) &&
4433 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4438 ERR("BUGGER: shape with native surface? cw=%p", cw);
4441 evas_object_image_size_get(cw->obj, &w, &h);
4442 if ((w < 1) || (h < 1)) return;
4445 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4446 _e_comp_object_alpha_set(cw);
4447 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4448 evas_object_image_alpha_set(o, 1);
4450 p = pix = evas_object_image_data_get(cw->obj, 1);
4453 evas_object_image_data_set(cw->obj, pix);
4458 unsigned char *spix, *sp;
4460 spix = calloc(w * h, sizeof(unsigned char));
4462 for (i = 0; i < cw->ec->shape_rects_num; i++)
4466 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4467 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4468 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4469 sp = spix + (w * ry) + rx;
4470 for (py = 0; py < rh; py++)
4472 for (px = 0; px < rw; px++)
4480 for (py = 0; py < h; py++)
4482 for (px = 0; px < w; px++)
4484 unsigned int mask, imask;
4486 mask = ((unsigned int)(*sp)) << 24;
4488 imask |= imask >> 8;
4489 imask |= imask >> 8;
4490 *p = mask | (*p & imask);
4491 //if (*sp) *p = 0xff000000 | *p;
4492 //else *p = 0x00000000;
4501 for (py = 0; py < h; py++)
4503 for (px = 0; px < w; px++)
4507 evas_object_image_data_set(cw->obj, pix);
4508 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4509 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4511 evas_object_image_data_set(o, pix);
4512 evas_object_image_data_update_add(o, 0, 0, w, h);
4514 // don't need to fix alpha chanel as blending
4515 // should be totally off here regardless of
4516 // alpha channel content
4520 _e_comp_object_clear(E_Comp_Object *cw)
4525 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4527 if (cw->render_update_lock.lock) return;
4530 e_pixmap_clear(cw->ec->pixmap);
4532 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4533 evas_object_image_size_set(cw->obj, 1, 1);
4534 evas_object_image_data_set(cw->obj, NULL);
4535 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4537 evas_object_image_size_set(o, 1, 1);
4538 evas_object_image_data_set(o, NULL);
4541 e_comp_object_render_update_del(cw->smart_obj);
4545 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4549 API_ENTRY EINA_FALSE;
4551 if (cw->transparent.set == set)
4556 evas_object_color_get(obj, &r, &g, &b, &a);
4557 evas_object_color_set(obj, 0, 0, 0, 0);
4559 cw->transparent.user_r = r;
4560 cw->transparent.user_g = g;
4561 cw->transparent.user_b = b;
4562 cw->transparent.user_a = a;
4564 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4566 cw->transparent.user_r,
4567 cw->transparent.user_g,
4568 cw->transparent.user_b,
4569 cw->transparent.user_a);
4571 cw->transparent.set = EINA_TRUE;
4575 cw->transparent.set = EINA_FALSE;
4577 evas_object_color_set(obj,
4578 cw->transparent.user_r,
4579 cw->transparent.user_g,
4580 cw->transparent.user_b,
4581 cw->transparent.user_a);
4583 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4585 cw->transparent.user_r,
4586 cw->transparent.user_g,
4587 cw->transparent.user_b,
4588 cw->transparent.user_a);
4594 /* helper function to simplify toggling of redirection for display servers which support it */
4596 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4601 if (cw->redirected == set) return;
4602 cw->redirected = set;
4603 if (cw->external_content) return;
4605 e_comp_object_map_update(obj);
4609 if (cw->updates_exist)
4610 e_comp_object_render_update_add(obj);
4612 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4614 _e_comp_object_transparent_set(obj, EINA_FALSE);
4615 evas_object_smart_callback_call(obj, "redirected", NULL);
4619 _e_comp_object_clear(cw);
4620 _e_comp_object_transparent_set(obj, EINA_TRUE);
4621 evas_object_smart_callback_call(obj, "unredirected", NULL);
4626 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4629 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4631 if (cw->buffer_destroy_listener.notify)
4633 cw->buffer_destroy_listener.notify = NULL;
4634 wl_list_remove(&cw->buffer_destroy_listener.link);
4637 if (e_object_is_del(E_OBJECT(cw->ec)))
4639 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4644 /* if it's current displaying buffer, do not remove its content */
4645 if (!evas_object_visible_get(cw->ec->frame))
4646 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4651 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4656 if (cw->buffer_destroy_listener.notify)
4658 wl_list_remove(&cw->buffer_destroy_listener.link);
4659 cw->buffer_destroy_listener.notify = NULL;
4662 if (cw->tbm_surface)
4664 tbm_surface_internal_unref(cw->tbm_surface);
4665 cw->tbm_surface = NULL;
4670 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4672 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4673 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4675 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4677 tbm_surface_internal_ref(ns->data.tbm.buffer);
4678 cw->tbm_surface = ns->data.tbm.buffer;
4682 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4683 evas_object_image_native_surface_set(cw->obj, ns);
4687 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4689 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4690 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4691 evas_object_image_native_surface_set(o, ns);
4698 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4700 Evas_Native_Surface ns;
4703 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4704 if (cw->ec->input_only) return;
4705 if (cw->external_content) return;
4706 if (cw->render_update_lock.lock) return;
4709 memset(&ns, 0, sizeof(Evas_Native_Surface));
4713 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4714 set = (!cw->ec->shaped);
4716 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4720 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4724 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4727 if (cw->ec->input_only) return;
4730 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4731 _e_comp_object_alpha_set(cw);
4733 e_comp_object_native_surface_set(obj, cw->native);
4734 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4738 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4744 if (cw->blanked == set) return;
4746 _e_comp_object_alpha_set(cw);
4749 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4750 evas_object_image_data_set(cw->obj, NULL);
4754 e_comp_object_native_surface_set(obj, 1);
4755 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4759 _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)
4764 if (!_damage_trace) return;
4768 if (!evas_object_visible_get(cw->obj)) return;
4770 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4772 o = evas_object_rectangle_add(e_comp->evas);
4773 evas_object_layer_set(o, E_LAYER_MAX);
4774 evas_object_name_set(o, "damage_trace");
4775 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4776 evas_object_resize(o, dmg_w, dmg_h);
4777 evas_object_color_set(o, 0, 128, 0, 128);
4778 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4779 evas_object_pass_events_set(o, EINA_TRUE);
4780 evas_object_show(o);
4782 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4784 dmg_w, dmg_h, dmg_x, dmg_y,
4785 origin->w, origin->h, origin->x, origin->y);
4787 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4790 /* mark an object as dirty and setup damages */
4792 e_comp_object_dirty(Evas_Object *obj)
4795 Eina_Rectangle *rect;
4799 Eina_Bool dirty, visible;
4803 if (cw->external_content) return;
4804 if (!cw->redirected) return;
4805 if (cw->render_update_lock.lock)
4807 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4810 /* only actually dirty if pixmap is available */
4811 if (!e_pixmap_resource_get(cw->ec->pixmap))
4813 // e_pixmap_size_get returns last attached buffer size
4814 // eventhough it is destroyed
4815 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4818 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4819 visible = cw->visible;
4820 if (!dirty) w = h = 1;
4821 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4823 evas_object_image_data_set(cw->obj, NULL);
4824 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4825 evas_object_image_size_set(cw->obj, tw, th);
4826 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4827 if (cw->pending_updates)
4828 eina_tiler_area_size_set(cw->pending_updates, w, h);
4829 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4831 evas_object_image_pixels_dirty_set(o, dirty);
4833 evas_object_image_data_set(o, NULL);
4834 evas_object_image_size_set(o, tw, th);
4835 visible |= evas_object_visible_get(o);
4839 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4843 e_comp_object_native_surface_set(obj, 1);
4845 m = _e_comp_object_map_damage_transform_get(cw->ec);
4846 it = eina_tiler_iterator_new(cw->updates);
4847 EINA_ITERATOR_FOREACH(it, rect)
4849 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4850 * of evas engine and doesn't convert damage according to evas_map.
4851 * so damage of evas_object_image use surface coordinate.
4855 int damage_x, damage_y, damage_w, damage_h;
4857 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4858 &damage_x, &damage_y, &damage_w, &damage_h);
4859 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4860 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4864 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4865 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4868 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4869 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4870 if (cw->pending_updates)
4871 eina_tiler_rect_add(cw->pending_updates, rect);
4873 eina_iterator_free(it);
4874 if (m) e_map_free(m);
4875 if (cw->pending_updates)
4876 eina_tiler_clear(cw->updates);
4879 cw->pending_updates = cw->updates;
4880 cw->updates = eina_tiler_new(w, h);
4881 eina_tiler_tile_size_set(cw->updates, 1, 1);
4883 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4884 evas_object_smart_callback_call(obj, "dirty", NULL);
4885 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4886 /* force render if main object is hidden but mirrors are visible */
4887 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4888 e_comp_object_render(obj);
4892 e_comp_object_render(Evas_Object *obj)
4899 API_ENTRY EINA_FALSE;
4901 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4902 if (cw->ec->input_only) return EINA_TRUE;
4903 if (cw->external_content) return EINA_TRUE;
4904 if (cw->native) return EINA_FALSE;
4905 /* if comp object is not redirected state, comp object should not be set by newly committed data
4906 because image size of comp object is 1x1 and it should not be shown on canvas */
4907 if (!cw->redirected) return EINA_TRUE;
4908 if (cw->render_update_lock.lock)
4910 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4913 e_comp_object_render_update_del(obj);
4914 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4916 if (!cw->pending_updates)
4918 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4919 evas_object_image_data_set(cw->obj, NULL);
4920 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4921 evas_object_image_data_set(o, NULL);
4925 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4927 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4929 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4932 e_pixmap_image_refresh(cw->ec->pixmap);
4933 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4936 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4937 e_pixmap_image_data_ref(cw->ec->pixmap);
4939 /* set pixel data */
4940 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4941 _e_comp_object_alpha_set(cw);
4942 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4944 evas_object_image_data_set(o, pix);
4945 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4946 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4949 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4951 e_comp_client_post_update_add(cw->ec);
4956 /* create a duplicate of an evas object */
4958 e_comp_object_util_mirror_add(Evas_Object *obj)
4962 unsigned int *pix = NULL;
4963 Eina_Bool argb = EINA_FALSE;
4968 cw = evas_object_data_get(obj, "comp_mirror");
4971 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4972 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4973 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4974 evas_object_image_alpha_set(o, 1);
4975 evas_object_image_source_set(o, obj);
4978 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4979 if (cw->external_content)
4981 ERR("%p of client %p is external content.", obj, cw->ec);
4984 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4985 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4986 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4987 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4988 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4989 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4990 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4991 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4992 evas_object_data_set(o, "comp_mirror", cw);
4994 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4995 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4997 evas_object_image_size_set(o, tw, th);
5000 pix = evas_object_image_data_get(cw->obj, 0);
5006 evas_object_image_native_surface_set(o, cw->ns);
5009 Evas_Native_Surface ns;
5010 memset(&ns, 0, sizeof(Evas_Native_Surface));
5011 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5012 evas_object_image_native_surface_set(o, &ns);
5017 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5018 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5020 (e_pixmap_image_exists(cw->ec->pixmap)))
5021 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5023 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5030 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5031 evas_object_image_pixels_dirty_set(o, dirty);
5032 evas_object_image_data_set(o, pix);
5033 evas_object_image_data_set(cw->obj, pix);
5035 evas_object_image_data_update_add(o, 0, 0, tw, th);
5040 //////////////////////////////////////////////////////
5043 e_comp_object_effect_allowed_get(Evas_Object *obj)
5045 API_ENTRY EINA_FALSE;
5047 if (!cw->shobj) return EINA_FALSE;
5048 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5049 return !e_comp_config_get()->match.disable_borders;
5052 /* setup an api effect for a client */
5054 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5057 Eina_Stringshare *grp;
5058 E_Comp_Config *config;
5059 Eina_Bool loaded = EINA_FALSE;
5061 API_ENTRY EINA_FALSE;
5062 if (!cw->shobj) return EINA_FALSE; //input window
5064 if (!effect) effect = "none";
5065 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5067 config = e_comp_config_get();
5068 if ((config) && (config->effect_file))
5070 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5072 cw->effect_set = EINA_TRUE;
5079 edje_object_file_get(cw->effect_obj, NULL, &grp);
5080 cw->effect_set = !eina_streq(effect, "none");
5081 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5082 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5084 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5085 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5086 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5088 if (cw->effect_running)
5090 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5093 cw->effect_set = EINA_FALSE;
5094 return cw->effect_set;
5098 if (cw->effect_running)
5100 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5103 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5104 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5105 if (cw->effect_clip)
5107 evas_object_clip_unset(cw->clip);
5108 cw->effect_clip = 0;
5110 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5112 _e_comp_object_dim_update(cw);
5114 return cw->effect_set;
5117 /* set params for embryo scripts in effect */
5119 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5121 Edje_Message_Int_Set *msg;
5125 EINA_SAFETY_ON_NULL_RETURN(params);
5126 EINA_SAFETY_ON_FALSE_RETURN(count);
5127 if (!cw->effect_set) return;
5129 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5130 msg->count = (int)count;
5131 for (x = 0; x < count; x++)
5132 msg->val[x] = params[x];
5133 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5134 edje_object_message_signal_process(cw->effect_obj);
5138 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5140 Edje_Signal_Cb end_cb;
5142 E_Comp_Object *cw = data;
5144 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5145 cw->effect_running = 0;
5146 if (!_e_comp_object_animating_end(cw)) return;
5148 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5150 evas_object_data_del(cw->smart_obj, "effect_running");
5151 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5152 e_comp_visibility_calculation_set(EINA_TRUE);
5155 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5156 if (!end_cb) return;
5157 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5158 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5159 end_cb(end_data, cw->smart_obj, emission, source);
5162 /* clip effect to client's zone */
5164 e_comp_object_effect_clip(Evas_Object *obj)
5168 zone = e_comp_zone_find_by_ec(cw->ec);
5170 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5171 if (!cw->effect_clip_able) return;
5172 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5173 cw->effect_clip = 1;
5176 /* unclip effect from client's zone */
5178 e_comp_object_effect_unclip(Evas_Object *obj)
5181 if (!cw->effect_clip) return;
5182 evas_object_clip_unset(cw->smart_obj);
5183 cw->effect_clip = 0;
5186 /* start effect, running end_cb after */
5188 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5190 API_ENTRY EINA_FALSE;
5191 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5192 if (!cw->effect_set) return EINA_FALSE;
5194 if (cw->effect_running)
5196 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5199 e_comp_object_effect_clip(obj);
5200 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5202 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5203 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5204 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5205 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5207 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5208 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5210 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5211 _e_comp_object_animating_begin(cw);
5212 cw->effect_running = 1;
5216 /* stop a currently-running effect immediately */
5218 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5221 Edje_Signal_Cb end_cb_before = NULL;
5222 void *end_data_before = NULL;
5223 API_ENTRY EINA_FALSE;
5225 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5226 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5228 if (end_cb_before != end_cb) return EINA_TRUE;
5229 e_comp_object_effect_unclip(obj);
5230 if (cw->effect_clip)
5232 evas_object_clip_unset(cw->effect_obj);
5233 cw->effect_clip = 0;
5235 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5236 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5238 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5240 evas_object_data_del(cw->smart_obj, "effect_running");
5241 e_comp_visibility_calculation_set(EINA_TRUE);
5244 cw->effect_running = 0;
5245 ret = _e_comp_object_animating_end(cw);
5247 if ((ret) && (end_cb_before))
5249 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5250 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5257 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5259 return a->pri - b->pri;
5262 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5263 E_API E_Comp_Object_Mover *
5264 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5266 E_Comp_Object_Mover *prov;
5268 prov = E_NEW(E_Comp_Object_Mover, 1);
5269 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5270 prov->func = provider;
5271 prov->data = (void*)data;
5274 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5275 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5280 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5282 EINA_SAFETY_ON_NULL_RETURN(prov);
5283 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5288 e_comp_object_effect_object_get(Evas_Object *obj)
5292 return cw->effect_obj;
5296 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5298 API_ENTRY EINA_FALSE;
5299 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5300 if (!cw->effect_set) return EINA_FALSE;
5307 ////////////////////////////////////
5310 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5312 if (e_comp->autoclose.obj)
5314 e_comp_ungrab_input(0, 1);
5315 if (e_comp->autoclose.del_cb)
5316 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5317 else if (!already_del)
5319 evas_object_hide(e_comp->autoclose.obj);
5320 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5322 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5324 e_comp->autoclose.obj = NULL;
5325 e_comp->autoclose.data = NULL;
5326 e_comp->autoclose.del_cb = NULL;
5327 e_comp->autoclose.key_cb = NULL;
5328 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5332 _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)
5334 _e_comp_object_autoclose_cleanup(0);
5338 _e_comp_object_autoclose_setup(Evas_Object *obj)
5340 if (!e_comp->autoclose.rect)
5342 /* create rect just below autoclose object to catch mouse events */
5343 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5344 evas_object_move(e_comp->autoclose.rect, 0, 0);
5345 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5346 evas_object_show(e_comp->autoclose.rect);
5347 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5348 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5349 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5350 e_comp_grab_input(0, 1);
5352 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5353 evas_object_focus_set(obj, 1);
5357 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5359 _e_comp_object_autoclose_setup(obj);
5360 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5364 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5366 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5367 _e_comp_object_autoclose_cleanup(1);
5368 if (e_client_focused_get()) return;
5370 E_Zone *zone = e_zone_current_get();
5373 e_zone_focus_reset(zone);
5377 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5381 if (e_comp->autoclose.obj)
5383 if (e_comp->autoclose.obj == obj) return;
5384 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5385 e_comp->autoclose.obj = obj;
5386 e_comp->autoclose.del_cb = del_cb;
5387 e_comp->autoclose.key_cb = cb;
5388 e_comp->autoclose.data = (void*)data;
5389 if (evas_object_visible_get(obj))
5390 _e_comp_object_autoclose_setup(obj);
5392 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5393 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5396 e_comp->autoclose.obj = obj;
5397 e_comp->autoclose.del_cb = del_cb;
5398 e_comp->autoclose.key_cb = cb;
5399 e_comp->autoclose.data = (void*)data;
5400 if (evas_object_visible_get(obj))
5401 _e_comp_object_autoclose_setup(obj);
5403 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5404 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5408 e_comp_object_is_animating(Evas_Object *obj)
5412 return cw->animating;
5416 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5420 if ((cw->external_content) &&
5421 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5423 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5424 "But current external content is %d object for %p.",
5425 cw->content_type, cw->ec);
5429 cw->user_alpha_set = EINA_TRUE;
5430 cw->user_alpha = alpha;
5432 if (!cw->obj) return;
5434 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5436 evas_object_image_alpha_set(cw->obj, alpha);
5438 if ((!cw->native) && (!cw->external_content))
5439 evas_object_image_data_set(cw->obj, NULL);
5443 e_comp_object_alpha_get(Evas_Object *obj)
5445 API_ENTRY EINA_FALSE;
5447 return evas_object_image_alpha_get(cw->obj);
5451 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5453 Eina_Bool mask_set = EINA_FALSE;
5457 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5458 if (cw->ec->input_only) return;
5465 o = evas_object_rectangle_add(e_comp->evas);
5466 evas_object_color_set(o, 0, 0, 0, 0);
5467 evas_object_clip_set(o, cw->clip);
5468 evas_object_smart_member_add(o, obj);
5469 evas_object_move(o, 0, 0);
5470 evas_object_resize(o, cw->w, cw->h);
5471 /* save render op value to restore when clear a mask.
5473 * NOTE: DO NOT change the render op on ec->frame while mask object
5474 * is set. it will overwrite the changed op value. */
5475 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5476 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5477 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5478 if (cw->visible) evas_object_show(o);
5481 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5482 ELOGF("COMP", " |mask_obj", cw->ec);
5483 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5490 evas_object_smart_member_del(cw->mask.obj);
5491 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5493 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5494 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5500 e_comp_object_mask_has(Evas_Object *obj)
5502 API_ENTRY EINA_FALSE;
5504 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5508 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5513 if ((cw->external_content) &&
5514 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5516 WRN("Can set up size to ONLY evas \"image\" object. "
5517 "But current external content is %d object for %p.",
5518 cw->content_type, cw->ec);
5522 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5524 evas_object_image_size_set(cw->obj, tw, th);
5528 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5530 Eina_Bool transform_set = EINA_FALSE;
5532 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5533 if (cw->ec->input_only) return;
5535 transform_set = !!set;
5539 if (!cw->transform_bg_obj)
5541 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5542 evas_object_move(o, 0, 0);
5543 evas_object_resize(o, 1, 1);
5544 if (cw->transform_bg_color.a >= 255)
5545 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5547 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5548 evas_object_color_set(o,
5549 cw->transform_bg_color.r,
5550 cw->transform_bg_color.g,
5551 cw->transform_bg_color.b,
5552 cw->transform_bg_color.a);
5553 if (cw->visible) evas_object_show(o);
5555 cw->transform_bg_obj = o;
5556 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5558 #ifdef REFACTOR_DESK_AREA
5559 e_comp_object_transform_obj_stack_update(obj);
5561 _e_comp_object_transform_obj_stack_update(obj);
5566 if (cw->transform_bg_obj)
5568 evas_object_smart_member_del(cw->transform_bg_obj);
5569 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5575 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5579 cw->transform_bg_color.r = r;
5580 cw->transform_bg_color.g = g;
5581 cw->transform_bg_color.b = b;
5582 cw->transform_bg_color.a = a;
5584 if (cw->transform_bg_obj)
5586 evas_object_color_set(cw->transform_bg_obj,
5587 cw->transform_bg_color.r,
5588 cw->transform_bg_color.g,
5589 cw->transform_bg_color.b,
5590 cw->transform_bg_color.a);
5595 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5598 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5599 if (cw->ec->input_only) return;
5600 if (!cw->transform_bg_obj) return;
5602 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5606 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5609 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5610 if (cw->ec->input_only) return;
5611 if (!cw->transform_bg_obj) return;
5613 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5617 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5619 Eina_Bool transform_set = EINA_FALSE;
5621 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5622 if (cw->ec->input_only) return;
5624 transform_set = !!set;
5628 if (!cw->transform_tranp_obj)
5630 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5631 evas_object_move(o, 0, 0);
5632 evas_object_resize(o, 1, 1);
5633 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5634 evas_object_color_set(o, 0, 0, 0, 0);
5635 if (cw->visible) evas_object_show(o);
5637 cw->transform_tranp_obj = o;
5638 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5639 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5640 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5642 #ifdef REFACTOR_DESK_AREA
5643 e_comp_object_transform_obj_stack_update(obj);
5645 _e_comp_object_transform_obj_stack_update(obj);
5650 if (cw->transform_tranp_obj)
5652 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5653 evas_object_smart_member_del(cw->transform_tranp_obj);
5654 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5660 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5663 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5664 if (cw->ec->input_only) return;
5665 if (!cw->transform_tranp_obj) return;
5667 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5671 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5674 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5675 if (cw->ec->input_only) return;
5676 if (!cw->transform_tranp_obj) return;
5678 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5681 #ifdef REFACTOR_DESK_AREA
5684 e_comp_object_layer_update(Evas_Object *obj,
5685 Evas_Object *above, Evas_Object *below)
5687 E_Comp_Object *cw2 = NULL;
5688 Evas_Object *o = NULL;
5693 if (cw->ec->layer_block) return;
5694 if ((above) && (below))
5696 ERR("Invalid layer update request! cw=%p", cw);
5704 layer = evas_object_layer_get(o);
5705 cw2 = evas_object_data_get(o, "comp_obj");
5708 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5710 o = evas_object_above_get(o);
5711 if ((!o) || (o == cw->smart_obj)) break;
5712 if (evas_object_layer_get(o) != layer)
5714 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5719 ec = e_client_top_get();
5720 if (ec) o = ec->frame;
5723 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5727 _e_comp_object_layers_remove(cw);
5730 if (cw2->layer > cw->layer)
5731 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5732 else if (cw2->layer == cw->layer)
5735 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5737 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5739 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5742 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5745 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5750 e_comp_object_layer_get(Evas_Object *obj)
5757 e_comp_object_content_set(Evas_Object *obj,
5758 Evas_Object *content,
5759 E_Comp_Object_Content_Type type)
5761 API_ENTRY EINA_FALSE;
5763 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5764 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5765 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5769 ERR("Can't set e.swallow.content to requested content. "
5770 "Previous comp object should not be changed at all.");
5774 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5776 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5777 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5779 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5780 type, content, cw->ec, cw->ec->pixmap);
5784 cw->external_content = EINA_TRUE;
5787 cw->content_type = type;
5788 e_util_size_debug_set(cw->obj, 1);
5789 evas_object_name_set(cw->obj, "cw->obj");
5790 _e_comp_object_alpha_set(cw);
5793 _e_comp_object_shadow_setup(cw);
5799 e_comp_object_content_unset(Evas_Object *obj)
5801 API_ENTRY EINA_FALSE;
5803 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5804 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5806 if (!cw->obj && !cw->ec->visible)
5808 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5812 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5814 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5820 if (cw->frame_object)
5821 edje_object_part_unswallow(cw->frame_object, cw->obj);
5823 edje_object_part_unswallow(cw->shobj, cw->obj);
5825 evas_object_del(cw->obj);
5826 evas_object_hide(cw->obj);
5830 cw->external_content = EINA_FALSE;
5831 if (cw->ec->is_cursor)
5834 DBG("%p is cursor surface..", cw->ec);
5835 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5837 evas_object_resize(cw->ec->frame, pw, ph);
5838 evas_object_hide(cw->ec->frame);
5843 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5844 cw->obj = evas_object_image_filled_add(e_comp->evas);
5845 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5846 e_util_size_debug_set(cw->obj, 1);
5847 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5848 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5849 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5850 evas_object_name_set(cw->obj, "cw->obj");
5851 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5852 _e_comp_object_alpha_set(cw);
5855 _e_comp_object_shadow_setup(cw);
5860 _e_comp_intercept_show_helper(cw);
5864 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5865 e_comp_object_dirty(cw->smart_obj);
5866 e_comp_object_render(cw->smart_obj);
5867 e_comp_object_render_update_add(obj);
5872 EINTERN Evas_Object *
5873 e_comp_object_content_get(Evas_Object *obj)
5877 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5879 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5881 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5888 E_API E_Comp_Object_Content_Type
5889 e_comp_object_content_type_get(Evas_Object *obj)
5891 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5893 return cw->content_type;
5897 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5900 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5901 E_Comp_Config *conf = e_comp_config_get();
5902 if (cw->ec->input_only) return;
5903 if (!conf->dim_rect_enable) return;
5905 cw->dim.mask_set = mask_set;
5911 if (!cw->dim.enable) return;
5912 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5916 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5918 Eina_Bool mask_set = EINA_FALSE;
5922 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5923 E_Comp_Config *conf = e_comp_config_get();
5924 if (cw->ec->input_only) return;
5925 if (!conf->dim_rect_enable) return;
5931 if (cw->dim.mask_obj)
5933 evas_object_smart_member_del(cw->dim.mask_obj);
5934 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5937 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);
5938 o = evas_object_rectangle_add(e_comp->evas);
5939 evas_object_color_set(o, 0, 0, 0, 0);
5940 evas_object_smart_member_add(o, obj);
5941 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5942 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5944 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5945 if (cw->visible) evas_object_show(o);
5947 cw->dim.mask_obj = o;
5948 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5950 evas_object_layer_set(cw->dim.mask_obj, 9998);
5954 if (cw->dim.mask_obj)
5956 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5957 evas_object_smart_member_del(cw->dim.mask_obj);
5958 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5964 e_comp_object_dim_client_set(E_Client *ec)
5966 E_Comp_Config *conf = e_comp_config_get();
5968 if (!conf->dim_rect_enable) return ;
5969 if (dim_client == ec) return;
5971 Eina_Bool prev_dim = EINA_FALSE;
5972 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5974 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5975 prev_dim = EINA_TRUE;
5977 if (prev_dim && dim_client->visible && ec)
5979 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5980 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5984 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5985 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5991 e_comp_object_dim_client_get(void)
5993 E_Comp_Config *conf = e_comp_config_get();
5995 if (!conf->dim_rect_enable ) return NULL;
6001 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6004 char emit[32] = "\0";
6005 E_Comp_Config *conf = e_comp_config_get();
6008 if (!conf->dim_rect_enable) return;
6009 if (!cw->effect_obj) return;
6010 if (enable == cw->dim.enable) return;
6012 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6013 if (noeffect || !conf->dim_rect_effect)
6015 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6019 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6022 cw->dim.enable = enable;
6024 if (cw->dim.mask_set && !enable)
6026 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6027 edje_object_signal_emit(cw->effect_obj, emit, "e");
6029 else if (cw->dim.mask_set && enable)
6031 edje_object_signal_emit(cw->effect_obj, emit, "e");
6032 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6036 edje_object_signal_emit(cw->effect_obj, emit, "e");
6041 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6043 API_ENTRY EINA_FALSE;
6044 E_Comp_Config *conf = e_comp_config_get();
6046 if (!ec) return EINA_FALSE;
6047 if (!conf->dim_rect_enable) return EINA_FALSE;
6049 if (cw->dim.enable) return EINA_TRUE;
6055 _e_comp_object_dim_update(E_Comp_Object *cw)
6057 E_Comp_Config *conf = e_comp_config_get();
6060 if (!conf->dim_rect_enable) return;
6061 if (!cw->effect_obj) return;
6064 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6065 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6067 if (cw->dim.mask_set)
6069 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6075 e_comp_object_clear(Evas_Object *obj)
6079 _e_comp_object_clear(cw);
6083 e_comp_object_hwc_update_exists(Evas_Object *obj)
6085 API_ENTRY EINA_FALSE;
6086 return cw->hwc_need_update;
6091 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6094 cw->hwc_need_update = set;
6098 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6100 API_ENTRY EINA_FALSE;
6101 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6105 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6108 if (cw->indicator.obj != indicator)
6109 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6110 cw->indicator.obj = indicator;
6111 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6115 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6118 if (cw->indicator.obj != indicator) return;
6119 cw->indicator.obj = NULL;
6120 edje_object_part_unswallow(cw->shobj, indicator);
6124 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6127 Edje_Message_Int_Set *msg;
6129 if (!cw->indicator.obj) return;
6131 cw->indicator.w = w;
6132 cw->indicator.h = h;
6134 if (!cw->shobj) return;
6136 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6140 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6141 edje_object_message_signal_process(cw->shobj);
6144 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6146 e_comp_object_map_update(Evas_Object *obj)
6149 E_Client *ec = cw->ec;
6150 E_Comp_Wl_Client_Data *cdata;
6152 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6155 int l, remain = sizeof buffer;
6158 if (e_object_is_del(E_OBJECT(ec))) return;
6159 cdata = e_client_cdata_get(ec);
6162 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6163 * when new buffer is attached.
6165 if (!cdata->buffer_ref.buffer) return;
6167 if ((!cw->redirected) ||
6168 (e_client_video_hw_composition_check(ec)) ||
6169 (!e_comp_wl_output_buffer_transform_get(ec) &&
6170 cdata->scaler.buffer_viewport.buffer.scale == 1))
6172 if (evas_object_map_enable_get(cw->effect_obj))
6174 ELOGF("TRANSFORM", "map: disable", cw->ec);
6175 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6176 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6177 evas_object_resize(cw->effect_obj, tw, th);
6184 EINA_SAFETY_ON_NULL_RETURN(map);
6186 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6192 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6194 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6195 e_map_point_image_uv_set(map, 0, x, y);
6196 l = snprintf(p, remain, "%d,%d", x, y);
6197 p += l, remain -= l;
6199 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6200 e_map_point_image_uv_set(map, 1, x, y);
6201 l = snprintf(p, remain, " %d,%d", x, y);
6202 p += l, remain -= l;
6204 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6205 e_map_point_image_uv_set(map, 2, x, y);
6206 l = snprintf(p, remain, " %d,%d", x, y);
6207 p += l, remain -= l;
6209 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6210 e_map_point_image_uv_set(map, 3, x, y);
6211 l = snprintf(p, remain, " %d,%d", x, y);
6212 p += l, remain -= l;
6214 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6216 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6218 e_comp_object_map_set(cw->effect_obj, map);
6219 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6223 /* if there's screen rotation with comp mode, then ec->effect_obj and
6224 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6226 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6227 evas_object_resize(cw->effect_obj, tw, th);
6231 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6233 API_ENTRY EINA_FALSE;
6235 cw->render_trace = set;
6241 e_comp_object_native_usable_get(Evas_Object *obj)
6243 API_ENTRY EINA_FALSE;
6244 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6246 if (cw->ec->input_only) return EINA_FALSE;
6247 if (cw->external_content) return EINA_FALSE;
6248 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6250 /* just return true value, if it is normal case */
6251 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6254 Evas_Native_Surface *ns;
6255 ns = evas_object_image_native_surface_get(cw->obj);
6257 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6260 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6268 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6270 API_ENTRY EINA_FALSE;
6271 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6272 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6273 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6275 if (cw->image_filter == filter) return EINA_TRUE;
6279 case E_COMP_IMAGE_FILTER_BLUR:
6280 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6282 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6283 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6285 case E_COMP_IMAGE_FILTER_INVERSE:
6286 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6288 case E_COMP_IMAGE_FILTER_NONE:
6290 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6294 cw->image_filter = filter;
6296 wl_signal_emit_mutable(&cw->events.image_filter_set, NULL);
6301 EINTERN E_Comp_Image_Filter
6302 e_comp_object_image_filter_get(Evas_Object *obj)
6304 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6305 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6306 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6307 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6309 return cw->image_filter;
6313 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6317 if (!_damage_trace) return;
6319 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6320 evas_object_del(obj);
6322 _damage_trace_post_objs = NULL;
6326 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6328 if (!_damage_trace) return;
6330 _damage_trace_post_objs = _damage_trace_objs;
6331 _damage_trace_objs = NULL;
6335 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6337 if (_damage_trace == onoff) return;
6341 evas_event_callback_add(e_comp->evas,
6342 EVAS_CALLBACK_RENDER_PRE,
6343 _e_comp_object_damage_trace_render_pre_cb,
6346 evas_event_callback_add(e_comp->evas,
6347 EVAS_CALLBACK_RENDER_POST,
6348 _e_comp_object_damage_trace_render_post_cb,
6355 EINA_LIST_FREE(_damage_trace_objs, obj)
6356 evas_object_del(obj);
6358 _damage_trace_objs = NULL;
6360 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6361 evas_object_del(obj);
6363 _damage_trace_post_objs = NULL;
6365 evas_event_callback_del(e_comp->evas,
6366 EVAS_CALLBACK_RENDER_PRE,
6367 _e_comp_object_damage_trace_render_pre_cb);
6369 evas_event_callback_del(e_comp->evas,
6370 EVAS_CALLBACK_RENDER_POST,
6371 _e_comp_object_damage_trace_render_post_cb);
6374 _damage_trace = onoff;
6378 e_comp_object_redirected_get(Evas_Object *obj)
6380 API_ENTRY EINA_FALSE;
6381 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6383 return cw->redirected;
6387 e_comp_object_color_visible_get(Evas_Object *obj)
6389 API_ENTRY EINA_FALSE;
6392 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6394 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6398 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6402 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6406 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6414 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6416 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6418 return e_map_set_to_comp_object(em, obj);
6422 e_comp_object_map_get(const Evas_Object *obj)
6424 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6426 return e_map_get_from_comp_object(obj);
6430 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6432 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6434 evas_object_map_enable_set(obj, enable);
6440 e_comp_object_render_update_lock(Evas_Object *obj)
6442 E_Comp_Wl_Buffer *buffer;
6443 struct wayland_tbm_client_queue *cqueue;
6445 API_ENTRY EINA_FALSE;
6447 if (cw->render_update_lock.lock == 0)
6449 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6451 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6452 if ((buffer) && (buffer->resource))
6454 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6456 wayland_tbm_server_client_queue_flush(cqueue);
6459 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6460 e_comp_object_render_update_del(obj);
6462 ELOGF("COMP", "Render update lock enabled", cw->ec);
6465 cw->render_update_lock.lock++;
6471 e_comp_object_render_update_unlock(Evas_Object *obj)
6475 if (cw->render_update_lock.lock == 0)
6478 cw->render_update_lock.lock--;
6480 if (cw->render_update_lock.lock == 0)
6483 if (cw->render_update_lock.pending_move_set)
6485 evas_object_move(obj,
6486 cw->render_update_lock.pending_move_x,
6487 cw->render_update_lock.pending_move_y);
6488 cw->render_update_lock.pending_move_x = 0;
6489 cw->render_update_lock.pending_move_y = 0;
6490 cw->render_update_lock.pending_move_set = EINA_FALSE;
6493 if (cw->render_update_lock.pending_resize_set)
6495 evas_object_resize(obj,
6496 cw->render_update_lock.pending_resize_w,
6497 cw->render_update_lock.pending_resize_h);
6498 cw->render_update_lock.pending_resize_w = 0;
6499 cw->render_update_lock.pending_resize_h = 0;
6500 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6503 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6505 if ((cw->ec->exp_iconify.buffer_flush) &&
6506 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6507 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6508 e_comp_object_clear(obj);
6510 e_comp_object_render_update_add(obj);
6512 ELOGF("COMP", "Render update lock disabled", cw->ec);
6517 e_comp_object_render_update_lock_get(Evas_Object *obj)
6519 API_ENTRY EINA_FALSE;
6521 if (cw->render_update_lock.lock > 0)
6528 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6532 if (cw->transparent.set)
6534 if (r) *r = cw->transparent.user_r;
6535 if (g) *g = cw->transparent.user_g;
6536 if (b) *b = cw->transparent.user_b;
6537 if (a) *a = cw->transparent.user_a;
6541 evas_object_color_get(obj, r, g, b, a);
6546 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6550 evas_object_render_op_set(cw->obj, op);
6552 wl_signal_emit_mutable(&cw->events.render_op_set, NULL);
6555 EINTERN Evas_Render_Op
6556 e_comp_object_render_op_get(Evas_Object *obj)
6558 API_ENTRY EVAS_RENDER_BLEND;
6560 return evas_object_render_op_get(cw->obj);
6564 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6567 wl_signal_add(&cw->events.lower, listener);
6570 #ifdef REFACTOR_DESK_AREA
6572 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6575 wl_signal_add(&cw->events.lower_done, listener);
6579 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6582 wl_signal_add(&cw->events.raise, listener);
6587 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6590 wl_signal_add(&cw->events.show, listener);
6594 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6597 wl_signal_add(&cw->events.hide, listener);
6600 #ifdef REFACTOR_DESK_AREA
6602 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6605 wl_signal_add(&cw->events.set_layer, listener);
6609 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6612 wl_signal_add(&cw->events.stack_above, listener);
6616 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6619 wl_signal_add(&cw->events.stack_below, listener);
6624 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6627 wl_signal_add(&cw->events.image_filter_set, listener);
6631 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6634 wl_signal_add(&cw->events.render_op_set, listener);