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);
3085 cw->smart_obj = obj;
3086 cw->x = cw->y = cw->w = cw->h = -1;
3087 evas_object_smart_data_set(obj, cw);
3088 cw->opacity = 255.0;
3089 cw->external_content = 0;
3090 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3091 cw->transform_bg_color.r = 0;
3092 cw->transform_bg_color.g = 0;
3093 cw->transform_bg_color.b = 0;
3094 cw->transform_bg_color.a = 255;
3095 evas_object_data_set(obj, "comp_obj", cw);
3096 evas_object_move(obj, -1, -1);
3097 /* intercept ALL the callbacks! */
3098 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3099 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3100 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3101 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3102 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3103 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3104 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3105 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3106 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3107 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3108 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3110 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3111 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3112 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3113 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3115 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3116 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3118 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3119 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3121 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3123 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3124 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3128 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3131 evas_object_color_set(cw->clip, r, g, b, a);
3132 evas_object_smart_callback_call(obj, "color_set", NULL);
3137 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3140 evas_object_clip_set(cw->clip, clip);
3144 _e_comp_smart_clip_unset(Evas_Object *obj)
3147 evas_object_clip_unset(cw->clip);
3151 _e_comp_smart_hide(Evas_Object *obj)
3153 TRACE_DS_BEGIN(COMP:SMART HIDE);
3158 evas_object_hide(cw->clip);
3159 if (cw->input_obj) evas_object_hide(cw->input_obj);
3160 evas_object_hide(cw->effect_obj);
3161 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3162 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3163 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3170 /* unset native surface if current displaying buffer was destroied */
3171 if (!cw->buffer_destroy_listener.notify)
3173 Evas_Native_Surface *ns;
3174 ns = evas_object_image_native_surface_get(cw->obj);
3175 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3176 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3179 if (!cw->ec->input_only)
3181 edje_object_freeze(cw->effect_obj);
3182 edje_object_freeze(cw->shobj);
3183 edje_object_play_set(cw->shobj, 0);
3184 if (cw->frame_object)
3185 edje_object_play_set(cw->frame_object, 0);
3188 e_comp_render_queue(); //force nocomp recheck
3194 _e_comp_smart_show(Evas_Object *obj)
3202 if ((cw->w < 0) || (cw->h < 0))
3203 CRI("ACK! ec:%p", cw->ec);
3205 TRACE_DS_BEGIN(COMP:SMART SHOW);
3207 e_comp_object_map_update(obj);
3209 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3210 evas_object_show(tmp->frame);
3212 evas_object_show(cw->clip);
3213 if (cw->input_obj) evas_object_show(cw->input_obj);
3214 if (!cw->ec->input_only)
3216 edje_object_thaw(cw->effect_obj);
3217 edje_object_thaw(cw->shobj);
3218 edje_object_play_set(cw->shobj, 1);
3219 if (cw->frame_object)
3220 edje_object_play_set(cw->frame_object, 1);
3222 evas_object_show(cw->effect_obj);
3223 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3224 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3225 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3226 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3227 e_comp_render_queue();
3228 if (cw->ec->input_only)
3233 if (cw->ec->iconic && (!cw->ec->new_client))
3235 if (e_client_is_iconified_by_client(cw->ec))
3237 ELOGF("COMP", "Set launching flag..", cw->ec);
3238 cw->ec->launching = EINA_TRUE;
3241 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3243 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3246 ELOGF("COMP", "Set launching flag..", cw->ec);
3247 cw->ec->launching = EINA_TRUE;
3249 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3250 _e_comp_object_animating_begin(cw);
3251 if (!_e_comp_object_effect_visibility_start(cw, 1))
3257 /* ensure some random effect doesn't lock the client offscreen */
3261 e_comp_object_effect_set(obj, NULL);
3264 _e_comp_object_dim_update(cw);
3270 _e_comp_smart_del(Evas_Object *obj)
3276 if (cw->buffer_destroy_listener.notify)
3278 wl_list_remove(&cw->buffer_destroy_listener.link);
3279 cw->buffer_destroy_listener.notify = NULL;
3282 if (cw->tbm_surface)
3284 tbm_surface_internal_unref(cw->tbm_surface);
3285 cw->tbm_surface = NULL;
3288 if (cw->render_update_lock.buffer_ref.buffer)
3290 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3291 cw->ec, cw->render_update_lock.lock);
3292 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3295 e_comp_object_render_update_del(cw->smart_obj);
3296 E_FREE_FUNC(cw->updates, eina_tiler_free);
3297 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3304 EINA_LIST_FREE(cw->obj_mirror, o)
3306 evas_object_image_data_set(o, NULL);
3307 evas_object_freeze_events_set(o, 1);
3308 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3312 #ifdef REFACTOR_DESK_AREA
3314 _e_comp_object_layers_remove(cw);
3316 l = evas_object_data_get(obj, "comp_object-to_del");
3317 E_FREE_LIST(l, evas_object_del);
3318 _e_comp_object_mouse_event_callback_unset(cw);
3319 evas_object_del(cw->clip);
3320 evas_object_del(cw->obj);
3321 evas_object_del(cw->shobj);
3322 evas_object_del(cw->effect_obj);
3323 evas_object_del(cw->frame_object);
3324 evas_object_del(cw->input_obj);
3325 evas_object_del(cw->mask.obj);
3326 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3327 evas_object_del(cw->transform_bg_obj);
3328 evas_object_del(cw->transform_tranp_obj);
3329 evas_object_del(cw->default_input_obj);
3330 eina_stringshare_del(cw->frame_theme);
3331 eina_stringshare_del(cw->frame_name);
3335 e_comp->animating--;
3337 e_object_unref(E_OBJECT(cw->ec));
3339 cw->ec->frame = NULL;
3344 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3348 cw->x = x, cw->y = y;
3349 evas_object_move(cw->effect_obj, x, y);
3350 evas_object_move(cw->default_input_obj, x, y);
3351 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3353 e_comp_object_map_update(obj);
3357 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3359 Eina_Bool first = EINA_FALSE;
3364 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3366 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3368 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3370 if (cw->w != w || cw->h != h)
3371 e_comp_object_map_update(obj);
3373 first = ((cw->w < 1) || (cw->h < 1));
3374 cw->w = w, cw->h = h;
3378 if (cw->frame_object)
3379 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3382 /* verify pixmap:object size */
3383 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3385 if ((ww != pw) || (hh != ph))
3386 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3388 evas_object_resize(cw->effect_obj, tw, th);
3389 evas_object_resize(cw->default_input_obj, w, h);
3391 evas_object_resize(cw->input_obj, w, h);
3393 evas_object_resize(cw->mask.obj, w, h);
3394 /* resize render update tiler */
3397 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3398 cw->updates_full = 0;
3399 if (cw->updates) eina_tiler_clear(cw->updates);
3403 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3404 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3412 e_comp_render_queue();
3418 _e_comp_smart_init(void)
3420 if (_e_comp_smart) return;
3422 static const Evas_Smart_Class sc =
3425 EVAS_SMART_CLASS_VERSION,
3429 _e_comp_smart_resize,
3432 _e_comp_smart_color_set,
3433 _e_comp_smart_clip_set,
3434 _e_comp_smart_clip_unset,
3444 _e_comp_smart = evas_smart_class_new(&sc);
3449 e_comp_object_init(void)
3451 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3452 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3453 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3454 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3458 e_comp_object_shutdown(void)
3464 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3466 API_ENTRY EINA_FALSE;
3467 return !!cw->force_visible;
3469 /////////////////////////////////////////////////////////
3472 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3475 Eina_Bool comp_object;
3477 comp_object = !!evas_object_data_get(obj, "comp_object");
3482 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3484 e_comp_render_queue();
3486 l = evas_object_data_get(obj, "comp_object-to_del");
3487 E_FREE_LIST(l, evas_object_del);
3491 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3493 if (e_comp_util_object_is_above_nocomp(obj) &&
3494 (!evas_object_data_get(obj, "comp_override")))
3496 evas_object_data_set(obj, "comp_override", (void*)1);
3497 e_comp_override_add();
3502 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3504 Eina_Bool ref = EINA_TRUE;
3505 if (evas_object_visible_get(obj))
3509 d = evas_object_data_del(obj, "comp_hiding");
3511 /* currently trying to hide */
3514 /* already visible */
3518 evas_object_show(obj);
3521 evas_object_ref(obj);
3522 evas_object_data_set(obj, "comp_ref", (void*)1);
3524 edje_object_signal_emit(obj, "e,state,visible", "e");
3525 evas_object_data_set(obj, "comp_showing", (void*)1);
3526 if (e_comp_util_object_is_above_nocomp(obj))
3528 evas_object_data_set(obj, "comp_override", (void*)1);
3529 e_comp_override_add();
3534 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3536 if (!evas_object_visible_get(obj)) return;
3537 /* already hiding */
3538 if (evas_object_data_get(obj, "comp_hiding")) return;
3539 if (!evas_object_data_del(obj, "comp_showing"))
3541 evas_object_ref(obj);
3542 evas_object_data_set(obj, "comp_ref", (void*)1);
3544 edje_object_signal_emit(obj, "e,state,hidden", "e");
3545 evas_object_data_set(obj, "comp_hiding", (void*)1);
3547 if (evas_object_data_del(obj, "comp_override"))
3548 e_comp_override_timed_pop();
3552 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3554 if (!e_util_strcmp(emission, "e,action,hide,done"))
3556 if (!evas_object_data_del(obj, "comp_hiding")) return;
3557 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3558 evas_object_hide(obj);
3559 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3562 evas_object_data_del(obj, "comp_showing");
3563 if (evas_object_data_del(obj, "comp_ref"))
3564 evas_object_unref(obj);
3568 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3574 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3578 E_API E_Comp_Object_Hook *
3579 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3581 E_Comp_Object_Hook *ch;
3583 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3584 ch = E_NEW(E_Comp_Object_Hook, 1);
3585 if (!ch) return NULL;
3586 ch->hookpoint = hookpoint;
3588 ch->data = (void*)data;
3589 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3594 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3597 if (_e_comp_object_hooks_walking == 0)
3599 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3603 _e_comp_object_hooks_delete++;
3606 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3607 E_API E_Comp_Object_Intercept_Hook *
3608 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3610 E_Comp_Object_Intercept_Hook *ch;
3612 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3613 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3614 if (!ch) return NULL;
3615 ch->hookpoint = hookpoint;
3617 ch->data = (void*)data;
3618 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3623 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3626 if (_e_comp_object_intercept_hooks_walking == 0)
3628 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3632 _e_comp_object_intercept_hooks_delete++;
3637 e_comp_object_util_add(Evas_Object *obj)
3641 E_Comp_Config *conf = e_comp_config_get();
3642 Eina_Bool skip = EINA_FALSE;
3648 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3650 name = evas_object_name_get(obj);
3651 vis = evas_object_visible_get(obj);
3652 o = edje_object_add(e_comp->evas);
3653 evas_object_data_set(o, "comp_object", (void*)1);
3655 skip = (!strncmp(name, "noshadow", 8));
3657 evas_object_data_set(o, "comp_object_skip", (void*)1);
3659 if (conf->shadow_style)
3661 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3662 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3665 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3666 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3667 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3669 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3671 evas_object_geometry_get(obj, &x, &y, &w, &h);
3672 evas_object_geometry_set(o, x, y, w, h);
3673 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3675 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3677 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3678 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3679 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3680 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3681 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3682 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3684 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3686 edje_object_part_swallow(o, "e.swallow.content", obj);
3688 _e_comp_object_event_add(o);
3691 evas_object_show(o);
3696 /* utility functions for deleting objects when their "owner" is deleted */
3698 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3703 EINA_SAFETY_ON_NULL_RETURN(to_del);
3704 l = evas_object_data_get(obj, "comp_object-to_del");
3705 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3706 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3707 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3711 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3716 EINA_SAFETY_ON_NULL_RETURN(to_del);
3717 l = evas_object_data_get(obj, "comp_object-to_del");
3719 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3722 /////////////////////////////////////////////////////////
3724 EINTERN Evas_Object *
3725 e_comp_object_client_add(E_Client *ec)
3730 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3731 if (ec->frame) return NULL;
3732 _e_comp_smart_init();
3733 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3734 cw = evas_object_smart_data_get(o);
3735 if (!cw) return NULL;
3736 evas_object_data_set(o, "E_Client", ec);
3739 evas_object_data_set(o, "comp_object", (void*)1);
3741 _e_comp_object_event_add(o);
3746 /* utility functions for getting client inset */
3748 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3751 if (!cw->client_inset.calc)
3757 if (ax) *ax = x - cw->client_inset.l;
3758 if (ay) *ay = y - cw->client_inset.t;
3762 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3765 if (!cw->client_inset.calc)
3771 if (ax) *ax = x + cw->client_inset.l;
3772 if (ay) *ay = y + cw->client_inset.t;
3776 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3779 if (!cw->client_inset.calc)
3785 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3786 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3790 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3793 if (!cw->client_inset.calc)
3799 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3800 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3804 e_comp_object_client_get(Evas_Object *obj)
3809 /* FIXME: remove this when eo is used */
3810 o = evas_object_data_get(obj, "comp_smart_obj");
3812 return e_comp_object_client_get(o);
3813 return cw ? cw->ec : NULL;
3817 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3820 if (cw->frame_extends)
3821 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3826 if (w) *w = cw->ec->w;
3827 if (h) *h = cw->ec->h;
3832 e_comp_object_util_zone_get(Evas_Object *obj)
3834 E_Zone *zone = NULL;
3838 zone = e_comp_zone_find_by_ec(cw->ec);
3843 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3844 zone = e_comp_zone_xy_get(x, y);
3850 e_comp_object_util_center(Evas_Object *obj)
3852 int x, y, w, h, ow, oh;
3857 zone = e_comp_object_util_zone_get(obj);
3858 EINA_SAFETY_ON_NULL_RETURN(zone);
3859 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3860 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3861 ow = cw->ec->w, oh = cw->ec->h;
3863 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3864 x = x + (w - ow) / 2;
3865 y = y + (h - oh) / 2;
3866 evas_object_move(obj, x, y);
3870 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3872 int x, y, w, h, ow, oh;
3875 EINA_SAFETY_ON_NULL_RETURN(on);
3876 evas_object_geometry_get(on, &x, &y, &w, &h);
3877 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3878 ow = cw->ec->w, oh = cw->ec->h;
3880 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3881 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3885 e_comp_object_util_fullscreen(Evas_Object *obj)
3890 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3893 evas_object_move(obj, 0, 0);
3894 evas_object_resize(obj, e_comp->w, e_comp->h);
3899 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3907 ow = cw->w, oh = cw->h;
3909 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3910 zone = e_comp_object_util_zone_get(obj);
3911 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3912 if (x) *x = zx + (zw - ow) / 2;
3913 if (y) *y = zy + (zh - oh) / 2;
3917 e_comp_object_input_objs_del(Evas_Object *obj)
3920 E_Input_Rect_Data *input_rect_data;
3921 E_Input_Rect_Smart_Data *input_rect_sd;
3926 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3927 if (!input_rect_sd) return;
3929 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3931 if (input_rect_data->obj)
3933 evas_object_smart_member_del(input_rect_data->obj);
3934 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3936 E_FREE(input_rect_data);
3941 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3944 E_Input_Rect_Data *input_rect_data = NULL;
3945 E_Input_Rect_Smart_Data *input_rect_sd;
3946 int client_w, client_h;
3948 if (cw->ec->client.w)
3949 client_w = cw->ec->client.w;
3951 client_w = cw->ec->w;
3953 if (cw->ec->client.h)
3954 client_h = cw->ec->client.h;
3956 client_h = cw->ec->h;
3958 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3962 _e_comp_input_obj_smart_init();
3963 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3964 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3965 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3968 input_rect_sd->cw = cw;
3971 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3974 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3975 if (input_rect_data)
3977 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3978 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3982 if ((input_rect_data) &&
3983 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3985 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3986 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3987 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3988 evas_object_clip_set(input_rect_data->obj, cw->clip);
3989 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3990 evas_object_geometry_set(input_rect_data->obj,
3991 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3992 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3993 evas_object_pass_events_set(cw->default_input_obj, 1);
3994 evas_object_pass_events_set(cw->obj, 1);
3997 evas_object_show(input_rect_data->obj);
3998 evas_object_show(cw->input_obj);
4003 evas_object_smart_member_del(cw->input_obj);
4004 E_FREE_FUNC(cw->input_obj, evas_object_del);
4005 evas_object_pass_events_set(cw->default_input_obj, 0);
4006 evas_object_pass_events_set(cw->obj, 0);
4011 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4014 E_Input_Rect_Smart_Data *input_rect_sd;
4015 E_Input_Rect_Data *input_rect_data;
4018 if (!cw->input_obj) return;
4020 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4023 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4025 *list = eina_list_append(*list, &input_rect_data->rect);
4031 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4034 if (l) *l = cw->client_inset.l;
4035 if (r) *r = cw->client_inset.r;
4036 if (t) *t = cw->client_inset.t;
4037 if (b) *b = cw->client_inset.b;
4040 /* set geometry for CSD */
4042 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4048 if (cw->frame_object)
4049 CRI("ACK! ec:%p", cw->ec);
4050 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4051 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4052 calc = cw->client_inset.calc;
4053 cw->client_inset.calc = l || r || t || b;
4054 eina_stringshare_replace(&cw->frame_theme, "borderless");
4055 if (cw->client_inset.calc)
4057 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4058 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4059 e_client_size_set(cw->ec, tw, th);
4061 else if (cw->ec->maximized || cw->ec->fullscreen)
4063 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4064 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4066 if (!cw->ec->new_client)
4068 if (calc && cw->client_inset.calc)
4070 tx = cw->ec->x - (l - cw->client_inset.l);
4071 ty = cw->ec->y - (t - cw->client_inset.t);
4072 e_client_pos_set(cw->ec, tx, ty);
4074 cw->ec->changes.pos = cw->ec->changes.size = 1;
4077 cw->client_inset.l = l;
4078 cw->client_inset.r = r;
4079 cw->client_inset.t = t;
4080 cw->client_inset.b = b;
4084 e_comp_object_frame_allowed(Evas_Object *obj)
4086 API_ENTRY EINA_FALSE;
4087 return (cw->frame_object || (!cw->client_inset.calc));
4091 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4093 API_ENTRY EINA_FALSE;
4094 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4095 eina_stringshare_replace(&cw->frame_name, name);
4096 if (cw->frame_object)
4097 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4102 e_comp_object_frame_exists(Evas_Object *obj)
4104 API_ENTRY EINA_FALSE;
4105 return !!cw->frame_object;
4109 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4111 Evas_Object *o, *pbg;
4114 Eina_Stringshare *theme;
4116 API_ENTRY EINA_FALSE;
4118 if (!e_util_strcmp(cw->frame_theme, name))
4119 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4120 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4121 return _e_comp_object_shadow_setup(cw);
4122 pbg = cw->frame_object;
4123 theme = eina_stringshare_add(name);
4125 if (cw->frame_object)
4129 w = cw->ec->w, h = cw->ec->h;
4130 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4131 if ((cw->ec->w != w) || (cw->ec->h != h))
4133 cw->ec->changes.size = 1;
4136 E_FREE_FUNC(cw->frame_object, evas_object_del);
4137 if (!name) goto reshadow;
4139 o = edje_object_add(e_comp->evas);
4140 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4141 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4142 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4144 cw->frame_object = NULL;
4146 eina_stringshare_del(cw->frame_theme);
4147 cw->frame_theme = theme;
4152 if (theme != e_config->theme_default_border_style)
4154 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4155 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4159 ok = e_theme_edje_object_set(o, "base/theme/border",
4160 "e/widgets/border/default/border");
4161 if (ok && (theme == e_config->theme_default_border_style))
4163 /* Reset default border style to default */
4164 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4165 e_config_save_queue();
4172 cw->frame_object = o;
4173 eina_stringshare_del(cw->frame_theme);
4174 cw->frame_theme = theme;
4175 evas_object_name_set(o, "cw->frame_object");
4178 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4182 cw->ec->changes.icon = 1;
4188 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4193 _e_comp_object_shadow_setup(cw);
4196 int old_x, old_y, new_x = 0, new_y = 0;
4198 old_x = cw->x, old_y = cw->y;
4200 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4202 new_x = cw->ec->x, new_y = cw->ec->y;
4203 else if (cw->ec->placed || (!cw->ec->new_client))
4205 /* if no previous frame:
4206 * - reapply client_inset
4211 if (cw->ec->changes.size)
4219 zone = e_comp_zone_find_by_ec(cw->ec);
4222 x = cw->ec->client.x, y = cw->ec->client.y;
4223 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4224 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4226 new_x = x, new_y = y;
4229 if (old_x != new_x || old_y != new_y)
4231 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4232 cw->y = cw->x = -99999;
4233 evas_object_move(obj, new_x, new_y);
4237 if (cw->ec->maximized)
4239 cw->ec->changes.need_maximize = 1;
4242 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4243 if (cw->frame_object)
4245 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4248 cw->frame_extends = 0;
4249 evas_object_del(pbg);
4254 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4256 E_Comp_Object_Mover *prov;
4259 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4260 edje_object_signal_emit(cw->shobj, sig, src);
4261 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4262 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4263 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4265 /* start with highest priority callback first */
4266 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4268 if (!e_util_glob_match(sig, prov->sig)) continue;
4269 if (prov->func(prov->data, obj, sig)) break;
4274 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4276 /* FIXME: at some point I guess this should use eo to inherit
4277 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4278 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4281 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4285 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4288 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4292 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4295 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4299 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4302 Eina_Rectangle rect;
4305 if (cw->ec->input_only || (!cw->updates)) return;
4306 if (cw->nocomp) return;
4307 rect.x = x, rect.y = y;
4308 rect.w = w, rect.h = h;
4309 evas_object_smart_callback_call(obj, "damage", &rect);
4311 if (e_comp_is_on_overlay(cw->ec))
4313 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4314 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4315 * E module attempts to block screen update due to the particular policy.
4317 if (e_pixmap_resource_get(cw->ec->pixmap))
4318 cw->hwc_need_update = EINA_TRUE;
4321 /* ignore overdraw */
4322 if (cw->updates_full)
4324 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4325 e_comp_object_render_update_add(obj);
4327 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4328 evas_object_show(cw->smart_obj);
4332 /* clip rect to client surface */
4333 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4334 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4335 /* if rect is the total size of the client after clip, clear the updates
4336 * since this is guaranteed to be the whole region anyway
4338 eina_tiler_area_size_get(cw->updates, &tw, &th);
4339 if ((w > tw) || (h > th))
4341 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4342 eina_tiler_clear(cw->updates);
4343 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4345 tw = cw->ec->client.w, th = cw->ec->client.h;
4347 if ((!x) && (!y) && (w == tw) && (h == th))
4349 eina_tiler_clear(cw->updates);
4350 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4351 cw->updates_full = 1;
4352 cw->update_count = 0;
4355 if (cw->update_count > UPDATE_MAX)
4357 /* this is going to get really dumb, so just update the whole thing */
4358 eina_tiler_clear(cw->updates);
4359 cw->update_count = cw->updates_full = 1;
4360 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4361 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4365 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4366 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4368 cw->updates_exist = 1;
4369 e_comp_object_render_update_add(obj);
4371 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4372 evas_object_show(cw->smart_obj);
4376 e_comp_object_damage_exists(Evas_Object *obj)
4378 API_ENTRY EINA_FALSE;
4379 return cw->updates_exist;
4383 e_comp_object_render_update_add(Evas_Object *obj)
4387 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4388 if (cw->render_update_lock.lock) return;
4389 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4393 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4395 e_comp_render_queue();
4399 e_comp_object_render_update_del(Evas_Object *obj)
4403 if (cw->ec->input_only || (!cw->updates)) return;
4404 if (!cw->update) return;
4406 /* this gets called during comp animating to clear the update flag */
4407 if (e_comp->grabbed) return;
4408 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4409 if (!e_comp->updates)
4411 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4412 if (e_comp->render_animator)
4413 ecore_animator_freeze(e_comp->render_animator);
4418 e_comp_object_shape_apply(Evas_Object *obj)
4422 unsigned int i, *pix, *p;
4426 if (!cw->ec) return; //NYI
4427 if (cw->external_content) return;
4430 if ((cw->ec->shape_rects_num >= 1) &&
4431 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4436 ERR("BUGGER: shape with native surface? cw=%p", cw);
4439 evas_object_image_size_get(cw->obj, &w, &h);
4440 if ((w < 1) || (h < 1)) return;
4443 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4444 _e_comp_object_alpha_set(cw);
4445 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4446 evas_object_image_alpha_set(o, 1);
4448 p = pix = evas_object_image_data_get(cw->obj, 1);
4451 evas_object_image_data_set(cw->obj, pix);
4456 unsigned char *spix, *sp;
4458 spix = calloc(w * h, sizeof(unsigned char));
4460 for (i = 0; i < cw->ec->shape_rects_num; i++)
4464 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4465 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4466 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4467 sp = spix + (w * ry) + rx;
4468 for (py = 0; py < rh; py++)
4470 for (px = 0; px < rw; px++)
4478 for (py = 0; py < h; py++)
4480 for (px = 0; px < w; px++)
4482 unsigned int mask, imask;
4484 mask = ((unsigned int)(*sp)) << 24;
4486 imask |= imask >> 8;
4487 imask |= imask >> 8;
4488 *p = mask | (*p & imask);
4489 //if (*sp) *p = 0xff000000 | *p;
4490 //else *p = 0x00000000;
4499 for (py = 0; py < h; py++)
4501 for (px = 0; px < w; px++)
4505 evas_object_image_data_set(cw->obj, pix);
4506 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4507 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4509 evas_object_image_data_set(o, pix);
4510 evas_object_image_data_update_add(o, 0, 0, w, h);
4512 // don't need to fix alpha chanel as blending
4513 // should be totally off here regardless of
4514 // alpha channel content
4518 _e_comp_object_clear(E_Comp_Object *cw)
4523 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4525 if (cw->render_update_lock.lock) return;
4528 e_pixmap_clear(cw->ec->pixmap);
4530 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4531 evas_object_image_size_set(cw->obj, 1, 1);
4532 evas_object_image_data_set(cw->obj, NULL);
4533 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4535 evas_object_image_size_set(o, 1, 1);
4536 evas_object_image_data_set(o, NULL);
4539 e_comp_object_render_update_del(cw->smart_obj);
4543 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4547 API_ENTRY EINA_FALSE;
4549 if (cw->transparent.set == set)
4554 evas_object_color_get(obj, &r, &g, &b, &a);
4555 evas_object_color_set(obj, 0, 0, 0, 0);
4557 cw->transparent.user_r = r;
4558 cw->transparent.user_g = g;
4559 cw->transparent.user_b = b;
4560 cw->transparent.user_a = a;
4562 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4564 cw->transparent.user_r,
4565 cw->transparent.user_g,
4566 cw->transparent.user_b,
4567 cw->transparent.user_a);
4569 cw->transparent.set = EINA_TRUE;
4573 cw->transparent.set = EINA_FALSE;
4575 evas_object_color_set(obj,
4576 cw->transparent.user_r,
4577 cw->transparent.user_g,
4578 cw->transparent.user_b,
4579 cw->transparent.user_a);
4581 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4583 cw->transparent.user_r,
4584 cw->transparent.user_g,
4585 cw->transparent.user_b,
4586 cw->transparent.user_a);
4592 /* helper function to simplify toggling of redirection for display servers which support it */
4594 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4599 if (cw->redirected == set) return;
4600 cw->redirected = set;
4601 if (cw->external_content) return;
4603 e_comp_object_map_update(obj);
4607 if (cw->updates_exist)
4608 e_comp_object_render_update_add(obj);
4610 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4612 _e_comp_object_transparent_set(obj, EINA_FALSE);
4613 evas_object_smart_callback_call(obj, "redirected", NULL);
4617 _e_comp_object_clear(cw);
4618 _e_comp_object_transparent_set(obj, EINA_TRUE);
4619 evas_object_smart_callback_call(obj, "unredirected", NULL);
4624 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4627 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4629 if (cw->buffer_destroy_listener.notify)
4631 cw->buffer_destroy_listener.notify = NULL;
4632 wl_list_remove(&cw->buffer_destroy_listener.link);
4635 if (e_object_is_del(E_OBJECT(cw->ec)))
4637 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4642 /* if it's current displaying buffer, do not remove its content */
4643 if (!evas_object_visible_get(cw->ec->frame))
4644 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4649 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4654 if (cw->buffer_destroy_listener.notify)
4656 wl_list_remove(&cw->buffer_destroy_listener.link);
4657 cw->buffer_destroy_listener.notify = NULL;
4660 if (cw->tbm_surface)
4662 tbm_surface_internal_unref(cw->tbm_surface);
4663 cw->tbm_surface = NULL;
4668 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4670 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4671 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4673 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4675 tbm_surface_internal_ref(ns->data.tbm.buffer);
4676 cw->tbm_surface = ns->data.tbm.buffer;
4680 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4681 evas_object_image_native_surface_set(cw->obj, ns);
4685 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4687 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4688 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4689 evas_object_image_native_surface_set(o, ns);
4696 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4698 Evas_Native_Surface ns;
4701 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4702 if (cw->ec->input_only) return;
4703 if (cw->external_content) return;
4704 if (cw->render_update_lock.lock) return;
4707 memset(&ns, 0, sizeof(Evas_Native_Surface));
4711 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4712 set = (!cw->ec->shaped);
4714 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4718 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4722 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4725 if (cw->ec->input_only) return;
4728 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4729 _e_comp_object_alpha_set(cw);
4731 e_comp_object_native_surface_set(obj, cw->native);
4732 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4736 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4742 if (cw->blanked == set) return;
4744 _e_comp_object_alpha_set(cw);
4747 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4748 evas_object_image_data_set(cw->obj, NULL);
4752 e_comp_object_native_surface_set(obj, 1);
4753 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4757 _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)
4762 if (!_damage_trace) return;
4766 if (!evas_object_visible_get(cw->obj)) return;
4768 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4770 o = evas_object_rectangle_add(e_comp->evas);
4771 evas_object_layer_set(o, E_LAYER_MAX);
4772 evas_object_name_set(o, "damage_trace");
4773 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4774 evas_object_resize(o, dmg_w, dmg_h);
4775 evas_object_color_set(o, 0, 128, 0, 128);
4776 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4777 evas_object_pass_events_set(o, EINA_TRUE);
4778 evas_object_show(o);
4780 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4782 dmg_w, dmg_h, dmg_x, dmg_y,
4783 origin->w, origin->h, origin->x, origin->y);
4785 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4788 /* mark an object as dirty and setup damages */
4790 e_comp_object_dirty(Evas_Object *obj)
4793 Eina_Rectangle *rect;
4797 Eina_Bool dirty, visible;
4801 if (cw->external_content) return;
4802 if (!cw->redirected) return;
4803 if (cw->render_update_lock.lock)
4805 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4808 /* only actually dirty if pixmap is available */
4809 if (!e_pixmap_resource_get(cw->ec->pixmap))
4811 // e_pixmap_size_get returns last attached buffer size
4812 // eventhough it is destroyed
4813 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4816 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4817 visible = cw->visible;
4818 if (!dirty) w = h = 1;
4819 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4821 evas_object_image_data_set(cw->obj, NULL);
4822 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4823 evas_object_image_size_set(cw->obj, tw, th);
4824 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4825 if (cw->pending_updates)
4826 eina_tiler_area_size_set(cw->pending_updates, w, h);
4827 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4829 evas_object_image_pixels_dirty_set(o, dirty);
4831 evas_object_image_data_set(o, NULL);
4832 evas_object_image_size_set(o, tw, th);
4833 visible |= evas_object_visible_get(o);
4837 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4841 e_comp_object_native_surface_set(obj, 1);
4843 m = _e_comp_object_map_damage_transform_get(cw->ec);
4844 it = eina_tiler_iterator_new(cw->updates);
4845 EINA_ITERATOR_FOREACH(it, rect)
4847 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4848 * of evas engine and doesn't convert damage according to evas_map.
4849 * so damage of evas_object_image use surface coordinate.
4853 int damage_x, damage_y, damage_w, damage_h;
4855 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4856 &damage_x, &damage_y, &damage_w, &damage_h);
4857 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4858 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4862 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4863 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4866 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4867 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4868 if (cw->pending_updates)
4869 eina_tiler_rect_add(cw->pending_updates, rect);
4871 eina_iterator_free(it);
4872 if (m) e_map_free(m);
4873 if (cw->pending_updates)
4874 eina_tiler_clear(cw->updates);
4877 cw->pending_updates = cw->updates;
4878 cw->updates = eina_tiler_new(w, h);
4879 eina_tiler_tile_size_set(cw->updates, 1, 1);
4881 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4882 evas_object_smart_callback_call(obj, "dirty", NULL);
4883 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4884 /* force render if main object is hidden but mirrors are visible */
4885 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4886 e_comp_object_render(obj);
4890 e_comp_object_render(Evas_Object *obj)
4897 API_ENTRY EINA_FALSE;
4899 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4900 if (cw->ec->input_only) return EINA_TRUE;
4901 if (cw->external_content) return EINA_TRUE;
4902 if (cw->native) return EINA_FALSE;
4903 /* if comp object is not redirected state, comp object should not be set by newly committed data
4904 because image size of comp object is 1x1 and it should not be shown on canvas */
4905 if (!cw->redirected) return EINA_TRUE;
4906 if (cw->render_update_lock.lock)
4908 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4911 e_comp_object_render_update_del(obj);
4912 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4914 if (!cw->pending_updates)
4916 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4917 evas_object_image_data_set(cw->obj, NULL);
4918 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4919 evas_object_image_data_set(o, NULL);
4923 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4925 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4927 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4930 e_pixmap_image_refresh(cw->ec->pixmap);
4931 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4934 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4935 e_pixmap_image_data_ref(cw->ec->pixmap);
4937 /* set pixel data */
4938 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4939 _e_comp_object_alpha_set(cw);
4940 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4942 evas_object_image_data_set(o, pix);
4943 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4944 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4947 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4949 e_comp_client_post_update_add(cw->ec);
4954 /* create a duplicate of an evas object */
4956 e_comp_object_util_mirror_add(Evas_Object *obj)
4960 unsigned int *pix = NULL;
4961 Eina_Bool argb = EINA_FALSE;
4966 cw = evas_object_data_get(obj, "comp_mirror");
4969 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4970 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4971 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4972 evas_object_image_alpha_set(o, 1);
4973 evas_object_image_source_set(o, obj);
4976 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4977 if (cw->external_content)
4979 ERR("%p of client %p is external content.", obj, cw->ec);
4982 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4983 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4984 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4985 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4986 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4987 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4988 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4989 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4990 evas_object_data_set(o, "comp_mirror", cw);
4992 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4993 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4995 evas_object_image_size_set(o, tw, th);
4998 pix = evas_object_image_data_get(cw->obj, 0);
5004 evas_object_image_native_surface_set(o, cw->ns);
5007 Evas_Native_Surface ns;
5008 memset(&ns, 0, sizeof(Evas_Native_Surface));
5009 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5010 evas_object_image_native_surface_set(o, &ns);
5015 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5016 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5018 (e_pixmap_image_exists(cw->ec->pixmap)))
5019 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5021 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5028 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5029 evas_object_image_pixels_dirty_set(o, dirty);
5030 evas_object_image_data_set(o, pix);
5031 evas_object_image_data_set(cw->obj, pix);
5033 evas_object_image_data_update_add(o, 0, 0, tw, th);
5038 //////////////////////////////////////////////////////
5041 e_comp_object_effect_allowed_get(Evas_Object *obj)
5043 API_ENTRY EINA_FALSE;
5045 if (!cw->shobj) return EINA_FALSE;
5046 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5047 return !e_comp_config_get()->match.disable_borders;
5050 /* setup an api effect for a client */
5052 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5055 Eina_Stringshare *grp;
5056 E_Comp_Config *config;
5057 Eina_Bool loaded = EINA_FALSE;
5059 API_ENTRY EINA_FALSE;
5060 if (!cw->shobj) return EINA_FALSE; //input window
5062 if (!effect) effect = "none";
5063 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5065 config = e_comp_config_get();
5066 if ((config) && (config->effect_file))
5068 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5070 cw->effect_set = EINA_TRUE;
5077 edje_object_file_get(cw->effect_obj, NULL, &grp);
5078 cw->effect_set = !eina_streq(effect, "none");
5079 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5080 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5082 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5083 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5084 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5086 if (cw->effect_running)
5088 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5091 cw->effect_set = EINA_FALSE;
5092 return cw->effect_set;
5096 if (cw->effect_running)
5098 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5101 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5102 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5103 if (cw->effect_clip)
5105 evas_object_clip_unset(cw->clip);
5106 cw->effect_clip = 0;
5108 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5110 _e_comp_object_dim_update(cw);
5112 return cw->effect_set;
5115 /* set params for embryo scripts in effect */
5117 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5119 Edje_Message_Int_Set *msg;
5123 EINA_SAFETY_ON_NULL_RETURN(params);
5124 EINA_SAFETY_ON_FALSE_RETURN(count);
5125 if (!cw->effect_set) return;
5127 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5128 msg->count = (int)count;
5129 for (x = 0; x < count; x++)
5130 msg->val[x] = params[x];
5131 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5132 edje_object_message_signal_process(cw->effect_obj);
5136 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5138 Edje_Signal_Cb end_cb;
5140 E_Comp_Object *cw = data;
5142 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5143 cw->effect_running = 0;
5144 if (!_e_comp_object_animating_end(cw)) return;
5146 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5148 evas_object_data_del(cw->smart_obj, "effect_running");
5149 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5150 e_comp_visibility_calculation_set(EINA_TRUE);
5153 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5154 if (!end_cb) return;
5155 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5156 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5157 end_cb(end_data, cw->smart_obj, emission, source);
5160 /* clip effect to client's zone */
5162 e_comp_object_effect_clip(Evas_Object *obj)
5166 zone = e_comp_zone_find_by_ec(cw->ec);
5168 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5169 if (!cw->effect_clip_able) return;
5170 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5171 cw->effect_clip = 1;
5174 /* unclip effect from client's zone */
5176 e_comp_object_effect_unclip(Evas_Object *obj)
5179 if (!cw->effect_clip) return;
5180 evas_object_clip_unset(cw->smart_obj);
5181 cw->effect_clip = 0;
5184 /* start effect, running end_cb after */
5186 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5188 API_ENTRY EINA_FALSE;
5189 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5190 if (!cw->effect_set) return EINA_FALSE;
5192 if (cw->effect_running)
5194 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5197 e_comp_object_effect_clip(obj);
5198 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5200 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5201 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5202 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5203 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5205 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5206 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5208 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5209 _e_comp_object_animating_begin(cw);
5210 cw->effect_running = 1;
5214 /* stop a currently-running effect immediately */
5216 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5219 Edje_Signal_Cb end_cb_before = NULL;
5220 void *end_data_before = NULL;
5221 API_ENTRY EINA_FALSE;
5223 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5224 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5226 if (end_cb_before != end_cb) return EINA_TRUE;
5227 e_comp_object_effect_unclip(obj);
5228 if (cw->effect_clip)
5230 evas_object_clip_unset(cw->effect_obj);
5231 cw->effect_clip = 0;
5233 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5234 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5236 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5238 evas_object_data_del(cw->smart_obj, "effect_running");
5239 e_comp_visibility_calculation_set(EINA_TRUE);
5242 cw->effect_running = 0;
5243 ret = _e_comp_object_animating_end(cw);
5245 if ((ret) && (end_cb_before))
5247 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5248 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5255 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5257 return a->pri - b->pri;
5260 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5261 E_API E_Comp_Object_Mover *
5262 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5264 E_Comp_Object_Mover *prov;
5266 prov = E_NEW(E_Comp_Object_Mover, 1);
5267 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5268 prov->func = provider;
5269 prov->data = (void*)data;
5272 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5273 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5278 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5280 EINA_SAFETY_ON_NULL_RETURN(prov);
5281 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5286 e_comp_object_effect_object_get(Evas_Object *obj)
5290 return cw->effect_obj;
5294 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5296 API_ENTRY EINA_FALSE;
5297 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5298 if (!cw->effect_set) return EINA_FALSE;
5305 ////////////////////////////////////
5308 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5310 if (e_comp->autoclose.obj)
5312 e_comp_ungrab_input(0, 1);
5313 if (e_comp->autoclose.del_cb)
5314 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5315 else if (!already_del)
5317 evas_object_hide(e_comp->autoclose.obj);
5318 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5320 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5322 e_comp->autoclose.obj = NULL;
5323 e_comp->autoclose.data = NULL;
5324 e_comp->autoclose.del_cb = NULL;
5325 e_comp->autoclose.key_cb = NULL;
5326 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5330 _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)
5332 _e_comp_object_autoclose_cleanup(0);
5336 _e_comp_object_autoclose_setup(Evas_Object *obj)
5338 if (!e_comp->autoclose.rect)
5340 /* create rect just below autoclose object to catch mouse events */
5341 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5342 evas_object_move(e_comp->autoclose.rect, 0, 0);
5343 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5344 evas_object_show(e_comp->autoclose.rect);
5345 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5346 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5347 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5348 e_comp_grab_input(0, 1);
5350 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5351 evas_object_focus_set(obj, 1);
5355 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5357 _e_comp_object_autoclose_setup(obj);
5358 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5362 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5364 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5365 _e_comp_object_autoclose_cleanup(1);
5366 if (e_client_focused_get()) return;
5368 E_Zone *zone = e_zone_current_get();
5371 e_zone_focus_reset(zone);
5375 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5379 if (e_comp->autoclose.obj)
5381 if (e_comp->autoclose.obj == obj) return;
5382 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5383 e_comp->autoclose.obj = obj;
5384 e_comp->autoclose.del_cb = del_cb;
5385 e_comp->autoclose.key_cb = cb;
5386 e_comp->autoclose.data = (void*)data;
5387 if (evas_object_visible_get(obj))
5388 _e_comp_object_autoclose_setup(obj);
5390 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5391 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5394 e_comp->autoclose.obj = obj;
5395 e_comp->autoclose.del_cb = del_cb;
5396 e_comp->autoclose.key_cb = cb;
5397 e_comp->autoclose.data = (void*)data;
5398 if (evas_object_visible_get(obj))
5399 _e_comp_object_autoclose_setup(obj);
5401 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5402 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5406 e_comp_object_is_animating(Evas_Object *obj)
5410 return cw->animating;
5414 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5418 if ((cw->external_content) &&
5419 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5421 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5422 "But current external content is %d object for %p.",
5423 cw->content_type, cw->ec);
5427 cw->user_alpha_set = EINA_TRUE;
5428 cw->user_alpha = alpha;
5430 if (!cw->obj) return;
5432 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5434 evas_object_image_alpha_set(cw->obj, alpha);
5436 if ((!cw->native) && (!cw->external_content))
5437 evas_object_image_data_set(cw->obj, NULL);
5441 e_comp_object_alpha_get(Evas_Object *obj)
5443 API_ENTRY EINA_FALSE;
5445 return evas_object_image_alpha_get(cw->obj);
5449 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5451 Eina_Bool mask_set = EINA_FALSE;
5455 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5456 if (cw->ec->input_only) return;
5463 o = evas_object_rectangle_add(e_comp->evas);
5464 evas_object_color_set(o, 0, 0, 0, 0);
5465 evas_object_clip_set(o, cw->clip);
5466 evas_object_smart_member_add(o, obj);
5467 evas_object_move(o, 0, 0);
5468 evas_object_resize(o, cw->w, cw->h);
5469 /* save render op value to restore when clear a mask.
5471 * NOTE: DO NOT change the render op on ec->frame while mask object
5472 * is set. it will overwrite the changed op value. */
5473 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5474 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5475 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5476 if (cw->visible) evas_object_show(o);
5479 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5480 ELOGF("COMP", " |mask_obj", cw->ec);
5481 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5488 evas_object_smart_member_del(cw->mask.obj);
5489 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5491 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5492 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5498 e_comp_object_mask_has(Evas_Object *obj)
5500 API_ENTRY EINA_FALSE;
5502 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5506 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5511 if ((cw->external_content) &&
5512 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5514 WRN("Can set up size to ONLY evas \"image\" object. "
5515 "But current external content is %d object for %p.",
5516 cw->content_type, cw->ec);
5520 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5522 evas_object_image_size_set(cw->obj, tw, th);
5526 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5528 Eina_Bool transform_set = EINA_FALSE;
5530 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5531 if (cw->ec->input_only) return;
5533 transform_set = !!set;
5537 if (!cw->transform_bg_obj)
5539 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5540 evas_object_move(o, 0, 0);
5541 evas_object_resize(o, 1, 1);
5542 if (cw->transform_bg_color.a >= 255)
5543 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5545 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5546 evas_object_color_set(o,
5547 cw->transform_bg_color.r,
5548 cw->transform_bg_color.g,
5549 cw->transform_bg_color.b,
5550 cw->transform_bg_color.a);
5551 if (cw->visible) evas_object_show(o);
5553 cw->transform_bg_obj = o;
5554 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5556 #ifdef REFACTOR_DESK_AREA
5557 e_comp_object_transform_obj_stack_update(obj);
5559 _e_comp_object_transform_obj_stack_update(obj);
5564 if (cw->transform_bg_obj)
5566 evas_object_smart_member_del(cw->transform_bg_obj);
5567 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5573 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5577 cw->transform_bg_color.r = r;
5578 cw->transform_bg_color.g = g;
5579 cw->transform_bg_color.b = b;
5580 cw->transform_bg_color.a = a;
5582 if (cw->transform_bg_obj)
5584 evas_object_color_set(cw->transform_bg_obj,
5585 cw->transform_bg_color.r,
5586 cw->transform_bg_color.g,
5587 cw->transform_bg_color.b,
5588 cw->transform_bg_color.a);
5593 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5596 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5597 if (cw->ec->input_only) return;
5598 if (!cw->transform_bg_obj) return;
5600 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5604 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5607 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5608 if (cw->ec->input_only) return;
5609 if (!cw->transform_bg_obj) return;
5611 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5615 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5617 Eina_Bool transform_set = EINA_FALSE;
5619 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5620 if (cw->ec->input_only) return;
5622 transform_set = !!set;
5626 if (!cw->transform_tranp_obj)
5628 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5629 evas_object_move(o, 0, 0);
5630 evas_object_resize(o, 1, 1);
5631 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5632 evas_object_color_set(o, 0, 0, 0, 0);
5633 if (cw->visible) evas_object_show(o);
5635 cw->transform_tranp_obj = o;
5636 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5637 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5638 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5640 #ifdef REFACTOR_DESK_AREA
5641 e_comp_object_transform_obj_stack_update(obj);
5643 _e_comp_object_transform_obj_stack_update(obj);
5648 if (cw->transform_tranp_obj)
5650 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5651 evas_object_smart_member_del(cw->transform_tranp_obj);
5652 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5658 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5661 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5662 if (cw->ec->input_only) return;
5663 if (!cw->transform_tranp_obj) return;
5665 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5669 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5672 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5673 if (cw->ec->input_only) return;
5674 if (!cw->transform_tranp_obj) return;
5676 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5679 #ifdef REFACTOR_DESK_AREA
5682 e_comp_object_layer_update(Evas_Object *obj,
5683 Evas_Object *above, Evas_Object *below)
5685 E_Comp_Object *cw2 = NULL;
5686 Evas_Object *o = NULL;
5691 if (cw->ec->layer_block) return;
5692 if ((above) && (below))
5694 ERR("Invalid layer update request! cw=%p", cw);
5702 layer = evas_object_layer_get(o);
5703 cw2 = evas_object_data_get(o, "comp_obj");
5706 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5708 o = evas_object_above_get(o);
5709 if ((!o) || (o == cw->smart_obj)) break;
5710 if (evas_object_layer_get(o) != layer)
5712 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5717 ec = e_client_top_get();
5718 if (ec) o = ec->frame;
5721 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5725 _e_comp_object_layers_remove(cw);
5728 if (cw2->layer > cw->layer)
5729 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5730 else if (cw2->layer == cw->layer)
5733 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5735 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5737 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5740 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5743 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5748 e_comp_object_layer_get(Evas_Object *obj)
5755 e_comp_object_content_set(Evas_Object *obj,
5756 Evas_Object *content,
5757 E_Comp_Object_Content_Type type)
5759 API_ENTRY EINA_FALSE;
5761 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5762 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5763 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5767 ERR("Can't set e.swallow.content to requested content. "
5768 "Previous comp object should not be changed at all.");
5772 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5774 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5775 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5777 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5778 type, content, cw->ec, cw->ec->pixmap);
5782 cw->external_content = EINA_TRUE;
5785 cw->content_type = type;
5786 e_util_size_debug_set(cw->obj, 1);
5787 evas_object_name_set(cw->obj, "cw->obj");
5788 _e_comp_object_alpha_set(cw);
5791 _e_comp_object_shadow_setup(cw);
5797 e_comp_object_content_unset(Evas_Object *obj)
5799 API_ENTRY EINA_FALSE;
5801 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5802 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5804 if (!cw->obj && !cw->ec->visible)
5806 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5810 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5812 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5818 if (cw->frame_object)
5819 edje_object_part_unswallow(cw->frame_object, cw->obj);
5821 edje_object_part_unswallow(cw->shobj, cw->obj);
5823 evas_object_del(cw->obj);
5824 evas_object_hide(cw->obj);
5828 cw->external_content = EINA_FALSE;
5829 if (cw->ec->is_cursor)
5832 DBG("%p is cursor surface..", cw->ec);
5833 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5835 evas_object_resize(cw->ec->frame, pw, ph);
5836 evas_object_hide(cw->ec->frame);
5841 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5842 cw->obj = evas_object_image_filled_add(e_comp->evas);
5843 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5844 e_util_size_debug_set(cw->obj, 1);
5845 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5846 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5847 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5848 evas_object_name_set(cw->obj, "cw->obj");
5849 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5850 _e_comp_object_alpha_set(cw);
5853 _e_comp_object_shadow_setup(cw);
5858 _e_comp_intercept_show_helper(cw);
5862 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5863 e_comp_object_dirty(cw->smart_obj);
5864 e_comp_object_render(cw->smart_obj);
5865 e_comp_object_render_update_add(obj);
5870 EINTERN Evas_Object *
5871 e_comp_object_content_get(Evas_Object *obj)
5875 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5877 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5879 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5886 E_API E_Comp_Object_Content_Type
5887 e_comp_object_content_type_get(Evas_Object *obj)
5889 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5891 return cw->content_type;
5895 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5898 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5899 E_Comp_Config *conf = e_comp_config_get();
5900 if (cw->ec->input_only) return;
5901 if (!conf->dim_rect_enable) return;
5903 cw->dim.mask_set = mask_set;
5909 if (!cw->dim.enable) return;
5910 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5914 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5916 Eina_Bool mask_set = EINA_FALSE;
5920 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5921 E_Comp_Config *conf = e_comp_config_get();
5922 if (cw->ec->input_only) return;
5923 if (!conf->dim_rect_enable) return;
5929 if (cw->dim.mask_obj)
5931 evas_object_smart_member_del(cw->dim.mask_obj);
5932 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5935 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);
5936 o = evas_object_rectangle_add(e_comp->evas);
5937 evas_object_color_set(o, 0, 0, 0, 0);
5938 evas_object_smart_member_add(o, obj);
5939 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5940 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5942 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5943 if (cw->visible) evas_object_show(o);
5945 cw->dim.mask_obj = o;
5946 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5948 evas_object_layer_set(cw->dim.mask_obj, 9998);
5952 if (cw->dim.mask_obj)
5954 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5955 evas_object_smart_member_del(cw->dim.mask_obj);
5956 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5962 e_comp_object_dim_client_set(E_Client *ec)
5964 E_Comp_Config *conf = e_comp_config_get();
5966 if (!conf->dim_rect_enable) return ;
5967 if (dim_client == ec) return;
5969 Eina_Bool prev_dim = EINA_FALSE;
5970 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5972 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5973 prev_dim = EINA_TRUE;
5975 if (prev_dim && dim_client->visible && ec)
5977 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5978 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5982 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5983 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5989 e_comp_object_dim_client_get(void)
5991 E_Comp_Config *conf = e_comp_config_get();
5993 if (!conf->dim_rect_enable ) return NULL;
5999 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6002 char emit[32] = "\0";
6003 E_Comp_Config *conf = e_comp_config_get();
6006 if (!conf->dim_rect_enable) return;
6007 if (!cw->effect_obj) return;
6008 if (enable == cw->dim.enable) return;
6010 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6011 if (noeffect || !conf->dim_rect_effect)
6013 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6017 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6020 cw->dim.enable = enable;
6022 if (cw->dim.mask_set && !enable)
6024 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6025 edje_object_signal_emit(cw->effect_obj, emit, "e");
6027 else if (cw->dim.mask_set && enable)
6029 edje_object_signal_emit(cw->effect_obj, emit, "e");
6030 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6034 edje_object_signal_emit(cw->effect_obj, emit, "e");
6039 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6041 API_ENTRY EINA_FALSE;
6042 E_Comp_Config *conf = e_comp_config_get();
6044 if (!ec) return EINA_FALSE;
6045 if (!conf->dim_rect_enable) return EINA_FALSE;
6047 if (cw->dim.enable) return EINA_TRUE;
6053 _e_comp_object_dim_update(E_Comp_Object *cw)
6055 E_Comp_Config *conf = e_comp_config_get();
6058 if (!conf->dim_rect_enable) return;
6059 if (!cw->effect_obj) return;
6062 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6063 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6065 if (cw->dim.mask_set)
6067 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6073 e_comp_object_clear(Evas_Object *obj)
6077 _e_comp_object_clear(cw);
6081 e_comp_object_hwc_update_exists(Evas_Object *obj)
6083 API_ENTRY EINA_FALSE;
6084 return cw->hwc_need_update;
6089 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6092 cw->hwc_need_update = set;
6096 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6098 API_ENTRY EINA_FALSE;
6099 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6103 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6106 if (cw->indicator.obj != indicator)
6107 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6108 cw->indicator.obj = indicator;
6109 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6113 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6116 if (cw->indicator.obj != indicator) return;
6117 cw->indicator.obj = NULL;
6118 edje_object_part_unswallow(cw->shobj, indicator);
6122 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6125 Edje_Message_Int_Set *msg;
6127 if (!cw->indicator.obj) return;
6129 cw->indicator.w = w;
6130 cw->indicator.h = h;
6132 if (!cw->shobj) return;
6134 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6138 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6139 edje_object_message_signal_process(cw->shobj);
6142 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6144 e_comp_object_map_update(Evas_Object *obj)
6147 E_Client *ec = cw->ec;
6148 E_Comp_Wl_Client_Data *cdata;
6150 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6153 int l, remain = sizeof buffer;
6156 if (e_object_is_del(E_OBJECT(ec))) return;
6157 cdata = e_client_cdata_get(ec);
6160 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6161 * when new buffer is attached.
6163 if (!cdata->buffer_ref.buffer) return;
6165 if ((!cw->redirected) ||
6166 (e_client_video_hw_composition_check(ec)) ||
6167 (!e_comp_wl_output_buffer_transform_get(ec) &&
6168 cdata->scaler.buffer_viewport.buffer.scale == 1))
6170 if (evas_object_map_enable_get(cw->effect_obj))
6172 ELOGF("TRANSFORM", "map: disable", cw->ec);
6173 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6174 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6175 evas_object_resize(cw->effect_obj, tw, th);
6182 EINA_SAFETY_ON_NULL_RETURN(map);
6184 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6190 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6192 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6193 e_map_point_image_uv_set(map, 0, x, y);
6194 l = snprintf(p, remain, "%d,%d", x, y);
6195 p += l, remain -= l;
6197 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6198 e_map_point_image_uv_set(map, 1, x, y);
6199 l = snprintf(p, remain, " %d,%d", x, y);
6200 p += l, remain -= l;
6202 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6203 e_map_point_image_uv_set(map, 2, x, y);
6204 l = snprintf(p, remain, " %d,%d", x, y);
6205 p += l, remain -= l;
6207 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6208 e_map_point_image_uv_set(map, 3, x, y);
6209 l = snprintf(p, remain, " %d,%d", x, y);
6210 p += l, remain -= l;
6212 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6214 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6216 e_comp_object_map_set(cw->effect_obj, map);
6217 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6221 /* if there's screen rotation with comp mode, then ec->effect_obj and
6222 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6224 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6225 evas_object_resize(cw->effect_obj, tw, th);
6229 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6231 API_ENTRY EINA_FALSE;
6233 cw->render_trace = set;
6239 e_comp_object_native_usable_get(Evas_Object *obj)
6241 API_ENTRY EINA_FALSE;
6242 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6244 if (cw->ec->input_only) return EINA_FALSE;
6245 if (cw->external_content) return EINA_FALSE;
6246 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6248 /* just return true value, if it is normal case */
6249 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6252 Evas_Native_Surface *ns;
6253 ns = evas_object_image_native_surface_get(cw->obj);
6255 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6258 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6266 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6268 API_ENTRY EINA_FALSE;
6269 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6270 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6271 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6275 case E_COMP_IMAGE_FILTER_BLUR:
6276 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6278 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6279 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6281 case E_COMP_IMAGE_FILTER_INVERSE:
6282 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6284 case E_COMP_IMAGE_FILTER_NONE:
6286 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6290 cw->image_filter = filter;
6295 EINTERN E_Comp_Image_Filter
6296 e_comp_object_image_filter_get(Evas_Object *obj)
6298 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6299 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6300 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6301 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6303 return cw->image_filter;
6307 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6311 if (!_damage_trace) return;
6313 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6314 evas_object_del(obj);
6316 _damage_trace_post_objs = NULL;
6320 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6322 if (!_damage_trace) return;
6324 _damage_trace_post_objs = _damage_trace_objs;
6325 _damage_trace_objs = NULL;
6329 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6331 if (_damage_trace == onoff) return;
6335 evas_event_callback_add(e_comp->evas,
6336 EVAS_CALLBACK_RENDER_PRE,
6337 _e_comp_object_damage_trace_render_pre_cb,
6340 evas_event_callback_add(e_comp->evas,
6341 EVAS_CALLBACK_RENDER_POST,
6342 _e_comp_object_damage_trace_render_post_cb,
6349 EINA_LIST_FREE(_damage_trace_objs, obj)
6350 evas_object_del(obj);
6352 _damage_trace_objs = NULL;
6354 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6355 evas_object_del(obj);
6357 _damage_trace_post_objs = NULL;
6359 evas_event_callback_del(e_comp->evas,
6360 EVAS_CALLBACK_RENDER_PRE,
6361 _e_comp_object_damage_trace_render_pre_cb);
6363 evas_event_callback_del(e_comp->evas,
6364 EVAS_CALLBACK_RENDER_POST,
6365 _e_comp_object_damage_trace_render_post_cb);
6368 _damage_trace = onoff;
6372 e_comp_object_redirected_get(Evas_Object *obj)
6374 API_ENTRY EINA_FALSE;
6375 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6377 return cw->redirected;
6381 e_comp_object_color_visible_get(Evas_Object *obj)
6383 API_ENTRY EINA_FALSE;
6386 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6388 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6392 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6396 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6400 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6408 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6410 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6412 return e_map_set_to_comp_object(em, obj);
6416 e_comp_object_map_get(const Evas_Object *obj)
6418 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6420 return e_map_get_from_comp_object(obj);
6424 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6426 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6428 evas_object_map_enable_set(obj, enable);
6434 e_comp_object_render_update_lock(Evas_Object *obj)
6436 E_Comp_Wl_Buffer *buffer;
6437 struct wayland_tbm_client_queue *cqueue;
6439 API_ENTRY EINA_FALSE;
6441 if (cw->render_update_lock.lock == 0)
6443 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6445 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6446 if ((buffer) && (buffer->resource))
6448 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6450 wayland_tbm_server_client_queue_flush(cqueue);
6453 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6454 e_comp_object_render_update_del(obj);
6456 ELOGF("COMP", "Render update lock enabled", cw->ec);
6459 cw->render_update_lock.lock++;
6465 e_comp_object_render_update_unlock(Evas_Object *obj)
6469 if (cw->render_update_lock.lock == 0)
6472 cw->render_update_lock.lock--;
6474 if (cw->render_update_lock.lock == 0)
6477 if (cw->render_update_lock.pending_move_set)
6479 evas_object_move(obj,
6480 cw->render_update_lock.pending_move_x,
6481 cw->render_update_lock.pending_move_y);
6482 cw->render_update_lock.pending_move_x = 0;
6483 cw->render_update_lock.pending_move_y = 0;
6484 cw->render_update_lock.pending_move_set = EINA_FALSE;
6487 if (cw->render_update_lock.pending_resize_set)
6489 evas_object_resize(obj,
6490 cw->render_update_lock.pending_resize_w,
6491 cw->render_update_lock.pending_resize_h);
6492 cw->render_update_lock.pending_resize_w = 0;
6493 cw->render_update_lock.pending_resize_h = 0;
6494 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6497 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6499 if ((cw->ec->exp_iconify.buffer_flush) &&
6500 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6501 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6502 e_comp_object_clear(obj);
6504 e_comp_object_render_update_add(obj);
6506 ELOGF("COMP", "Render update lock disabled", cw->ec);
6511 e_comp_object_render_update_lock_get(Evas_Object *obj)
6513 API_ENTRY EINA_FALSE;
6515 if (cw->render_update_lock.lock > 0)
6522 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6526 if (cw->transparent.set)
6528 if (r) *r = cw->transparent.user_r;
6529 if (g) *g = cw->transparent.user_g;
6530 if (b) *b = cw->transparent.user_b;
6531 if (a) *a = cw->transparent.user_a;
6535 evas_object_color_get(obj, r, g, b, a);
6540 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6544 evas_object_render_op_set(cw->obj, op);
6547 EINTERN Evas_Render_Op
6548 e_comp_object_render_op_get(Evas_Object *obj)
6550 API_ENTRY EVAS_RENDER_BLEND;
6552 return evas_object_render_op_get(cw->obj);
6556 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6559 wl_signal_add(&cw->events.lower, listener);
6562 #ifdef REFACTOR_DESK_AREA
6564 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6567 wl_signal_add(&cw->events.lower_done, listener);
6571 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6574 wl_signal_add(&cw->events.raise, listener);
6579 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6582 wl_signal_add(&cw->events.show, listener);
6586 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6589 wl_signal_add(&cw->events.hide, listener);
6592 #ifdef REFACTOR_DESK_AREA
6594 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6597 wl_signal_add(&cw->events.set_layer, listener);
6601 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6604 wl_signal_add(&cw->events.stack_above, listener);
6608 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6611 wl_signal_add(&cw->events.stack_below, listener);